l0uai commited on
Commit
52f55f8
·
1 Parent(s): fcb9b70

Publish causal YellowCab benchmark and model card

Browse files
EVALUATION.md ADDED
@@ -0,0 +1,94 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # YellowCab evaluation
2
+
3
+ ## Question
4
+
5
+ Can three chronological road images combined with past-and-current telemetry
6
+ forecast a GPS-derived taxi maneuver approximately 20 seconds ahead better than
7
+ tested single-modality and rule-based baselines?
8
+
9
+ ## Frozen evaluation contract
10
+
11
+ - Published model version: `v0.1-causal`
12
+ - Published Safetensors SHA-256:
13
+ `af1a98cd96bb68d642f7a0adeedfacac37b230917afc15f3c87230a99a15b8a2`
14
+ - Training manifest SHA-256:
15
+ `8b92ad563892776cc25148f39fec6bf207e1e442c618b58fb07af7e2b899364d`
16
+ - Split SHA-256:
17
+ `bfc5e960c8af32d0ea75a5e293bb95b3125111ace2cf8452eb42feb4bc2a1a5e`
18
+ - Seed: `20260726`
19
+ - Primary metric: macro F1
20
+
21
+ The split is forward in time by complete route. The earliest 26 routes are used
22
+ for training, the next five for validation, and the newest five for testing.
23
+ Frames never cross route boundaries between splits.
24
+
25
+ ## Causal-input audit
26
+
27
+ The original dataset builder could use a future-bearing fallback when the
28
+ past-to-current displacement was too small to establish a reliable heading. The
29
+ causal manifest removes that fallback. When displacement is below four metres,
30
+ heading is represented as unknown using `(sin=0, cos=1)`.
31
+
32
+ The audit changed 5,974 of 74,680 rows:
33
+
34
+ - 4,552 training rows
35
+ - 819 validation rows
36
+ - 603 test rows
37
+
38
+ The released `v0.1-causal` checkpoint was trained on the corrected manifest.
39
+ Labels still use future trajectory by definition; model inputs do not.
40
+
41
+ ## Metrics
42
+
43
+ Macro F1 is primary because the test set is imbalanced. Accuracy, balanced
44
+ accuracy, weighted F1, log loss, Brier score, and 15-bin expected calibration
45
+ error are secondary.
46
+
47
+ The macro-F1 confidence interval is computed with 500 bootstrap resamples of
48
+ complete test routes. This preserves within-route dependence instead of treating
49
+ 8,594 sequential examples as independent observations.
50
+
51
+ ## Reproduction from published predictions
52
+
53
+ The repository publishes labels, predictions, probabilities, and generic route
54
+ groups for every test example in `eval_predictions.csv`. It excludes images,
55
+ capture identifiers, timestamps, grid cells, and geographic data.
56
+
57
+ ```bash
58
+ python -m pip install numpy pandas scikit-learn
59
+ python recompute_metrics.py
60
+ ```
61
+
62
+ The script checks that probability rows sum to one and reproduces the core
63
+ point estimates and route-clustered macro-F1 interval.
64
+
65
+ ## Selective prediction
66
+
67
+ `selective_metrics.csv` evaluates the confidence-based abstention rule. At the
68
+ default 0.45 threshold, the model retains 5,971 of 8,594 examples (69.5%
69
+ coverage). Accuracy among retained examples is 0.6583 and macro F1 is 0.4327.
70
+
71
+ Selective metrics describe only the accepted subset. They do not mean the
72
+ abstained examples disappear operationally; a real system must route them to a
73
+ fallback or human review process.
74
+
75
+ ## Interpretation
76
+
77
+ YellowCab has the highest macro F1 among the tested models. It does not win every
78
+ metric: telemetry gradient boosting has higher balanced accuracy, and a majority
79
+ classifier has higher raw accuracy because most examples are `continue`.
80
+
81
+ This supports use as a ranking, indexing, and research model. It does not support
82
+ claims of safe actuation, universal geographic generalization, or global
83
+ state-of-the-art status.
84
+
85
+ ## Remaining evaluation work
86
+
87
+ A stronger future release should add:
88
+
89
+ - an independently human-labeled gold test set;
90
+ - a separate calibration split;
91
+ - evaluation across additional cities, camera mounts, weather, and daylight;
92
+ - selective-risk curves for the abstention threshold;
93
+ - an operational video-retrieval study at fixed event recall; and
94
+ - independent replication on a public, task-compatible benchmark.
README.md CHANGED
@@ -4,18 +4,42 @@ license: apache-2.0
4
  tags:
5
  - driving
6
  - multimodal
 
7
  - time-series
 
8
  - custom-handler
9
  - research
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10
  ---
11
 
12
  # YellowCab
13
 
14
- YellowCab is a multimodal PyTorch model that predicts one of five near-future
15
- taxi maneuver labels from three chronologically ordered camera frames and
16
- twelve telemetry features.
17
-
18
- The output labels are:
19
 
20
  - `continue`
21
  - `slow`
@@ -23,31 +47,153 @@ The output labels are:
23
  - `turn_left`
24
  - `turn_right`
25
 
26
- ## Model
 
 
27
 
28
- YellowCab combines:
29
 
30
- - an EfficientNet-B0 visual encoder;
31
- - a one-layer unidirectional GRU over three image embeddings;
32
- - a telemetry MLP over twelve normalized features; and
33
- - a five-class fusion head with temperature scaling and optional abstention.
34
 
35
- The checkpoint and its exact loading configuration are included in this
36
- repository. The checkpoint SHA-256 is recorded in `config.json`.
 
 
37
 
38
- ## Data and privacy
 
 
 
 
39
 
40
- The model was trained on privacy-redacted imagery collected from the operator's
41
- taxi fleet under contributor agreements authorizing model training. No source
42
- imagery, route manifests, or personal identifiers are distributed here.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
43
 
44
  ## Input
45
 
46
  Requests require exactly three base64-encoded JPEG or PNG frames ordered oldest
47
- to newest. Their nominal offsets are approximately `t-20 s`, `t-10 s`, and `t`.
48
- Optional frame timestamps must be strictly increasing.
49
 
50
- All telemetry fields documented in `config.json` are required:
51
 
52
  `current_speed_mps`, `past_speed_mps`, `acceleration_mps2`,
53
  `past_turn_degrees`, `past_yaw_rate_deg_s`, `heading_sin`, `heading_cos`,
@@ -77,29 +223,10 @@ All telemetry fields documented in `config.json` are required:
77
  }
78
  ```
79
 
80
- The custom `EndpointHandler` in `handler.py` validates inputs and returns the
81
- predicted label, ordered class probabilities, confidence, and abstention state.
82
- This custom multimodal architecture is not compatible with the standard
83
- image-classification `pipeline()` or widget.
84
-
85
- ## Evaluation
86
-
87
- The release process included leakage-free held-out evaluation. Numeric results
88
- are omitted until the corresponding report is published for this exact
89
- checkpoint digest. Users should evaluate performance and calibration on their
90
- own target domain.
91
-
92
- ## Intended use and limitations
93
-
94
- YellowCab is intended for research, fleet analytics, and prototyping. Its labels
95
- are GPS-derived maneuver proxies rather than human safety annotations.
96
- Performance may vary with geography, weather, camera placement, traffic
97
- conditions, and telemetry quality.
98
-
99
- Telemetry supplied at inference time must be computed only from observations
100
- available at or before the newest frame. YellowCab is not a safety-certified
101
- system and should not be used as the sole input to steering, braking, throttle,
102
- or other safety-critical decisions.
103
 
104
  ## Local use
105
 
@@ -116,9 +243,64 @@ predict = EndpointHandler(".")
116
  result = predict(request_body)
117
  ```
118
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
119
  ## License
120
 
121
  Unless otherwise noted, the model weights and original code, configuration, and
122
- documentation in this repository are licensed under the Apache License 2.0.
123
- Third-party components remain subject to their respective terms; see
124
- `THIRD_PARTY_NOTICES.md`.
 
 
 
 
 
 
 
 
 
 
 
 
 
4
  tags:
5
  - driving
6
  - multimodal
7
+ - computer-vision
8
  - time-series
9
+ - maneuver-forecasting
10
  - custom-handler
11
  - research
12
+ metrics:
13
+ - f1
14
+ - accuracy
15
+ model-index:
16
+ - name: YellowCab v0.1-causal
17
+ results:
18
+ - task:
19
+ type: image-classification
20
+ name: Multimodal maneuver forecasting
21
+ dataset:
22
+ name: YellowCab private forward-route holdout
23
+ type: private
24
+ split: test
25
+ metrics:
26
+ - type: f1
27
+ name: Macro F1
28
+ value: 0.3915542658
29
+ - type: accuracy
30
+ name: Balanced accuracy
31
+ value: 0.3915633404
32
+ - type: accuracy
33
+ name: Accuracy
34
+ value: 0.5755178031
35
  ---
