訓練日期 2026-05-22 · 5090-2 單卡 batch 128 · MobileNetV3-L + camaug + partial-label BCE + mixup
v521 修了 export_p12 pagination bug:v519 export 用 page_size=100 沒做 pagination loop,**只 fetch cvat #12 前 100 個 task**(cvat #12 現有 704 task)導致 v519 訓練 dataset 嚴重不完整。v521 加 pagination 後 fetch 全 704 task / 27,844 manifest rows,best_val_mAP 0.9741 vs v519 0.9503(+2.4pp)。
| 指標 | v519 | v521 | Δ |
|---|---|---|---|
| best_val_mAP | 0.9503 | 0.9741 | +2.4pp |
| test mAP | 0.9505 | 0.9575 | +0.7pp |
| test macro_f1 | 0.9214 | 0.9336 | +1.2pp |
| cvat #12 task fetched | 100(截斷 bug) | 704(完整) | 7× |
| train_time | — | 1863s (~31 min) | |
| epochs_run | — | 19 (early stop) |
Bug:export_p12_v519.py line 96:
tasks = s.get(f"{CVAT2}/api/tasks",
params={"project_id": 12, "page_size": 100, "ordering": "id"}).json()["results"]
# 只 fetch 第一頁 100 task,沒做 while next pagination loop
結果 v519 訓練實際只用 96 unique task(cvat #12 當時剛好 task < 100),manifest 123k rows 看似充足但 task 多樣性大幅缺失。隨 cvat #12 task 累積到 704(許多後加 task ID > 4000 高於 page 1),v519 重跑 export 變得越來越不完整。
v521 修復:加 while page+=1 paginated loop fetch 全部 task:
tasks, page = [], 1
while True:
r = s.get(f"{CVAT2}/api/tasks",
params={"project_id": 12, "page_size": 500, "page": page, "ordering": "id"}).json()
tasks += r.get("results", [])
if not r.get("next"): break
page += 1
同樣 bug pattern 已寫進 SOP(一般 cvat API 都該 paginate)。
| Attribute | v519 AP | v521 AP | Δ | v521 F1 | v521 P / R |
|---|---|---|---|---|---|
| hard_hat | 0.9948 | 0.9931 | -0.002 | 0.968 | 0.965 / 0.970 |
| no_head_protection | 0.9744 | 0.9917 | +1.7pp | 0.964 | 0.962 / 0.966 |
| full_face_mask | 0.9934 | 0.9908 | -0.003 | 0.949 | 0.938 / 0.961 |
| face_mask | 0.9901 | 0.9895 | -0.001 | 0.951 | 0.940 / 0.963 |
| no_gloves | 0.9950 | 0.9991 | +0.4pp | 0.987 | 0.990 / 0.985 |
| cotton_gloves | 0.8604 | 0.8872 | +2.7pp | 0.833 | 0.784 / 0.889 |
| rubber_gloves | 0.9999 | 0.9996 | -0.000 | 0.996 | 0.993 / 1.000 |
| no_protective_clothing | 0.9970 | 0.9998 | +0.3pp | 0.997 | 0.998 / 0.996 |
| cleanroom_suit | 1.0000 | 0.9997 | 0 | 0.994 | 0.987 / 1.000 |
| splash_proof_gown | 1.0000 | 1.0000 | — | 1.000 | 1.000 / 1.000 |
| safety_vest | 0.9637 | 0.9609 | -0.003 | 0.928 | 0.911 / 0.945 |
| safety_shoes | 0.9599 | 0.8022 | -15.8pp | 0.777 | 0.651 / 0.963 |
| no_safety_shoes | 0.8653 | 0.9997 | +13.4pp | 0.994 | 0.998 / 0.990 |
| no_sleeves | 0.9505 | 0.9998 | +4.9pp | 0.993 | 0.991 / 0.994 |
| heartbeat | 0.8819 | 0.9014 | +2.0pp | 0.858 | 0.839 / 0.878 |
| sleeves | 0.7121 | 0.8041 | +9.2pp | 0.739 | 0.872 / 0.641 |
| safety_glasses | 0.9659 | 0.9628 | -0.003 | 0.901 | 0.928 / 0.876 |
| hair_cover | 0.9212 | 0.8872 | -3.4pp | 0.928 | 0.875 / 0.987 |
| helmet_goggles | 0.9862 | 0.9972 | +1.1pp | 0.978 | 0.990 / 0.965 |
| harness | 0.9254 | 0.9236 | -0.002 | 0.855 | 0.874 / 0.838 |
| fall | 0.9739 | 0.9755 | +0.002 | 0.950 | 0.936 / 0.964 |
| aluminized_apron | 1.0000 | 1.0000 | — | 1.000 | 1.000 / 1.000 |
| Split | v519 | v521 | Δ |
|---|---|---|---|
| total rows | 123,907 | ~28,000 (修 bug 後) | 不同採樣 + 9 個新 RAI/JUJIA/IRODA task |
| cvat #12 tasks fetched | 100 | 704 | 7× (修 pagination) |
注:v521 manifest 行數較少是因 v521 重新從修好的 cvat #12 fetch(task 完整但部分 task subset 為空被 export 跳過);v519 看似 123k rows 是用舊 task 一直 frame×person 累加,但 task 多樣性不足。
factory_ppe_v20260521/best.pt ⬇ · 17 MB
backbone: mobilenetv3_large_100.ra_in1k (4.23M params)
img_size: 384×192
batch: 128, epochs: 40, patience: 8, lr: 3e-4, wd: 0.01
aug: camaug, mixup: 0.2
attr_neg_weight: {harness: 2.0, hard_hat: 1.3, safety_vest: 1.3, 其餘: 1.0}
22 attrs(21 原 + aluminized_apron)
partial-label BCE,unknown → mask=0 不算 loss
# Export 修了 pagination bug,現在 fetch cvat #12 全 704 task
manifest: /home/ubuntu/factory_ppe/crops_v521/manifest_v521.csv