🦺 PPE 21-attr SOTA 研究報告
2026-05-18 · cvat2 #12 partial-label test split (12,856 rows) · 8 hr autonomous research on 5090-2
核心結論:Phase 5 Ensemble 在 21 個可評估 attr 平均 recall @ precision≥0.95 達到 0.9142,比現役 v515b baseline (0.8062) 提升 +10.8 個百分點。
這次研究的主指標是 recall @ precision≥0.95(每個 attr 在 precision 鎖定 95% 下能拉到的 recall)— 這是「低誤報率」場景最相關的指標,比 mAP / F1 更貼近 production iSeek 通報需求。
📊 整體指標總覽
v515b baseline0.806mean R@P95
CvN-Base + TTA0.881+7.4 pp
CvN-Large + TTA0.882+7.6 pp
Phase 5 Ensemble ⭐0.914+10.8 pp
| Stack | mean R@P95 | mean F1max | mean AP | 推論成本 | 備註 |
| v504 (production) | 0.8059 | 0.9178 | — | 1× | MobileNetV3-L 21-attr |
| v515 multitask (22-attr) | 0.8007 | 0.9418 | — | 1× | strong aug + harness neg_w=20 |
| v515b (22-attr) | 0.8062 | 0.9306 | 0.9616 | 1× | camaug + 對齊 v504 |
| VLM Qwen2.5-VL-3B zero-shot | 0.1948 | 0.7149 | — | ~5× | 3-point P-R curve 限制 |
| ConvNeXt-Base (fine-tune) | 0.8729 | 0.9483 | 0.9723 | 1× | 新訓,88M params |
| ConvNeXt-Base + hflip TTA | 0.8806 | 0.9491 | 0.9729 | 2× | +0.0077 free lift |
| ConvNeXt-Large (fine-tune) | 0.8710 | 0.9499 | 0.9724 | 1× | 新訓,198M params,ep9 早停 |
| ConvNeXt-Large + hflip TTA | 0.8822 | 0.9508 | 0.9731 | 2× | +0.0112 free lift |
| ViT-Base DINOv3 + TTA | 0.8676 | 0.9444 | — | 2× | 新訓,frozen DINOv3 backbone |
| ViT-Large SigLIP + TTA | 0.8359 | 0.9290 | — | 2× | 新訓,305M params |
| Phase 5 Ensemble ⭐ | 0.9142 | 0.9586 | 0.9799 | 4-7× | per-attr greedy logit-avg |
🚀 主要進步來源
Ensemble 比單一最佳 model (CvN-L+TTA) 再提升 +3.2pp,主要 win 在以下 attr:
| attr | n_pos | baseline (v515b) | best single | Ensemble | Δ vs baseline | 進步來源 |
| no_safety_shoes | 18 | 0.722 | 0.833 (CvN-B) | 0.944 | +0.222 | CvN-B + v515mt 投票,超低樣本 attr 互補 |
| full_face_mask | 1210 | 0.953 | 0.984 | 0.988 | +0.035 | CvN-B+TTA + CvN-L |
| safety_glasses | 595 | 0.817 | 0.992 | 0.995 | +0.178 | CvN-L + CvN-L+TTA (大 backbone 主要 win) |
| heartbeat | 148 | 0.297 | 0.696 | 0.784 | +0.487 | DINOv3-B+TTA + SigLIP-L + CvN-L+TTA 多 backbone 互補 |
| no_head_protection | 1070 | 0.875 | 0.978 | 0.981 | +0.106 | CvN-B+TTA + CvN-L+TTA + v504 |
| safety_shoes | 88 | 0.557 | 0.830 | 0.830 | +0.273 | CvN-L 單模型已勝出 |
| safety_vest | 1788 | 0.829 | 0.933 | 0.950 | +0.121 | CvN-L+TTA + v515mt + SigLIP-L+TTA |
| harness | 1748 | 0.709 | 0.743 | 0.784 | +0.075 | CvN-L+TTA + v504 + v515mt + CvN-L 四票 |
| face_mask | 1089 | 0.935 | 0.998 | 0.998 | +0.063 | CvN-B+TTA 單模型已 ceiling |
| fall | 78 | 0.795 | 0.936 | 0.949 | +0.154 | CvN-B + SigLIP-L+TTA |
🔍 完整 per-attr 對照(baseline vs SOTA Ensemble)
主指標 recall @ precision≥0.95;綠底=Ensemble win baseline ≥+0.05;紅底=沒進步 (Δ ≤ 0)。
| attr | n_pos | v504 | v515b | CvN-L+TTA | Ensemble | Δ (Ens − v515b) | 判斷 |
| hard_hat | 3489 | 0.991 | 0.988 | 0.997 | 0.998 | +0.010 | 已近 ceiling |
| no_head_protection | 1070 | 0.902 | 0.875 | 0.976 | 0.981 | +0.106 | 大幅進步 |
| full_face_mask | 1210 | 0.750 | 0.953 | 0.983 | 0.988 | +0.035 | 進步 |
| face_mask | 1089 | 0.949 | 0.935 | 0.996 | 0.998 | +0.063 | 進步 |
| no_gloves | 479 | 0.823 | 0.962 | 1.000 | 1.000 | +0.038 | ceiling 達成 |
| cotton_gloves | 171 | 0.135 | 0.082 | 0.047 | 0.135 | +0.053 | ⚠️ 全模型都拉胯,真實弱點 |
| rubber_gloves | 632 | 1.000 | 1.000 | 1.000 | 1.000 | +0.000 | ceiling |
| no_protective_clothing | 668 | 1.000 | 0.996 | 0.999 | 1.000 | +0.004 | ceiling |
| cleanroom_suit | 51 | 1.000 | 1.000 | 1.000 | 1.000 | +0.000 | ceiling |
| splash_proof_gown | 540 | 1.000 | 1.000 | 1.000 | 1.000 | +0.000 | ceiling |
| safety_vest | 1788 | 0.875 | 0.829 | 0.933 | 0.950 | +0.121 | 大幅進步 |
| safety_shoes | 88 | 0.136 | 0.557 | 0.818 | 0.830 | +0.273 | 大幅進步 |
| no_safety_shoes | 18 | 0.778 | 0.722 | 0.556 | 0.944 | +0.222 | 大幅進步 |
| no_sleeves | 117 | 0.821 | 0.718 | 0.838 | 0.863 | +0.145 | 進步 |
| heartbeat | 148 | 0.581 | 0.297 | 0.649 | 0.784 | +0.487 | 巨幅進步 |
| sleeves | 5 | 1.000 | 0.600 | 0.800 | 1.000 | +0.400 | 樣本太少噪音大 |
| safety_glasses | 595 | 0.916 | 0.817 | 0.990 | 0.995 | +0.178 | 大幅進步 |
| hair_cover | 3 | 1.000 | 1.000 | 1.000 | 1.000 | +0.000 | 樣本=3 雜訊 |
| helmet_goggles | 222 | 1.000 | 1.000 | 1.000 | 1.000 | +0.000 | ceiling |
| harness | 1748 | 0.730 | 0.709 | 0.743 | 0.784 | +0.075 | 進步 |
| fall | 78 | 0.897 | 0.795 | 0.910 | 0.949 | +0.154 | 進步 |
| aluminized_apron | 0 | — | — | — | — | — | test set 全 unknown 無法評 |
| MEAN (21 OK attrs) | — | 0.8059 | 0.8062 | 0.8822 | 0.9142 | +0.1080 | +10.8 pp |
⚠️ 真實弱點 — 模型沒辦法救要補資料的 attr
cotton_gloves:所有 11 個 candidate 的 R@P95 都在
0.04 – 0.14 之間。Ensemble 也只到 0.135(基本就是 DINOv3-B single model 結果)。原因:模型對 cotton_gloves 的 prob 對真陽性常常落在 P=0.95 閾值之下(灰色棉手套 vs 一般灰色手部容易混淆)→
高 FP rate 把 threshold 推太高 → recall 死。光靠 ensemble + TTA + 大 backbone 沒救,必須:
- cvat2 #12 補更多 cotton_gloves 正樣本(現有 n_pos=171/394 valid)
- 補容易混淆的 hard negative(裸手沾灰、其他材質灰手套、空白灰背景手)
- 可能需要 per-attr 加 contrastive loss 或 hard negative mining
aluminized_apron:整個 test split 12,856 rows 都是 unknown。先前 LoRA 合成路線(v1/v2 兩次失敗)就是想補這個 attr 的 yes 樣本,但合成失敗。下一步:實際標真實 cvat2 task 累積 yes 樣本 → 用本次 SOTA 重新 evaluate。
🧠 VLM zero-shot 嘗試(部分有信號)
Qwen2.5-VL-3B 對 1499 stratified samples 跑 22 個 attr 的 yes/no/unclear prompt:整體 R@P95 = 0.195,遠低於 fine-tuned model。
主因是 hard yes/no 只給 3 點 P-R 曲線,多數 attr 達不到 P≥0.95 閾值。但少數 attr 仍有信號:
| attr | VLM R@P95 | VLM F1max | 觀察 |
| hard_hat | 0.824 | 0.896 | 大 attr 仍辨識得到 |
| rubber_gloves | 0.824 | 0.904 | 顏色/材質明顯 |
| harness | 0.449 | 0.610 | 中等信號 |
| full_face_mask | 0.000 | 0.851 | F1 高但 P=0.95 達不到 |
| cotton_gloves | 0.000 | 0.525 | VLM 也救不了 |
VLM 可能用法:conservative trigger — 只在「fine-tuned 模型說 yes」+「VLM 也說 yes」時才報 alarm。對 hard_hat / rubber_gloves / harness 三個關鍵 attr 預期可進一步降 FP,但需 production trial 驗證。
🏆 Top-3 部署選項
| Option | Stack | mean R@P95 | 推論成本 | complexity | 推薦度 |
| A | ConvNeXt-Base 單模型 | 0.873 | 1× (88M params) | 簡單 | 輕量 立即可上 |
| B | ConvNeXt-Large + hflip TTA | 0.882 | 2× (198M params) | 簡單 | 推薦 sweet spot |
| C | 3-model min-stack: DINOv3-B+TTA + CvN-L+TTA + CvN-L | ~0.91 | 3-6× | 中 | 平衡 |
| D | Phase 5 Full Ensemble (per-attr greedy) | 0.914 | 4-7× | 高 | 極致 適合離線 audit |
推薦先走 Option B:ConvNeXt-Large + hflip TTA 比 v515b 提升 +7.6pp recall@P=0.95,單 ckpt 部署簡單,2× inference cost 對 RTSP demo 仍可接受。先實際部署看 production iSeek FP / FN 變化,再決定要不要往 C/D 走。
📦 訓練 stack 詳細(4 個新 ckpt)
| 項目 | CvN-Base | CvN-Large | DINOv3-B | SigLIP-L |
| backbone | convnext_base.fb_in22k_ft_in1k | convnext_large.fb_in22k_ft_in1k | vit_base_patch14_dinov2.lvd142m | vit_large_patch16_siglip_384 |
| params | 88M | 198M | 86M (frozen) | 305M |
| img_size | [384, 192] | [384, 192] | [384, 192] | [384, 192] |
| train rows | 40,254 (crops_v515 Train) | 40,254 | 40,254 | 40,254 |
| val rows | 9,124 | 9,124 | 9,124 | 9,124 |
| test rows | 12,856 (crops_v515 Test) |
| epochs run | 15 | 9 (ep6 best) | 15 | 10 |
| val R@P95 | 0.943 | 0.956 | 0.940 | 0.913 |
| test R@P95 | 0.873 | 0.871 | 0.870 | 0.832 |
| ckpt size | 350.5 MB | 785.2 MB | 342.7 MB | 1213.8 MB |
| ckpt path | ~/runs_new/ppe_sota_v515/ckpts/<tag>/best.pt on 5090-2 |
val → test 約掉 7-8 pp:不是 overfitting,因為 baselines 也呈現同樣 gap(v515b val=0.99 → test=0.81)。原因是 test split 中 8006/12856 是 other source(與 train 主流 cvat2/p9/p17 不完全同分布),是 domain shift 不是過擬合。
🚫 已知 limitations(誠實列)
- partial-label test set 限制:per-attr valid 從 126 (no_safety_shoes) 到 11,210 (harness) 差距大,n_pos 個位數的 attr (hair_cover=3, sleeves=5, no_safety_shoes=18) 數字噪音大
- aluminized_apron 完全無法評估:test set 全 unknown,本次無法量化 SOTA stack 對這個 attr 的效果
- VLM 沒跑完 brief 預期的 7-34B 範圍:實際只跑 Qwen2.5-VL-3B(VRAM + disk 緊張,Qwen3-VL-8B / InternVL-2.5-8B / Llava-NeXT-34B 未跑)
- ConvNeXt-Large ep9 早停:ep6 best,patience 8 觸發。長 schedule + lower LR 預期還能再 +0.01-0.02
- 未做 multi-scale TTA:只用 hflip。multi-scale (384/448/512) 是後續 easy follow-up
- 未做 temperature scaling:對 R@P95 數學上無效(單調轉換不改 recall),如果未來需要 calibrated probability 給下游使用再做
- 沒部署:本次只研究 + 寫報告,user 決定是否部署到 ppe-demo。所有 ckpt 在 5090-2 本地,未上 R2
🎯 下一步建議(按 ROI 排序)
- 高 ROI 部署 Option B (CvN-L + hflip TTA) 到 model_viewer / ppe-demo,跑 1 週收 production iSeek FP / FN 對比 baseline → 證實效益
- 高 ROI 補 cotton_gloves hard negative + positive,cvat2 #12 加標 200-500 張 → 重訓並重評。這個 attr 是 ensemble 也救不了的真實弱點
- 中 ROI aluminized_apron 真實標注累積(放棄合成路線後的剩下選項),cvat2 #12 補 200+ 張 yes 樣本後重評
- 中 ROI CvN-Large 長 schedule 重訓(patience 16 + cosine LR),預期可再 +0.01-0.02 R@P95
- 低 ROI 跑剩下的 VLM(Qwen3-VL-8B / InternVL-2.5-8B),主要驗證 conservative trigger 對 hard_hat/rubber_gloves/harness 有沒有真實 FP 降幅
- 中 ROI 改 PPE21Handler 支援 ensemble(多 ckpt logit-avg),給 Option C/D 開門
📁 產出 artefacts
| 類別 | 檔案 | 內容 |
| 主報告 | ~/runs_new/ppe_sota_v515/SOTA_REPORT.md | 原始 18.2KB Markdown 報告 |
| 新 ckpt × 4 | ckpts/<tag>/best.pt | convnext_base / convnext_large / vit_base_dinov3 / vit_large_siglip |
| per-model metrics | results/metrics_<tag>.json | 每個 model 的 per-attr P/R/F1 + R@P95 |
| preds npz | results/preds_<tag>.npz | 每個 model 在 test set 上的 raw probs |
| Ensemble metadata | results/phase5_ensemble.json | per-attr greedy add 選出的 stack 組合 |
| test manifest | results/test_manifest.json | 12,856 rows 的 source / attr labels |
| VLM raw output | results/vlm_raw_qwen25vl3b.json | 1499 sample × 22 attr 的 yes/no/unclear |
研究在 5090-2 tmux session apron_research 內 autonomous 跑 ~6 hr 完成(預算 8hr)。完整原始 markdown 報告在 ~/runs_new/ppe_sota_v515/SOTA_REPORT.md。