36
 
37
  # YellowCab
38
 
39
+ YellowCab is a compact multimodal model for forecasting a taxi's observed
40
+ maneuver approximately 20 seconds ahead. It combines three chronological road
41
+ images with twelve past-and-current telemetry signals and returns calibrated
42
+ probabilities for:
 
43
 
44
  - `continue`
45
  - `slow`
 
47
  - `turn_left`
48
  - `turn_right`
49
 
50
+ The model has **5.29 million parameters**. It is intended for fleet-video
51
+ indexing, maneuver analytics, multimodal research, and prototyping—not vehicle
52
+ control.
53
 
54
+ ## What is technically useful about it?
55
 
56
+ YellowCab tests a practical hypothesis: recent visual context and vehicle motion
57
+ history are more useful together than either signal alone.
 
 
58
 
59
+ On the route-held-out silver benchmark, the causal temporal-fusion checkpoint
60
+ reaches **0.3916 macro F1**, compared with **0.3414** for the strongest tested
61
+ past-only telemetry baseline and **0.3050** for the tested current-frame
62
+ vision baseline. This supports uses such as:
63
 
64
+ - assigning likely maneuver tags to fleet footage;
65
+ - retrieving candidate stop and turn events for human review;
66
+ - prioritizing uncertain sequences for data collection or annotation;
67
+ - studying disagreement between visual and motion signals; and
68
+ - prototyping calibrated, abstaining multimodal classifiers.
69
 
70
+ These results do not establish a global rank. YellowCab uses a private,
71
+ task-specific benchmark and has not been evaluated under a directly comparable
72
+ public autonomous-driving leaderboard protocol.
73
+
74
+ ## Architecture
75
+
76
+ - Frozen ImageNet-pretrained EfficientNet-B0 visual encoder
77
+ - Three frames at nominal offsets `t-20 s`, `t-10 s`, and `t`
78
+ - Layer normalization followed by a one-layer unidirectional GRU
79
+ - Telemetry MLP over twelve normalized causal features
80
+ - Fusion classifier over five maneuver classes
81
+ - Temperature scaling and optional confidence-based abstention
82
+
83
+ The repository contains the exact architecture, configuration, integrity-checked
84
+ Safetensors checkpoint, and custom Hugging Face endpoint handler.
85
+
86
+ ## Evaluation
87
+
88
+ ### Protocol
89
+
90
+ - **74,680** examples across **36** routes
91
+ - **55,711** training examples from 26 routes
92
+ - **10,375** validation examples from 5 routes
93
+ - **8,594** test examples from the newest 5 completely held-out routes
94
+ - Complete forward-in-time route separation
95
+ - No frame from a validation or test route enters training
96
+ - Model inputs use only information available at or before the newest frame
97
+ - Labels are GPS-derived maneuver proxies approximately 20 seconds ahead
98
+ - Primary metric: macro F1
99
+ - 95% confidence interval: 500 route-clustered bootstrap samples
100
+
101
+ ### Headline results
102
+
103
+ | Metric | YellowCab |
104
+ | --- | ---: |
105
+ | Macro F1 | **0.3916** |
106
+ | Route-bootstrap 95% CI | **0.3476–0.4281** |
107
+ | Balanced accuracy | **0.3916** |
108
+ | Accuracy | **0.5755** |
109
+ | Weighted F1 | **0.5807** |
110
+ | Log loss | **1.0841** |
111
+ | Brier score | **0.5563** |
112
+ | ECE, 15 bins | **0.0118** |
113
+
114
+ Raw accuracy is not the primary metric because `continue` is the majority
115
+ class. A majority classifier reaches 0.6232 accuracy while scoring only 0.1536
116
+ macro F1.
117
+
118
+ ### Baselines
119
+
120
+ | Model | Macro F1 | Balanced accuracy | Accuracy |
121
+ | --- | ---: | ---: | ---: |
122
+ | **YellowCab: temporal vision + telemetry** | **0.3916** | 0.3916 | 0.5755 |
123
+ | Telemetry gradient boosting | 0.3414 | **0.4217** | 0.4147 |
124
+ | Current-frame vision linear model | 0.3050 | 0.2968 | 0.5752 |
125
+ | Past-motion rule | 0.2235 | 0.2238 | 0.4550 |
126
+ | Telemetry logistic regression | 0.1887 | 0.2872 | 0.1963 |
127
+ | Majority class | 0.1536 | 0.2000 | **0.6232** |
128
+
129
+ YellowCab improves macro F1 over every tested baseline, but the gradient-boosted
130
+ telemetry baseline has higher balanced accuracy. We report both rather than
131
+ claiming uniform dominance.
132
+
133
+ ### Per-class results
134
+
135
+ | Class | Precision | Recall | F1 | Support |
136
+ | --- | ---: | ---: | ---: | ---: |
137
+ | Continue | 0.7595 | 0.7394 | **0.7493** | 5,356 |
138
+ | Slow | 0.4031 | 0.3544 | **0.3772** | 951 |
139
+ | Stop | 0.3754 | 0.3423 | **0.3581** | 634 |
140
+ | Turn left | 0.2447 | 0.3157 | **0.2757** | 833 |
141
+ | Turn right | 0.1897 | 0.2061 | **0.1975** | 820 |
142
+
143
+ Turn performance is the clearest weakness. YellowCab should be used to produce
144
+ ranked candidates or analytics, not treated as a reliable maneuver oracle.
145
+
146
+ ### Confidence-based abstention
147
+
148
+ The default confidence threshold is 0.45. On this held-out set it retains
149
+ **69.5%** of examples, with **0.6583 selective accuracy** and **0.4327 selective
150
+ macro F1** among retained examples. Raising the threshold trades coverage for
151
+ higher accuracy:
152
+
153
+ | Threshold | Coverage | Selective accuracy | Selective macro F1 |
154
+ | --- | ---: | ---: | ---: |
155
+ | 0.00 | 100.0% | 0.5755 | 0.3916 |
156
+ | 0.35 | 91.0% | 0.6007 | 0.4061 |
157
+ | **0.45** | **69.5%** | **0.6583** | **0.4327** |
158
+ | 0.55 | 47.2% | 0.7324 | 0.4702 |
159
+ | 0.65 | 30.2% | 0.8092 | 0.5275 |
160
+
161
+ This makes the model more useful for candidate retrieval and review queues, but
162
+ these thresholds must be recalibrated after domain shift. Full results are in
163
+ [`selective_metrics.csv`](selective_metrics.csv).
164
+
165
+ ![Benchmark comparison](benchmark.png)
166
+
167
+ ![Held-out confusion matrix](confusion_matrix.png)
168
+
169
+ The complete checkpoint-specific report is in
170
+ [`evaluation.json`](evaluation.json). Recomputable, privacy-sanitized held-out
171
+ probabilities are in [`eval_predictions.csv`](eval_predictions.csv), and the
172
+ metric script is in [`recompute_metrics.py`](recompute_metrics.py). Additional
173
+ methodology and limitations are documented in
174
+ [`EVALUATION.md`](EVALUATION.md).
175
+
176
+ ## Checkpoint identity
177
+
178
+ - Version: `v0.1-causal`
179
+ - Published checkpoint SHA-256:
180
+ `af1a98cd96bb68d642f7a0adeedfacac37b230917afc15f3c87230a99a15b8a2`
181
+ - Training manifest SHA-256:
182
+ `8b92ad563892776cc25148f39fec6bf207e1e442c618b58fb07af7e2b899364d`
183
+ - Split SHA-256:
184
+ `bfc5e960c8af32d0ea75a5e293bb95b3125111ace2cf8452eb42feb4bc2a1a5e`
185
+ - Training seed: `20260726`
186
+
187
+ The causal-manifest audit replaced unavailable current headings with the neutral
188
+ encoding `(sin=0, cos=1)` rather than deriving them from future motion. The
189
+ published checkpoint was trained and evaluated on that corrected manifest.
190
 
191
  ## Input
192
 
193
  Requests require exactly three base64-encoded JPEG or PNG frames ordered oldest
194
+ to newest. Optional frame timestamps must be strictly increasing.
 
195
 
196
+ All telemetry fields are required:
197
 
198
  `current_speed_mps`, `past_speed_mps`, `acceleration_mps2`,
199
  `past_turn_degrees`, `past_yaw_rate_deg_s`, `heading_sin`, `heading_cos`,
 
