Upload README.md with huggingface_hub
Browse files
README.md
CHANGED
|
@@ -10,7 +10,7 @@ tags:
|
|
| 10 |
|
| 11 |
# Temporal Smoke Model (bbox-tube-temporal)
|
| 12 |
|
| 13 |
-
> **Latest release:** [`v0.
|
| 14 |
|
| 15 |
A temporal wildfire-**smoke** classifier for short sequences of camera frames. A
|
| 16 |
YOLO detector proposes boxes, boxes are linked across frames into temporal
|
|
@@ -49,7 +49,7 @@ from huggingface_hub import hf_hub_download
|
|
| 49 |
from temporal_model.core.model import BboxTubeTemporalModel
|
| 50 |
|
| 51 |
# 1. Download a specific release (pin the revision).
|
| 52 |
-
model_zip = hf_hub_download("pyronear/temporal-model", "model.zip", revision="v0.
|
| 53 |
|
| 54 |
# 2. Temporally-ordered frames. Filenames carry timestamps
|
| 55 |
# (<prefix>_<YYYY-MM-DDTHH-MM-SS>.jpg); the order is the time order.
|
|
@@ -60,21 +60,30 @@ frame_paths = sorted(Path("my_sequence").glob("*.jpg"))
|
|
| 60 |
model = BboxTubeTemporalModel.from_package(Path(model_zip), device=None)
|
| 61 |
out = model.predict_sequence(frame_paths)
|
| 62 |
|
| 63 |
-
|
| 64 |
-
print("
|
| 65 |
|
| 66 |
-
#
|
|
|
|
|
|
|
| 67 |
kept = out.details.get("tubes", {}).get("kept", [])
|
| 68 |
-
|
|
|
|
|
|
|
|
|
|
| 69 |
```
|
| 70 |
|
| 71 |
`predict_sequence(frame_paths)` returns a `TemporalModelOutput`:
|
| 72 |
|
| 73 |
-
- `is_positive: bool` — the smoke verdict.
|
| 74 |
-
|
| 75 |
-
|
| 76 |
-
|
| 77 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 78 |
|
| 79 |
## Served API (Docker)
|
| 80 |
|
|
@@ -85,10 +94,15 @@ The same model is also served as a FastAPI image with the `model.zip` baked in
|
|
| 85 |
docker run --gpus all -p 8000:8000 \
|
| 86 |
-e TEMPORAL_API_S3_BUCKET=<frames-bucket> \
|
| 87 |
-e TEMPORAL_API_S3_ENDPOINT_URL=<s3-endpoint> \
|
| 88 |
-
pyronear/temporal-model-api:0.
|
| 89 |
# POST /predict {"frames": ["<s3-key>", ...]} GET /health
|
| 90 |
```
|
| 91 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 92 |
## Provenance
|
| 93 |
|
| 94 |
Every `model.zip` manifest records how it was built — the training git SHA, the
|
|
|
|
| 10 |
|
| 11 |
# Temporal Smoke Model (bbox-tube-temporal)
|
| 12 |
|
| 13 |
+
> **Latest release:** [`v0.3.0`](https://huggingface.co/pyronear/temporal-model/tree/v0.3.0) — pin this revision for reproducibility, or omit `revision=` to always get the latest. All releases: the **Files and versions** tab.
|
| 14 |
|
| 15 |
A temporal wildfire-**smoke** classifier for short sequences of camera frames. A
|
| 16 |
YOLO detector proposes boxes, boxes are linked across frames into temporal
|
|
|
|
| 49 |
from temporal_model.core.model import BboxTubeTemporalModel
|
| 50 |
|
| 51 |
# 1. Download a specific release (pin the revision).
|
| 52 |
+
model_zip = hf_hub_download("pyronear/temporal-model", "model.zip", revision="v0.3.0")
|
| 53 |
|
| 54 |
# 2. Temporally-ordered frames. Filenames carry timestamps
|
| 55 |
# (<prefix>_<YYYY-MM-DDTHH-MM-SS>.jpg); the order is the time order.
|
|
|
|
| 60 |
model = BboxTubeTemporalModel.from_package(Path(model_zip), device=None)
|
| 61 |
out = model.predict_sequence(frame_paths)
|
| 62 |
|
| 63 |
+
# 1. Binary verdict — the alarm decision.
|
| 64 |
+
print("is_smoke: ", out.is_positive)
|
| 65 |
|
| 66 |
+
# 2. Calibrated smoke probability in [0, 1]: the strongest kept tube's calibrated
|
| 67 |
+
# probability (0.0 when no tube was kept). Use is_positive for a yes/no alarm;
|
| 68 |
+
# use the probability to rank/triage sequences or apply your own threshold.
|
| 69 |
kept = out.details.get("tubes", {}).get("kept", [])
|
| 70 |
+
probs = [t["probability"] for t in kept if t["probability"] is not None]
|
| 71 |
+
smoke_probability = max(probs) if probs else 0.0
|
| 72 |
+
print("smoke probability:", smoke_probability)
|
| 73 |
+
print("kept tubes: ", len(kept))
|
| 74 |
```
|
| 75 |
|
| 76 |
`predict_sequence(frame_paths)` returns a `TemporalModelOutput`:
|
| 77 |
|
| 78 |
+
- `is_positive: bool` — the smoke verdict. `True` iff at least one tube's
|
| 79 |
+
calibrated probability clears the packaged decision threshold.
|
| 80 |
+
- `details: dict` — per-tube logits, calibrated probabilities, bounding boxes, and
|
| 81 |
+
the decision (`aggregation`, `threshold`). The top-level **smoke probability** is
|
| 82 |
+
the maximum kept-tube `probability` (shown above).
|
| 83 |
+
|
| 84 |
+
`is_positive` and the probability are consistent: a positive sequence always has a
|
| 85 |
+
kept tube whose probability is ≥ the threshold, so `smoke_probability` is ≥ the
|
| 86 |
+
threshold whenever `is_smoke` is `True`.
|
| 87 |
|
| 88 |
## Served API (Docker)
|
| 89 |
|
|
|
|
| 94 |
docker run --gpus all -p 8000:8000 \
|
| 95 |
-e TEMPORAL_API_S3_BUCKET=<frames-bucket> \
|
| 96 |
-e TEMPORAL_API_S3_ENDPOINT_URL=<s3-endpoint> \
|
| 97 |
+
pyronear/temporal-model-api:0.3.0
|
| 98 |
# POST /predict {"frames": ["<s3-key>", ...]} GET /health
|
| 99 |
```
|
| 100 |
|
| 101 |
+
`POST /predict` returns `{ "is_smoke": bool, "probability": float | null, "model":
|
| 102 |
+
{...} }`, where `probability` is the calibrated max kept-tube probability (`null`
|
| 103 |
+
only for an uncalibrated model). Add `?verbose=true` for a `details` block with the
|
| 104 |
+
per-tube breakdown and decision config.
|
| 105 |
+
|
| 106 |
## Provenance
|
| 107 |
|
| 108 |
Every `model.zip` manifest records how it was built — the training git SHA, the
|