223
  }
224
  ```
225
 
226
+ The custom `EndpointHandler` validates the request and returns the predicted
227
+ label, ordered class probabilities, confidence, and abstention state. This
228
+ custom multimodal architecture is not compatible with the standard
229
+ image-classification `pipeline()` or Hub widget.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
230
 
231
  ## Local use
232
 
 
243
  result = predict(request_body)
244
  ```
245
 
246
+ ## Training data and privacy
247
+
248
+ The model was trained on privacy-redacted imagery collected from the operator's
249
+ taxi fleet under contributor agreements authorizing model training. No source
250
+ imagery, exact GPS records, route manifests, or personal identifiers are
251
+ distributed in this repository.
252
+
253
+ The published evaluation predictions use sequential example identifiers and
254
+ generic held-out route groups. Capture identifiers, timestamps, grid cells, and
255
+ locations have been removed.
256
+
257
+ ## Intended uses
258
+
259
+ - Offline fleet-video indexing and search
260
+ - Maneuver analytics and aggregate research
261
+ - Candidate-event retrieval followed by human review
262
+ - Multimodal classification and calibration research
263
+ - Prototyping and collection-planning experiments
264
+
265
+ ## Out-of-scope uses
266
+
267
+ Do not use YellowCab:
268
+
269
+ - as the sole input to steering, braking, throttle, or dispatch decisions;
270
+ - as a safety-certified driver-assistance component;
271
+ - to identify drivers, passengers, pedestrians, or locations;
272
+ - to infer intent, fault, liability, or legal compliance; or
273
+ - outside a target domain without measuring performance and calibration again.
274
+
275
+ ## Limitations
276
+
277
+ - Ground truth is GPS-derived silver labeling, not independent human annotation.
278
+ - The evaluation covers five held-out routes from one operating domain.
279
+ - Geography, weather, camera placement, traffic, and telemetry quality can shift
280
+ performance.
281
+ - Rare classes are substantially weaker than `continue`.
282
+ - Temperature scaling used the validation split rather than a separate
283
+ calibration split.
284
+ - No membership-inference, model-inversion, or differential-privacy assessment
285
+ has been completed.
286
+ - Benchmark results are author-reported and have not been independently
287
+ replicated on a public dataset.
288
+
289
  ## License
290
 
291
  Unless otherwise noted, the model weights and original code, configuration, and
292
+ documentation are licensed under the Apache License 2.0. Third-party components
293
+ remain subject to their respective terms; see
294
+ [`THIRD_PARTY_NOTICES.md`](THIRD_PARTY_NOTICES.md).
295
+
296
+ ## Citation
297
+
298
+ ```bibtex
299
+ @software{yellowcab_v0_1_causal_2026,
300
+ author = {{The General Data Corporation}},
301
+ title = {YellowCab: Multimodal Taxi Maneuver Forecasting},
302
+ year = {2026},
303
+ version = {v0.1-causal},
304
+ url = {https://huggingface.co/generaldata/YellowCab}
305
+ }
306
+ ```
benchmark.csv ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ model,samples,accuracy,balanced_accuracy,macro_f1,weighted_f1,log_loss,brier_score,ece_15_bin,p95_latency_ms,continue_recall,continue_f1,slow_recall,slow_f1,stop_recall,stop_f1,turn_left_recall,turn_left_f1,turn_right_recall,turn_right_f1,macro_f1_route_ci_low,macro_f1_route_ci_high
2
+ Temporal efficientnet_b0 + telemetry,8594,0.5755178031184547,0.39156334041323,0.3915542657655546,0.5807008272180106,1.0841176199931875,0.5563128377237149,0.011817411647322817,95.37229499110252,0.7393577296489918,0.7492904446546831,0.35436382754994744,0.37716843872411865,0.3422712933753943,0.3580858085808581,0.3157262905162065,0.27568134171907754,0.20609756097560974,0.19754529514903565,0.34762239048615595,0.42805096076291543
3
+ Telemetry gradient boosting,8594,0.4147079357691413,0.42166330996553986,0.341392924380058,0.45303568638063824,1.2490630281069546,0.6566714449096165,0.12167008852186818,,0.4051530993278566,0.5513911828230212,0.6466876971608833,0.3416666666666667,0.4889589905362776,0.29865125240847784,0.2797118847539016,0.2583148558758315,0.28780487804878047,0.25694066412629285,0.3149153283503967,0.34939970154465316
4
+ Vision linear (efficientnet_b0),8594,0.5751687223644403,0.2967510353079744,0.30503460507355407,0.5344562546214928,10.24602122531317,0.8349054717132016,0.40913361870747145,,0.8269230769230769,0.7406354515050168,0.15562565720294427,0.21480406386066764,0.25236593059936907,0.25559105431309903,0.15006002400960383,0.18102824040550325,0.09878048780487805,0.13311421528348397,0.26780560056303193,0.32731434371479995
5
+ Past-motion rule,8594,0.4549685827321387,0.22377382659168304,0.22352977859537337,0.45325423166470347,2.058490921490782,0.966304980218757,0.44503141726786155,,0.6562733383121733,0.6534064504136072,0.10199789695057834,0.09627791563275434,0.0,0.0,0.17767106842737096,0.17928528164748636,0.18292682926829268,0.18867924528301888,0.18734638205859894,0.23451957590710315
6
+ Telemetry logistic,8594,0.19629974400744707,0.2871892331606019,0.1886698746182765,0.18614071585068767,1.5832758165931655,0.8215841116420504,0.1432688177654283,,0.109596713965646,0.18162128712871287,0.601472134595163,0.25060240963855424,0.37066246056782337,0.17609591607343575,0.19567827130852342,0.17212249208025343,0.15853658536585366,0.16290726817042606,0.1839562547318565,0.20443593471582872
7
+ Majority class,8594,0.6232255061670933,0.2,0.15357706093189966,0.4785657076746885,1.1837257781136636,0.5768401032344809,0.03274965759140802,,1.0,0.7678853046594982,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.14609150326797388,0.1554760284937855
benchmark.png ADDED
bundle_manifest.json CHANGED
@@ -1,53 +1,93 @@
1
  {
2
- "schema": "yellowcab_huggingface_bundle_v1",
3
- "model_id": "generaldata/YellowCab",
4
- "model_version": "v0",
5
- "license": "Apache-2.0",
6
- "note": "bundle_manifest.json intentionally does not hash itself",
7
  "files": {
8
  ".gitattributes": {
9
  "bytes": 69,
10
  "sha256": "14281383ff036613975d5f219e22a1102041eb14de55c3f34db8223bb0784145"
11
  },
12
- "LICENSE": {
13
- "bytes": 11357,
14
- "sha256": "c71d239df91726fc519c6eb72d318ec65820627232b2f796219e87dcf35d0ab4"
15
  },
16
- "NOTICE": {
17
- "bytes": 622,
18
- "sha256": "1983f5396c5d59083231fdf3516feacc267b13bbe8090b31804260fde5c39c72"
19
  },
20
- "README.md": {
21
- "bytes": 3787,
22
- "sha256": "ca01c46bbd8f7b87a5a5353d3c6ccf2ac7b8032bb339033346e64d396713ef73"
23
  },
24
- "THIRD_PARTY_NOTICES.md": {
25
- "bytes": 1454,
26
- "sha256": "38f7bb94a0824965ac7cff7cc2f4378a0a44cbe08aad02b97468d86243b2da1d"
27
  },
28
  "config.json": {
29
- "bytes": 9339,
30
- "sha256": "1d268c27e8f4ebf76cb52cacd72e7a6f27a44e7076b857da15ef5253139b227f"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
31
  },
32
  "handler.py": {
33
  "bytes": 17681,
34
  "sha256": "a8a3c804e71e4864ac26cae394d9f1e32af86d38ae939226066e1c9767ac2eaa"
35
  },
 
 
 
 
36
  "model.py": {
37
  "bytes": 8419,
38
  "sha256": "48cf1aafb242a497be2ec9ad7abd6211608cf04e98c9fae20d5878ba8a09bc52"
39
  },
40
  "model.safetensors": {
41
- "bytes": 21384660,
42
- "sha256": "241f8335bdbe45e9f88e45640b35e3426e2c1e8fd58b9e0bec774a417988d57c"
 
 
 
 
 
 
 
 
 
 
 
 
43
  },
44
  "requirements.txt": {
45
  "bytes": 80,
46
  "sha256": "92f03418ab85f5cb1239971fb4515cf1d2acc9aed7013d0aca74b17daa3f97ef"
47
  },
 
 
 
 
 
 
 
 
48
  "THIRD_PARTY_LICENSES/torchvision-BSD-3-Clause.txt": {
49
  "bytes": 1516,
50
  "sha256": "2b63e4f6569e0e58260881a1f7ea8b1d9802859ab3cb4b32a45cba246245c8da"
 
 
 
 
51
  }
52
  }
53
  }
 
1
  {
2
+ "schema": "gdc_yellowcab_public_bundle_v2",
 
 
 
 
3
  "files": {
4
  ".gitattributes": {
5
  "bytes": 69,
6
  "sha256": "14281383ff036613975d5f219e22a1102041eb14de55c3f34db8223bb0784145"
7
  },
8
+ "benchmark.csv": {
9
+ "bytes": 2524,
10
+ "sha256": "177d024f407c9e064b63eff4b0e594deb0ae6b861ce342c63e9bfc2458ff83e0"
11
  },
12
+ "benchmark.png": {
13
+ "bytes": 98848,
14
+ "sha256": "31e491792a60685e15a373cb1919bb732aaa675ca0bce5b5f38270c32d6c6a9a"
15
  },
16
+ "class_metrics.csv": {
17
+ "bytes": 2679,
18
+ "sha256": "bf35d02ca99e765be4926d95d6f197488569bf902c944eca97d2f954a5c87003"
19
  },
20
+ "classification_report.json": {
21
+ "bytes": 1128,
22
+ "sha256": "3c10ff529643649eb2b72f79244f6370c2ff9fe0c34e27b0600fe951047a7969"
23
  },
24
  "config.json": {
25
+ "bytes": 10944,
26
+ "sha256": "2a221f468f350360ed704f6552400312f67057fdc5610e795162a711a5636b9b"
27
+ },
28
+ "confusion_matrix.png": {
29
+ "bytes": 96286,
30
+ "sha256": "31fa8526560d76bc9600a40a6e48b2d6ef929934c54d8371e855de93431a5482"
31
+ },
32
+ "eval_predictions.csv": {
33
+ "bytes": 1156310,
34
+ "sha256": "d76846904ed54093d53a77610f040e2e9a6476cd2c06bd13edbf121ca9875dff"
35
+ },
36
+ "evaluation.json": {
37
+ "bytes": 12235,
38
+ "sha256": "e8890addffda4ec495a219f7439bb4d9ece5934f536e35d7f340830b475cbe21"
39
+ },
40
+ "EVALUATION.md": {
41
+ "bytes": 3606,
42
+ "sha256": "31d29ab99ac4761662a1bd4646e4c317deedb60c79577b844472485085f6a710"
43
  },
44
  "handler.py": {
45
  "bytes": 17681,
46
  "sha256": "a8a3c804e71e4864ac26cae394d9f1e32af86d38ae939226066e1c9767ac2eaa"
47
  },
48
+ "LICENSE": {
49
+ "bytes": 11357,
50
+ "sha256": "c71d239df91726fc519c6eb72d318ec65820627232b2f796219e87dcf35d0ab4"
51
+ },
52
  "model.py": {
53
  "bytes": 8419,
54
  "sha256": "48cf1aafb242a497be2ec9ad7abd6211608cf04e98c9fae20d5878ba8a09bc52"
55
  },
56
  "model.safetensors": {
57
+ "bytes": 21384748,
58
+ "sha256": "af1a98cd96bb68d642f7a0adeedfacac37b230917afc15f3c87230a99a15b8a2"
59
+ },
60
+ "NOTICE": {
61
+ "bytes": 622,
62
+ "sha256": "1983f5396c5d59083231fdf3516feacc267b13bbe8090b31804260fde5c39c72"
63
+ },
64
+ "README.md": {
65
+ "bytes": 10588,
66
+ "sha256": "6012ebee2b3d34d3117aaac5e2c1143e07f583b9c61fe6bc8cf1483c820cd8a4"
67
+ },
68
+ "recompute_metrics.py": {
69
+ "bytes": 3963,
70
+ "sha256": "dd2f8aeda429cfecb5204e6b2ed563a3d269500b0112ab6e7558a576f50dac5f"
71
  },
72
  "requirements.txt": {
73
  "bytes": 80,
74
  "sha256": "92f03418ab85f5cb1239971fb4515cf1d2acc9aed7013d0aca74b17daa3f97ef"
75
  },
76
+ "selective_metrics.csv": {
77
+ "bytes": 614,
78
+ "sha256": "e39afd4baf6104eced16f0658f19b3abb7f5278f29fe7cc641a544910eb28606"
79
+ },
80
+ "subset_metrics.csv": {
81
+ "bytes": 2430,
82
+ "sha256": "7de2bb82af604e2d5acc2276c345b7d01467b596f2196511394d2f3c60c569e4"
83
+ },
84
  "THIRD_PARTY_LICENSES/torchvision-BSD-3-Clause.txt": {
85
  "bytes": 1516,
86
  "sha256": "2b63e4f6569e0e58260881a1f7ea8b1d9802859ab3cb4b32a45cba246245c8da"
87
+ },
88
+ "THIRD_PARTY_NOTICES.md": {
89
+ "bytes": 1454,
90
+ "sha256": "38f7bb94a0824965ac7cff7cc2f4378a0a44cbe08aad02b97468d86243b2da1d"
91
  }
92
  }
93
  }
class_metrics.csv ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ model,class,precision,recall,f1,support
2
+ Majority class,continue,0.6232255061670933,1.0,0.7678853046594982,5356
3
+ Majority class,slow,0.0,0.0,0.0,951
4
+ Majority class,stop,0.0,0.0,0.0,634
5
+ Majority class,turn_left,0.0,0.0,0.0,833
6
+ Majority class,turn_right,0.0,0.0,0.0,820
7
+ Past-motion rule,continue,0.6505645012030353,0.6562733383121733,0.6534064504136072,5356
8
+ Past-motion rule,slow,0.09116541353383459,0.10199789695057834,0.09627791563275434,951
9
+ Past-motion rule,stop,0.0,0.0,0.0,634
10
+ Past-motion rule,turn_left,0.18092909535452323,0.17767106842737096,0.17928528164748636,833
11
+ Past-motion rule,turn_right,0.19480519480519481,0.18292682926829268,0.18867924528301888,820
12
+ Telemetry logistic,continue,0.529783393501805,0.109596713965646,0.18162128712871287,5356
13
+ Telemetry logistic,slow,0.15827338129496402,0.601472134595163,0.25060240963855424,951
14
+ Telemetry logistic,stop,0.11547911547911548,0.37066246056782337,0.17609591607343575,634
15
+ Telemetry logistic,turn_left,0.1536286522148916,0.19567827130852342,0.17212249208025343,833
16
+ Telemetry logistic,turn_right,0.16752577319587628,0.15853658536585366,0.16290726817042606,820
17
+ Telemetry gradient boosting,continue,0.8628230616302187,0.4051530993278566,0.5513911828230212,5356
18
+ Telemetry gradient boosting,slow,0.232163080407701,0.6466876971608833,0.3416666666666667,951
19
+ Telemetry gradient boosting,stop,0.21497919556171982,0.4889589905362776,0.29865125240847784,634
20
+ Telemetry gradient boosting,turn_left,0.2399588053553038,0.2797118847539016,0.2583148558758315,833
21
+ Telemetry gradient boosting,turn_right,0.232055063913471,0.28780487804878047,0.25694066412629285,820
22
+ Vision linear (efficientnet_b0),continue,0.6706541490006057,0.8269230769230769,0.7406354515050168,5356
23
+ Vision linear (efficientnet_b0),slow,0.34660421545667447,0.15562565720294427,0.21480406386066764,951
24
+ Vision linear (efficientnet_b0),stop,0.2588996763754045,0.25236593059936907,0.25559105431309903,634
25
+ Vision linear (efficientnet_b0),turn_left,0.2281021897810219,0.15006002400960383,0.18102824040550325,833
26
+ Vision linear (efficientnet_b0),turn_right,0.2040302267002519,0.09878048780487805,0.13311421528348397,820
27
+ Temporal efficientnet_b0 + telemetry,continue,0.759493670886076,0.7393577296489918,0.7492904446546831,5356
28
+ Temporal efficientnet_b0 + telemetry,slow,0.40311004784689,0.35436382754994744,0.37716843872411865,951
29
+ Temporal efficientnet_b0 + telemetry,stop,0.3754325259515571,0.3422712933753943,0.3580858085808581,634
30
+ Temporal efficientnet_b0 + telemetry,turn_left,0.24465116279069768,0.3157262905162065,0.27568134171907754,833
31
+ Temporal efficientnet_b0 + telemetry,turn_right,0.18967452300785634,0.20609756097560974,0.19754529514903565,820
classification_report.json ADDED
@@ -0,0 +1,45 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "continue": {
3
+ "precision": 0.759493670886076,
4
+ "recall": 0.7393577296489918,
5
+ "f1-score": 0.7492904446546831,
6
+ "support": 5356.0
7
+ },
8
+ "slow": {
9
+ "precision": 0.40311004784689,
10
+ "recall": 0.35436382754994744,
11
+ "f1-score": 0.37716843872411865,
12
+ "support": 951.0
13
+ },
14
+ "stop": {
15
+ "precision": 0.3754325259515571,
16
+ "recall": 0.3422712933753943,
17
+ "f1-score": 0.3580858085808581,
18
+ "support": 634.0
19
+ },
20
+ "turn_left": {
21
+ "precision": 0.24465116279069768,
22
+ "recall": 0.3157262905162065,
23
+ "f1-score": 0.27568134171907754,
24
+ "support": 833.0
25
+ },
26
+ "turn_right": {
27
+ "precision": 0.18967452300785634,
28
+ "recall": 0.20609756097560974,
29
+ "f1-score": 0.19754529514903565,
30
+ "support": 820.0
31
+ },
32
+ "accuracy": 0.5755178031184547,
33
+ "macro avg": {
34
+ "precision": 0.3944723860966154,
35
+ "recall": 0.39156334041323,
36
+ "f1-score": 0.3915542657655546,
37
+ "support": 8594.0
38
+ },
39
+ "weighted avg": {
40
+ "precision": 0.5874514202574582,
41
+ "recall": 0.5755178031184547,
42
+ "f1-score": 0.5807008272180106,
43
+ "support": 8594.0
44
+ }
45
+ }
config.json CHANGED
@@ -2,7 +2,7 @@
2
  "schema": "gdc_taxi_maneuver_release_config_v1",
3
  "model_id": "generaldata/YellowCab",
4
  "model_name": "YellowCab",
5
- "model_version": "v0",
6
  "task": "predict a GPS-derived maneuver proxy approximately 20 seconds ahead",
7
  "release_status": "public_research_release",
8
  "actuation_allowed": false,
@@ -212,34 +212,34 @@
212
  "source_example_count": 55711,
213
  "standard_deviation": "population_ddof_0",
214
  "missing_value_imputation_used": false,
215
- "arithmetic": "parse as float64, subtract float64 mean, divide by float64 std, then cast to float32",
216
  "mean": [
217
- 5.157084550141056,
218
- 5.055907504105811,
219
- 0.005347144408599654,
220
- -0.7335137853872429,
221
- -0.03728550645057143,
222
- -0.016535674384678782,
223
- 0.000406427351177191,
224
- 4.231490900988432,
225
- -0.24272832272310887,
226
- 0.6515114276493843,
227
- 0.08530019265689594,
228
- -0.07634009204840192
229
  ],
230
  "std": [
231
- 5.041778031679111,
232
- 5.164075560213916,
233
- 0.1699205233493807,
234
- 34.07308988288982,
235
- 1.7367109919849695,
236
- 0.7173100379931885,
237
- 0.6965577619147336,
238
- 1.9923153400250748,
239
- 0.6107164796141349,
240
- 0.3790002671740555,
241
- 0.6974503447543176,
242
- 0.7074313281731461
243
  ]
244
  }
245
  },
@@ -261,8 +261,8 @@
261
  },
262
  "calibration": {
263
  "method": "temperature_scaling",
264
- "temperature": 0.9275532364845276,
265
- "fit_split": "validation_after_restoring_best_epoch_3",
266
  "independent_calibration_split": false
267
  },
268
  "abstention": {
@@ -272,18 +272,55 @@
272
  },
273
  "checkpoint": {
274
  "file": "model.safetensors",
275
- "sha256": "241f8335bdbe45e9f88e45640b35e3426e2c1e8fd58b9e0bec774a417988d57c",
276
- "bytes": 21384660,
277
  "parameter_count": 5294233,
278
  "state_tensor_count": 376,
279
  "state_numel": 5336298,
280
  "state_dtypes": {
281
  "torch.float32": 327,
282
  "torch.int64": 49
283
- }
 
284
  },
285
  "warnings": [
286
  "research model; not a safety-certified vehicle-control system",
287
  "validate performance and calibration for the intended domain before use"
288
- ]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
289
  }
 
2
  "schema": "gdc_taxi_maneuver_release_config_v1",
3
  "model_id": "generaldata/YellowCab",
4
  "model_name": "YellowCab",
5
+ "model_version": "v0.1-causal",
6
  "task": "predict a GPS-derived maneuver proxy approximately 20 seconds ahead",
7
  "release_status": "public_research_release",
8
  "actuation_allowed": false,
 
212
  "source_example_count": 55711,
213
  "standard_deviation": "population_ddof_0",
214
  "missing_value_imputation_used": false,
215
+ "arithmetic": "parse as float64, subtract float32 training mean, divide by float32 training standard deviation, then cast to float32",
216
  "mean": [
217
+ 5.1570844650268555,
218
+ 5.055907726287842,
219
+ 0.005347144324332476,
220
+ -0.7335137724876404,
221
+ -0.03728550672531128,
222
+ -0.01271896529942751,
223
+ 0.08169970661401749,
224
+ 4.2314910888671875,
225
+ -0.2427283227443695,
226
+ 0.6515114307403564,
227
+ 0.08530019223690033,
228
+ -0.07634009420871735
229
  ],
230
  "std": [
231
+ 5.041778087615967,
232
+ 5.1640753746032715,
233
+ 0.16992051899433136,
234
+ 34.073089599609375,
235
+ 1.736711025238037,
236
+ 0.6867451071739197,
237
+ 0.7221804261207581,
238
+ 1.9923152923583984,
239
+ 0.6107164621353149,
240
+ 0.3790002763271332,
241
+ 0.6974503397941589,
242
+ 0.7074313163757324
243
  ]
244
  }
245
  },
 
261
  },
262
  "calibration": {
263
  "method": "temperature_scaling",
264
+ "temperature": 1.106177568435669,
265
+ "fit_split": "validation_after_restoring_best_epoch_4",
266
  "independent_calibration_split": false
267
  },
268
  "abstention": {
 
272
  },
273
  "checkpoint": {
274
  "file": "model.safetensors",
275
+ "sha256": "af1a98cd96bb68d642f7a0adeedfacac37b230917afc15f3c87230a99a15b8a2",
276
+ "bytes": 21384748,
277
  "parameter_count": 5294233,
278
  "state_tensor_count": 376,
279
  "state_numel": 5336298,
280
  "state_dtypes": {
281
  "torch.float32": 327,
282
  "torch.int64": 49
283
+ },
284
+ "source_checkpoint_sha256": "0cb9c71d5be8f7671029e459c24179863ae2abff3ccfec1b5837c169d7d6c703"
285
  },
286
  "warnings": [
287
  "research model; not a safety-certified vehicle-control system",
288
  "validate performance and calibration for the intended domain before use"
289
+ ],
290
+ "training": {
291
+ "manifest_sha256": "8b92ad563892776cc25148f39fec6bf207e1e442c618b58fb07af7e2b899364d",
292
+ "split_sha256": "bfc5e960c8af32d0ea75a5e293bb95b3125111ace2cf8452eb42feb4bc2a1a5e",
293
+ "samples": 74680,
294
+ "routes": 36,
295
+ "split_samples": {
296
+ "train": 55711,
297
+ "validation": 10375,
298
+ "test": 8594
299
+ },
300
+ "split_routes": {
301
+ "train": 26,
302
+ "validation": 5,
303
+ "test": 5
304
+ },
305
+ "seed": 20260726,
306
+ "epochs_completed": 8,
307
+ "best_validation_macro_f1": 0.37644976936491265,
308
+ "causal_input_policy": "When past-to-current displacement is below 4 m, encode unknown current heading as sin=0 and cos=1. No future bearing is used.",
309
+ "future_derived_model_inputs": 0
310
+ },
311
+ "evaluation": {
312
+ "artifact": "evaluation.json",
313
+ "checkpoint_specific": true,
314
+ "primary_metric": "macro_f1",
315
+ "test_samples": 8594,
316
+ "test_routes": 5,
317
+ "macro_f1": 0.3915542657655546,
318
+ "macro_f1_route_ci_95": [
319
+ 0.34762239048615595,
320
+ 0.42805096076291543
321
+ ],
322
+ "balanced_accuracy": 0.39156334041323,
323
+ "accuracy": 0.5755178031184547,
324
+ "ece_15_bin": 0.011817411647322817
325
+ }
326
  }
confusion_matrix.png ADDED
eval_predictions.csv ADDED
The diff for this file is too large to render. See raw diff
 
evaluation.json ADDED
@@ -0,0 +1,344 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "schema": "gdc_yellowcab_public_evaluation_v1",
3
+ "checkpoint": {
4
+ "source_file_sha256": "0cb9c71d5be8f7671029e459c24179863ae2abff3ccfec1b5837c169d7d6c703",
5
+ "published_file": "model.safetensors",
6
+ "published_sha256": "af1a98cd96bb68d642f7a0adeedfacac37b230917afc15f3c87230a99a15b8a2",
7
+ "training_manifest_sha256": "8b92ad563892776cc25148f39fec6bf207e1e442c618b58fb07af7e2b899364d",
8
+ "split_sha256": "bfc5e960c8af32d0ea75a5e293bb95b3125111ace2cf8452eb42feb4bc2a1a5e"
9
+ },
10
+ "causal_input_audit": {
11
+ "policy": "When past-to-current displacement is below 4 m, encode unknown current heading as sin=0 and cos=1. No future bearing is used.",
12
+ "corrected_rows": 5974,
13
+ "total_rows": 74680,
14
+ "future_derived_model_inputs": 0
15
+ },
16
+ "protocol": {
17
+ "label_type": "GPS-derived silver maneuver proxy",
18
+ "forecast_horizon": "approximately 20 seconds",
19
+ "split_policy": "Complete forward-in-time route holdout; no frame from a validation or test route enters training.",
20
+ "dataset_samples": 74680,
21
+ "dataset_routes": 36,
22
+ "test_samples": 8594,
23
+ "test_routes": 5,
24
+ "training_seed": 20260726,
25
+ "route_bootstrap_iterations": 500
26
+ },
27
+ "primary_result": {
28
+ "model": "Temporal efficientnet_b0 + telemetry",
29
+ "samples": 8594,
30
+ "accuracy": 0.5755178031184547,
31
+ "balanced_accuracy": 0.39156334041323,
32
+ "macro_f1": 0.3915542657655546,
33
+ "weighted_f1": 0.5807008272180106,
34
+ "log_loss": 1.0841176199931875,
35
+ "brier_score": 0.5563128377237149,
36
+ "ece_15_bin": 0.011817411647322817,
37
+ "p95_latency_ms": 95.37229499110252,
38
+ "continue_recall": 0.7393577296489918,
39
+ "continue_f1": 0.7492904446546831,
40
+ "slow_recall": 0.35436382754994744,
41
+ "slow_f1": 0.37716843872411865,
42
+ "stop_recall": 0.3422712933753943,
43
+ "stop_f1": 0.3580858085808581,
44
+ "turn_left_recall": 0.3157262905162065,
45
+ "turn_left_f1": 0.27568134171907754,
46
+ "turn_right_recall": 0.20609756097560974,
47
+ "turn_right_f1": 0.19754529514903565,
48
+ "macro_f1_route_ci_low": 0.34762239048615595,
49
+ "macro_f1_route_ci_high": 0.42805096076291543
50
+ },
51
+ "baselines": [
52
+ {
53
+ "model": "Temporal efficientnet_b0 + telemetry",
54
+ "samples": 8594,
55
+ "accuracy": 0.5755178031184547,
56
+ "balanced_accuracy": 0.39156334041323,
57
+ "macro_f1": 0.3915542657655546,
58
+ "weighted_f1": 0.5807008272180106,
59
+ "log_loss": 1.0841176199931877,
60
+ "brier_score": 0.5563128377237149,
61
+ "ece_15_bin": 0.0118174116473228,
62
+ "p95_latency_ms": 95.37229499110252,
63
+ "continue_recall": 0.7393577296489918,
64
+ "continue_f1": 0.7492904446546831,
65
+ "slow_recall": 0.3543638275499474,
66
+ "slow_f1": 0.3771684387241186,
67
+ "stop_recall": 0.3422712933753943,
68
+ "stop_f1": 0.3580858085808581,
69
+ "turn_left_recall": 0.3157262905162065,
70
+ "turn_left_f1": 0.2756813417190775,
71
+ "turn_right_recall": 0.2060975609756097,
72
+ "turn_right_f1": 0.1975452951490356,
73
+ "macro_f1_route_ci_low": 0.3476223904861559,
74
+ "macro_f1_route_ci_high": 0.4280509607629154
75
+ },
76
+ {
77
+ "model": "Telemetry gradient boosting",
78
+ "samples": 8594,
79
+ "accuracy": 0.4147079357691413,
80
+ "balanced_accuracy": 0.4216633099655398,
81
+ "macro_f1": 0.341392924380058,
82
+ "weighted_f1": 0.4530356863806382,
83
+ "log_loss": 1.2490630281069546,
84
+ "brier_score": 0.6566714449096165,
85
+ "ece_15_bin": 0.1216700885218681,
86
+ "p95_latency_ms": NaN,
87
+ "continue_recall": 0.4051530993278566,
88
+ "continue_f1": 0.5513911828230212,
89
+ "slow_recall": 0.6466876971608833,
90
+ "slow_f1": 0.3416666666666667,
91
+ "stop_recall": 0.4889589905362776,
92
+ "stop_f1": 0.2986512524084778,
93
+ "turn_left_recall": 0.2797118847539016,
94
+ "turn_left_f1": 0.2583148558758315,
95
+ "turn_right_recall": 0.2878048780487804,
96
+ "turn_right_f1": 0.2569406641262928,
97
+ "macro_f1_route_ci_low": 0.3149153283503967,
98
+ "macro_f1_route_ci_high": 0.3493997015446531
99
+ },
100
+ {
101
+ "model": "Vision linear (efficientnet_b0)",
102
+ "samples": 8594,
103
+ "accuracy": 0.5751687223644403,
104
+ "balanced_accuracy": 0.2967510353079744,
105
+ "macro_f1": 0.305034605073554,
106
+ "weighted_f1": 0.5344562546214928,
107
+ "log_loss": 10.24602122531317,
108
+ "brier_score": 0.8349054717132016,
109
+ "ece_15_bin": 0.4091336187074714,
110
+ "p95_latency_ms": NaN,
111
+ "continue_recall": 0.8269230769230769,
112
+ "continue_f1": 0.7406354515050168,
113
+ "slow_recall": 0.1556256572029442,
114
+ "slow_f1": 0.2148040638606676,
115
+ "stop_recall": 0.252365930599369,
116
+ "stop_f1": 0.255591054313099,
117
+ "turn_left_recall": 0.1500600240096038,
118
+ "turn_left_f1": 0.1810282404055032,
119
+ "turn_right_recall": 0.098780487804878,
120
+ "turn_right_f1": 0.1331142152834839,
121
+ "macro_f1_route_ci_low": 0.2678056005630319,
122
+ "macro_f1_route_ci_high": 0.3273143437147999
123
+ },
124
+ {
125
+ "model": "Past-motion rule",
126
+ "samples": 8594,
127
+ "accuracy": 0.4549685827321387,
128
+ "balanced_accuracy": 0.223773826591683,
129
+ "macro_f1": 0.2235297785953733,
130
+ "weighted_f1": 0.4532542316647034,
131
+ "log_loss": 2.058490921490782,
132
+ "brier_score": 0.966304980218757,
133
+ "ece_15_bin": 0.4450314172678615,
134
+ "p95_latency_ms": NaN,
135
+ "continue_recall": 0.6562733383121733,
136
+ "continue_f1": 0.6534064504136072,
137
+ "slow_recall": 0.1019978969505783,
138
+ "slow_f1": 0.0962779156327543,
139
+ "stop_recall": 0.0,
140
+ "stop_f1": 0.0,
141
+ "turn_left_recall": 0.1776710684273709,
142
+ "turn_left_f1": 0.1792852816474863,
143
+ "turn_right_recall": 0.1829268292682926,
144
+ "turn_right_f1": 0.1886792452830188,
145
+ "macro_f1_route_ci_low": 0.1873463820585989,
146
+ "macro_f1_route_ci_high": 0.2345195759071031
147
+ },
148
+ {
149
+ "model": "Telemetry logistic",
150
+ "samples": 8594,
151
+ "accuracy": 0.196299744007447,
152
+ "balanced_accuracy": 0.2871892331606019,
153
+ "macro_f1": 0.1886698746182765,
154
+ "weighted_f1": 0.1861407158506876,
155
+ "log_loss": 1.5832758165931655,
156
+ "brier_score": 0.8215841116420504,
157
+ "ece_15_bin": 0.1432688177654283,
158
+ "p95_latency_ms": NaN,
159
+ "continue_recall": 0.109596713965646,
160
+ "continue_f1": 0.1816212871287128,
161
+ "slow_recall": 0.601472134595163,
162
+ "slow_f1": 0.2506024096385542,
163
+ "stop_recall": 0.3706624605678233,
164
+ "stop_f1": 0.1760959160734357,
165
+ "turn_left_recall": 0.1956782713085234,
166
+ "turn_left_f1": 0.1721224920802534,
167
+ "turn_right_recall": 0.1585365853658536,
168
+ "turn_right_f1": 0.162907268170426,
169
+ "macro_f1_route_ci_low": 0.1839562547318565,
170
+ "macro_f1_route_ci_high": 0.2044359347158287
171
+ },
172
+ {
173
+ "model": "Majority class",
174
+ "samples": 8594,
175
+ "accuracy": 0.6232255061670933,
176
+ "balanced_accuracy": 0.2,
177
+ "macro_f1": 0.1535770609318996,
178
+ "weighted_f1": 0.4785657076746885,
179
+ "log_loss": 1.1837257781136636,
180
+ "brier_score": 0.5768401032344809,
181
+ "ece_15_bin": 0.032749657591408,
182
+ "p95_latency_ms": NaN,
183
+ "continue_recall": 1.0,
184
+ "continue_f1": 0.7678853046594982,
185
+ "slow_recall": 0.0,
186
+ "slow_f1": 0.0,
187
+ "stop_recall": 0.0,
188
+ "stop_f1": 0.0,
189
+ "turn_left_recall": 0.0,
190
+ "turn_left_f1": 0.0,
191
+ "turn_right_recall": 0.0,
192
+ "turn_right_f1": 0.0,
193
+ "macro_f1_route_ci_low": 0.1460915032679738,
194
+ "macro_f1_route_ci_high": 0.1554760284937855
195
+ }
196
+ ],
197
+ "per_class": [
198
+ {
199
+ "model": "Temporal efficientnet_b0 + telemetry",
200
+ "class": "continue",
201
+ "precision": 0.759493670886076,
202
+ "recall": 0.7393577296489918,
203
+ "f1": 0.7492904446546831,
204
+ "support": 5356
205
+ },
206
+ {
207
+ "model": "Temporal efficientnet_b0 + telemetry",
208
+ "class": "slow",
209
+ "precision": 0.40311004784689,
210
+ "recall": 0.3543638275499474,
211
+ "f1": 0.3771684387241186,
212
+ "support": 951
213
+ },
214
+ {
215
+ "model": "Temporal efficientnet_b0 + telemetry",
216
+ "class": "stop",
217
+ "precision": 0.3754325259515571,
218
+ "recall": 0.3422712933753943,
219
+ "f1": 0.3580858085808581,
220
+ "support": 634
221
+ },
222
+ {
223
+ "model": "Temporal efficientnet_b0 + telemetry",
224
+ "class": "turn_left",
225
+ "precision": 0.2446511627906976,
226
+ "recall": 0.3157262905162065,
227
+ "f1": 0.2756813417190775,
228
+ "support": 833
229
+ },
230
+ {
231
+ "model": "Temporal efficientnet_b0 + telemetry",
232
+ "class": "turn_right",
233
+ "precision": 0.1896745230078563,
234
+ "recall": 0.2060975609756097,
235
+ "f1": 0.1975452951490356,
236
+ "support": 820
237
+ }
238
+ ],
239
+ "subsets": [
240
+ {
241
+ "model": "Temporal efficientnet_b0 + telemetry",
242
+ "subset": "all_test",
243
+ "samples": 8594,
244
+ "macro_f1": 0.3915542657655546,
245
+ "balanced_accuracy": 0.39156334041323,
246
+ "accuracy": 0.5755178031184547
247
+ },
248
+ {
249
+ "model": "Temporal efficientnet_b0 + telemetry",
250
+ "subset": "unseen_grid_cells",
251
+ "samples": 1846,
252
+ "macro_f1": 0.3342824235159851,
253
+ "balanced_accuracy": 0.3360174291252364,
254
+ "accuracy": 0.5384615384615384
255
+ },
256
+ {
257
+ "model": "Temporal efficientnet_b0 + telemetry",
258
+ "subset": "night_utc",
259
+ "samples": 6930,
260
+ "macro_f1": 0.4102137401798389,
261
+ "balanced_accuracy": 0.4080902962744183,
262
+ "accuracy": 0.5946608946608947
263
+ },
264
+ {
265
+ "model": "Temporal efficientnet_b0 + telemetry",
266
+ "subset": "gps_accuracy_le_10m",
267
+ "samples": 8319,
268
+ "macro_f1": 0.393316436996118,
269
+ "balanced_accuracy": 0.3936744515708604,
270
+ "accuracy": 0.5783147012862123
271
+ }
272
+ ],
273
+ "selective_prediction": [
274
+ {
275
+ "confidence_threshold": 0.0,
276
+ "coverage": 1.0,
277
+ "accepted_examples": 8594,
278
+ "selective_accuracy": 0.5755178031184547,
279
+ "selective_macro_f1": 0.3915542657655546
280
+ },
281
+ {
282
+ "confidence_threshold": 0.25,
283
+ "coverage": 0.9987200372352804,
284
+ "accepted_examples": 8583,
285
+ "selective_accuracy": 0.5760223698007689,
286
+ "selective_macro_f1": 0.3919543899984051
287
+ },
288
+ {
289
+ "confidence_threshold": 0.35,
290
+ "coverage": 0.9100535257156156,
291
+ "accepted_examples": 7821,
292
+ "selective_accuracy": 0.6006904487917146,
293
+ "selective_macro_f1": 0.4060706565050537
294
+ },
295
+ {
296
+ "confidence_threshold": 0.45,
297
+ "coverage": 0.6947870607400511,
298
+ "accepted_examples": 5971,
299
+ "selective_accuracy": 0.658348685312343,
300
+ "selective_macro_f1": 0.4327252057994619
301
+ },
302
+ {
303
+ "confidence_threshold": 0.55,
304
+ "coverage": 0.4717244589248313,
305
+ "accepted_examples": 4054,
306
+ "selective_accuracy": 0.7323630981746423,
307
+ "selective_macro_f1": 0.470227025478709
308
+ },
309
+ {
310
+ "confidence_threshold": 0.65,
311
+ "coverage": 0.3019548522224808,
312
+ "accepted_examples": 2595,
313
+ "selective_accuracy": 0.8092485549132948,
314
+ "selective_macro_f1": 0.5275062675719726
315
+ },
316
+ {
317
+ "confidence_threshold": 0.75,
318
+ "coverage": 0.1748894577612287,
319
+ "accepted_examples": 1503,
320
+ "selective_accuracy": 0.8782435129740519,
321
+ "selective_macro_f1": 0.5566727737271018
322
+ },
323
+ {
324
+ "confidence_threshold": 0.85,
325
+ "coverage": 0.0829648592040958,
326
+ "accepted_examples": 713,
327
+ "selective_accuracy": 0.938288920056101,
328
+ "selective_macro_f1": 0.6097924940442192
329
+ }
330
+ ],
331
+ "calibration": {
332
+ "method": "temperature scaling",
333
+ "temperature": 1.106177568435669,
334
+ "fit_split": "validation after restoring the best checkpoint",
335
+ "independent_calibration_split": false
336
+ },
337
+ "limitations": [
338
+ "Labels are GPS-derived proxies rather than human safety annotations.",
339
+ "The test set contains five held-out routes from one operating domain.",
340
+ "Raw accuracy is distorted by the majority continue class; macro F1 is primary.",
341
+ "The calibration set is the validation split, not an independent fourth split.",
342
+ "This evaluation is not evidence of safe vehicle control."
343
+ ]
344
+ }
model.safetensors CHANGED
@@ -1,3 +1,3 @@
1
  version https://git-lfs.github.com/spec/v1
2
- oid sha256:241f8335bdbe45e9f88e45640b35e3426e2c1e8fd58b9e0bec774a417988d57c
3
- size 21384660
 
1
  version https://git-lfs.github.com/spec/v1
2
+ oid sha256:af1a98cd96bb68d642f7a0adeedfacac37b230917afc15f3c87230a99a15b8a2
3
+ size 21384748
recompute_metrics.py ADDED
@@ -0,0 +1,120 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Recompute YellowCab's public held-out metrics from sanitized predictions."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import json
6
+ from pathlib import Path
7
+
8
+ import numpy as np
9
+ import pandas as pd
10
+ from sklearn.metrics import (
11
+ accuracy_score,
12
+ balanced_accuracy_score,
13
+ brier_score_loss,
14
+ f1_score,
15
+ log_loss,
16
+ )
17
+
18
+
19
+ CLASSES = ("continue", "slow", "stop", "turn_left", "turn_right")
20
+ SEED = 20260726
21
+ BOOTSTRAP_ITERATIONS = 500
22
+
23
+
24
+ def expected_calibration_error(
25
+ probabilities: np.ndarray,
26
+ targets: np.ndarray,
27
+ *,
28
+ bins: int = 15,
29
+ ) -> float:
30
+ confidence = probabilities.max(axis=1)
31
+ predictions = probabilities.argmax(axis=1)
32
+ correct = predictions == targets
33
+ edges = np.linspace(0.0, 1.0, bins + 1)
34
+ value = 0.0
35
+ for index in range(bins):
36
+ if index == bins - 1:
37
+ mask = (confidence >= edges[index]) & (confidence <= edges[index + 1])
38
+ else:
39
+ mask = (confidence >= edges[index]) & (confidence < edges[index + 1])
40
+ if mask.any():
41
+ value += float(mask.mean()) * abs(
42
+ float(correct[mask].mean()) - float(confidence[mask].mean())
43
+ )
44
+ return value
45
+
46
+
47
+ def route_bootstrap_macro_f1(
48
+ frame: pd.DataFrame,
49
+ targets: np.ndarray,
50
+ predictions: np.ndarray,
51
+ ) -> tuple[float, float]:
52
+ route_values = frame["route_group"].astype(str).to_numpy()
53
+ routes = np.unique(route_values)
54
+ rng = np.random.default_rng(SEED)
55
+ values: list[float] = []
56
+ for _ in range(BOOTSTRAP_ITERATIONS):
57
+ sampled = rng.choice(routes, size=len(routes), replace=True)
58
+ indices = np.concatenate(
59
+ [np.flatnonzero(route_values == route) for route in sampled]
60
+ )
61
+ values.append(
62
+ float(
63
+ f1_score(
64
+ targets[indices],
65
+ predictions[indices],
66
+ labels=np.arange(len(CLASSES)),
67
+ average="macro",
68
+ zero_division=0,
69
+ )
70
+ )
71
+ )
72
+ return tuple(float(value) for value in np.quantile(values, [0.025, 0.975]))
73
+
74
+
75
+ def main() -> None:
76
+ root = Path(__file__).resolve().parent
77
+ frame = pd.read_csv(root / "eval_predictions.csv")
78
+ class_to_index = {name: index for index, name in enumerate(CLASSES)}
79
+ targets = frame["label"].map(class_to_index).to_numpy(dtype=np.int64)
80
+ predictions = frame["prediction"].map(class_to_index).to_numpy(dtype=np.int64)
81
+ probabilities = frame[
82
+ [f"prob_{class_name}" for class_name in CLASSES]
83
+ ].to_numpy(dtype=np.float64)
84
+ if not np.allclose(probabilities.sum(axis=1), 1.0, atol=1e-6):
85
+ raise ValueError("Probability rows do not sum to one")
86
+ one_hot = np.eye(len(CLASSES), dtype=np.float64)[targets]
87
+ ci_low, ci_high = route_bootstrap_macro_f1(frame, targets, predictions)
88
+ result = {
89
+ "samples": int(len(frame)),
90
+ "routes": int(frame["route_group"].nunique()),
91
+ "accuracy": float(accuracy_score(targets, predictions)),
92
+ "balanced_accuracy": float(balanced_accuracy_score(targets, predictions)),
93
+ "macro_f1": float(
94
+ f1_score(
95
+ targets,
96
+ predictions,
97
+ labels=np.arange(len(CLASSES)),
98
+ average="macro",
99
+ zero_division=0,
100
+ )
101
+ ),
102
+ "weighted_f1": float(
103
+ f1_score(
104
+ targets,
105
+ predictions,
106
+ labels=np.arange(len(CLASSES)),
107
+ average="weighted",
108
+ zero_division=0,
109
+ )
110
+ ),
111
+ "log_loss": float(log_loss(targets, probabilities, labels=range(len(CLASSES)))),
112
+ "brier_score": float(np.mean(np.sum((probabilities - one_hot) ** 2, axis=1))),
113
+ "ece_15_bin": expected_calibration_error(probabilities, targets),
114
+ "macro_f1_route_ci_95": [ci_low, ci_high],
115
+ }
116
+ print(json.dumps(result, indent=2))
117
+
118
+
119
+ if __name__ == "__main__":
120
+ main()
selective_metrics.csv ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ confidence_threshold,coverage,accepted_examples,selective_accuracy,selective_macro_f1
2
+ 0.0,1.0,8594,0.5755178031184547,0.3915542657655546
3
+ 0.25,0.9987200372352805,8583,0.5760223698007689,0.3919543899984051
4
+ 0.35,0.9100535257156156,7821,0.6006904487917146,0.4060706565050537
5
+ 0.45,0.6947870607400511,5971,0.658348685312343,0.43272520579946194
6
+ 0.55,0.4717244589248313,4054,0.7323630981746423,0.470227025478709
7
+ 0.65,0.3019548522224808,2595,0.8092485549132948,0.5275062675719726
8
+ 0.75,0.17488945776122877,1503,0.8782435129740519,0.5566727737271018
9
+ 0.85,0.08296485920409588,713,0.938288920056101,0.6097924940442192
subset_metrics.csv ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ model,subset,samples,macro_f1,balanced_accuracy,accuracy
2
+ Majority class,all_test,8594,0.1535770609318996,0.2,0.6232255061670933
3
+ Majority class,unseen_grid_cells,1846,0.1571052631578947,0.2,0.6468039003250271
4
+ Majority class,night_utc,6930,0.1544077257021351,0.2,0.6287157287157287
5
+ Majority class,gps_accuracy_le_10m,8319,0.153802900266351,0.2,0.6247145089554033
6
+ Past-motion rule,all_test,8594,0.2235297785953733,0.223773826591683,0.4549685827321387
7
+ Past-motion rule,unseen_grid_cells,1846,0.2332335187587507,0.236197410832345,0.4842903575297941
8
+ Past-motion rule,night_utc,6930,0.2274748552099628,0.2276228825290112,0.4647907647907648
9
+ Past-motion rule,gps_accuracy_le_10m,8319,0.2233687790979745,0.2235505984136381,0.4570260848659694
10
+ Telemetry logistic,all_test,8594,0.1886698746182765,0.2871892331606019,0.196299744007447
11
+ Telemetry logistic,unseen_grid_cells,1846,0.1725156222420228,0.256991711558178,0.189599133261105
12
+ Telemetry logistic,night_utc,6930,0.1896834893067224,0.284189614812793,0.1988455988455988
13
+ Telemetry logistic,gps_accuracy_le_10m,8319,0.1864075839388003,0.2847033040497686,0.1962976319269143
14
+ Telemetry gradient boosting,all_test,8594,0.341392924380058,0.4216633099655398,0.4147079357691413
15
+ Telemetry gradient boosting,unseen_grid_cells,1846,0.3136214897768011,0.386078121522199,0.3959913326110509
16
+ Telemetry gradient boosting,night_utc,6930,0.3470049007798196,0.4262284930269192,0.4278499278499278
17
+ Telemetry gradient boosting,gps_accuracy_le_10m,8319,0.3426226516709886,0.4236167573460645,0.4168770284890011
18
+ Vision linear (efficientnet_b0),all_test,8594,0.305034605073554,0.2967510353079744,0.5751687223644403
19
+ Vision linear (efficientnet_b0),unseen_grid_cells,1846,0.2928477852235921,0.2881051221485449,0.5893824485373781
20
+ Vision linear (efficientnet_b0),night_utc,6930,0.3217391911486912,0.3126224230959082,0.5862914862914863
21
+ Vision linear (efficientnet_b0),gps_accuracy_le_10m,8319,0.3060672066310756,0.2972976109580328,0.576631806707537
22
+ Temporal efficientnet_b0 + telemetry,all_test,8594,0.3915542657655546,0.39156334041323,0.5755178031184547
23
+ Temporal efficientnet_b0 + telemetry,unseen_grid_cells,1846,0.3342824235159851,0.3360174291252364,0.5384615384615384
24
+ Temporal efficientnet_b0 + telemetry,night_utc,6930,0.4102137401798389,0.4080902962744183,0.5946608946608947
25
+ Temporal efficientnet_b0 + telemetry,gps_accuracy_le_10m,8319,0.393316436996118,0.3936744515708604,0.5783147012862123