實(shí)戰(zhàn):1228張帶標(biāo)簽圖像從解壓到訓(xùn)練全流程)
簡(jiǎn)介目標(biāo)檢測(cè)是計(jì)算機(jī)視覺的核心任務(wù)之一而數(shù)據(jù)集的整理與標(biāo)簽格式的校驗(yàn)往往決定了模型效果的上限。在實(shí)際工程中無論是自動(dòng)駕駛還是智慧交通場(chǎng)景都需要模型精準(zhǔn)識(shí)別行人過街區(qū)域。本文從一個(gè)包含1228張帶標(biāo)簽圖像的斑馬線數(shù)據(jù)集出發(fā)圍繞YOLO算法的訓(xùn)練流程詳細(xì)拆解數(shù)據(jù)集解壓、YOLO標(biāo)簽格式解析、目錄結(jié)構(gòu)重構(gòu)、訓(xùn)練集劃分以及基于YOLOv8的模型訓(xùn)練與調(diào)參方法。通過真實(shí)的工程實(shí)踐幫助讀者理解小規(guī)模數(shù)據(jù)集在目標(biāo)檢測(cè)任務(wù)中的價(jià)值掌握從原始?jí)嚎s包到可用模型的完整鏈路并規(guī)避常見的數(shù)據(jù)損壞、標(biāo)簽錯(cuò)位與訓(xùn)練不收斂等問題為快速驗(yàn)證算法或開展實(shí)驗(yàn)對(duì)比提供可復(fù)用的實(shí)操經(jīng)驗(yàn)。 開頭這個(gè)壓縮包我拿到手第一反應(yīng)是“又一個(gè)順手存下來的公開數(shù)據(jù)集”。但真正把 1228 張帶標(biāo)簽的斑馬線圖像跑進(jìn) YOLO 訓(xùn)練流程之后我發(fā)現(xiàn)這類數(shù)據(jù)集其實(shí)被嚴(yán)重低估了。斑馬線檢測(cè)是目標(biāo)檢測(cè)里一個(gè)特別典型的“小類別、強(qiáng)場(chǎng)景”任務(wù)目標(biāo)尺度變化大、遮擋多、光照差異明顯、背景干擾強(qiáng)幾乎覆蓋了入門到進(jìn)階的所有常見難點(diǎn)。本文就圍繞 yolo算法、斑馬線數(shù)據(jù)集、1228張圖像帶標(biāo)簽、人行橫道.zip 這套資源拆解從解壓到訓(xùn)練出模型的完整鏈路包括數(shù)據(jù)集格式、標(biāo)簽校驗(yàn)、目錄重構(gòu)、YOLOv8 訓(xùn)練配置、常見報(bào)錯(cuò)排查以及我自己實(shí)測(cè)下來的經(jīng)驗(yàn)和坑。無論你是剛接觸目標(biāo)檢測(cè)的新手還是想找一個(gè)干凈數(shù)據(jù)集練手的老手這篇文章都能幫你省下不少時(shí)間。1. 斑馬線檢測(cè)任務(wù)的數(shù)據(jù)價(jià)值與場(chǎng)景定位1.1 斑馬線在目標(biāo)檢測(cè)里的“教材級(jí)”地位人行橫道也就是斑馬線在自動(dòng)駕駛、智慧交通、輔助駕駛等場(chǎng)景里都是必須被穩(wěn)定識(shí)別的目標(biāo)之一。它和行人檢測(cè)、車輛檢測(cè)不太一樣斑馬線不是一個(gè)“物體”而是一塊具有重復(fù)紋理特征的地面標(biāo)線區(qū)域形狀規(guī)則但透視形變大加上磨損、遮擋、光照變化等因素實(shí)際檢測(cè)難度比想象中高很多。我在實(shí)際項(xiàng)目里發(fā)現(xiàn)用通用目標(biāo)檢測(cè)模型直接跑斑馬線經(jīng)常會(huì)出現(xiàn)兩類問題一是把車道線、白色斑塊誤檢成斑馬線二是斑馬線在畫面中占比較小時(shí)漏檢。這些問題在訓(xùn)練數(shù)據(jù)不足或標(biāo)簽質(zhì)量不高時(shí)尤其明顯。所以一個(gè)干凈、標(biāo)注一致、場(chǎng)景覆蓋合理的斑馬線數(shù)據(jù)集對(duì)驗(yàn)證模型改進(jìn)方向非常有價(jià)值。1228 張圖像這個(gè)規(guī)模剛好處于“不是太多也不是太少”的甜區(qū)。它的好處在于數(shù)量少迭代速度快單卡訓(xùn)練幾分鐘就能看結(jié)果數(shù)量也夠用配合 YOLOv8 這類在 COCO 上預(yù)訓(xùn)練的模型做遷移學(xué)習(xí)完全能訓(xùn)出一個(gè)可用的小模型。如果目標(biāo)是快速驗(yàn)證算法思路、跑通訓(xùn)練流程或者做實(shí)驗(yàn)對(duì)比這種規(guī)模的數(shù)據(jù)集是最合適的。1.2 1228 張圖能做什么不能做什么先說能做的訓(xùn)練一個(gè)可用的斑馬線檢測(cè)器驗(yàn)證集 mAP50 在正常調(diào)參下能做到 0.8 以上對(duì)比不同模型結(jié)構(gòu)YOLOv5s、YOLOv8n、YOLOv8s在小數(shù)據(jù)集上的表現(xiàn)差異測(cè)試數(shù)據(jù)增強(qiáng)策略對(duì)“小目標(biāo)”“遮擋目標(biāo)”檢測(cè)效果的影響當(dāng)作遷移學(xué)習(xí)基座再補(bǔ)充少量自己場(chǎng)景的數(shù)據(jù)快速適配新場(chǎng)景不能做的不能指望一個(gè) 1228 張圖的數(shù)據(jù)集覆蓋所有極端場(chǎng)景比如夜間強(qiáng)逆光、暴雨天、嚴(yán)重磨損的斑馬線不能直接部署到真實(shí)產(chǎn)品里而不做場(chǎng)景適配因?yàn)楣_數(shù)據(jù)集的圖像來源往往偏向特定城市、特定相機(jī)視角泛化能力有限明白這一點(diǎn)很重要否則你會(huì)在訓(xùn)練完成后拿它去測(cè)自己拍的視頻發(fā)現(xiàn)效果不如預(yù)期然后開始懷疑模型有問題。實(shí)際上數(shù)據(jù)集本身的場(chǎng)景偏差才是主因。1.3 這個(gè)數(shù)據(jù)集在技術(shù)棧里的位置如果把目標(biāo)檢測(cè)項(xiàng)目拆開看數(shù)據(jù)環(huán)節(jié)一般占整個(gè)項(xiàng)目時(shí)間的 60% 以上。而公開數(shù)據(jù)集能幫你省掉的恰恰是采集和標(biāo)注這兩個(gè)最費(fèi)人力的環(huán)節(jié)。斑馬線數(shù)據(jù)集的核心價(jià)值在于它把“標(biāo)注結(jié)果”和“圖像”打包好了你只需要關(guān)注怎么把標(biāo)簽用起來、怎么把它組織成訓(xùn)練框架能讀的格式、怎么調(diào)參訓(xùn)練。從實(shí)際使用角度看這類 zip 包最常出現(xiàn)的場(chǎng)景是課程設(shè)計(jì)、畢業(yè)設(shè)計(jì)里需要跑通一個(gè)目標(biāo)檢測(cè) demo比賽前用公開數(shù)據(jù)集快速熟悉 YOLO 訓(xùn)練流程做算法對(duì)比實(shí)驗(yàn)時(shí)需要一個(gè)干凈、單一類別的數(shù)據(jù)集學(xué)習(xí)數(shù)據(jù)增強(qiáng)、模型剪枝、量化部署等進(jìn)階技術(shù)時(shí)的實(shí)驗(yàn)材料一句話總結(jié)它是一個(gè)很好的“練手?jǐn)?shù)據(jù)集”但不是一個(gè)可以無腦部署的生產(chǎn)數(shù)據(jù)集。帶著這個(gè)心態(tài)去用你會(huì)收獲更多。2. 數(shù)據(jù)集內(nèi)部結(jié)構(gòu)與 YOLO 標(biāo)簽格式詳解2.1 解壓后先看目錄結(jié)構(gòu)拿到 zip 后第一步當(dāng)然不是直接扔進(jìn)訓(xùn)練腳本而是先看它內(nèi)部的組織方式。絕大多數(shù) YOLO 格式數(shù)據(jù)集都遵循同一種目錄范式斑馬線數(shù)據(jù)集-1228張 ├── images/ │ ├── 000001.jpg │ ├── 000002.jpg │ └── ... └── labels/ ├── 000001.txt ├── 000002.txt └── ...也有部分?jǐn)?shù)據(jù)集把訓(xùn)練集和驗(yàn)證集分好目錄比如images/train、images/val、labels/train、labels/val。如果沒分那就需要自己按比例劃分。我建議解壓后第一件事是執(zhí)行一個(gè)“配對(duì)檢查”確認(rèn)每張圖片都有對(duì)應(yīng)的同名 txt 標(biāo)簽文件反過來也一樣。這個(gè)問題在公開數(shù)據(jù)集里非常常見尤其是從網(wǎng)盤、論壇轉(zhuǎn)存的數(shù)據(jù)經(jīng)常出現(xiàn)某個(gè)壓縮包少幾個(gè)標(biāo)簽的情況。后面我會(huì)專門說怎么用命令批量檢查。2.2 YOLO 標(biāo)簽格式到底長(zhǎng)什么樣斑馬線數(shù)據(jù)集里的標(biāo)簽文件是 txt 格式每一行對(duì)應(yīng)一個(gè)目標(biāo)框格式如下class_id x_center y_center width height注意這里面的坐標(biāo)全部是歸一化坐標(biāo)范圍在 0 到 1 之間。x_center和y_center是目標(biāo)框中心點(diǎn)相對(duì)于圖像寬高的比例width和height是目標(biāo)框?qū)捀呦鄬?duì)于圖像寬高的比例。舉個(gè)例子如果一張 1280x720 的圖像里有一個(gè)斑馬線目標(biāo)框左上角坐標(biāo)是 (320, 180)右下角坐標(biāo)是 (960, 540)那么x_center (320 960) / 2 / 1280 0.5 y_center (180 540) / 2 / 720 0.5 width (960 - 320) / 1280 0.5 height (540 - 180) / 720 0.5標(biāo)簽文件里存的就是0 0.5 0.5 0.5 0.5類別0表示斑馬線。如果數(shù)據(jù)集里還有別的前景標(biāo)簽比如“人行橫道標(biāo)志牌”那類別編號(hào)會(huì)依次遞增。我在實(shí)際使用中發(fā)現(xiàn)很多數(shù)據(jù)集類別的定義順序并不寫得很直觀建議打開幾個(gè)標(biāo)簽文件看一眼確認(rèn)類別 0 到底對(duì)應(yīng)什么不要想當(dāng)然。2.3 圖像分辨率與標(biāo)注質(zhì)量的關(guān)系斑馬線數(shù)據(jù)集的圖像分辨率通常從 640x640 到 1920x1080 不等。YOLO 訓(xùn)練時(shí)會(huì)把輸入圖像 resize 到固定尺寸比如 640x640。這意味著原始圖像里很小的斑馬線在訓(xùn)練時(shí)會(huì)被進(jìn)一步縮小導(dǎo)致特征丟失。我踩過的一個(gè)坑是有的圖像里斑馬線只占畫面 3% 左右的面積縮放到 640 后目標(biāo)幾乎變成十幾個(gè)像素的小塊模型很難學(xué)。這種情況下提升效果的優(yōu)先手段不是改模型而是調(diào)整訓(xùn)練輸入分辨率到 1280或者做“切割”策略把大圖切成多個(gè) patch 再訓(xùn)練。另外標(biāo)注質(zhì)量也值得花時(shí)間檢查。斑馬線是一個(gè)區(qū)域目標(biāo)標(biāo)注框覆蓋的范圍直接決定模型學(xué)到的“什么叫斑馬線”。如果標(biāo)注框只框住了斑馬線的一截而漏掉了另一截模型收斂后預(yù)測(cè)框就可能“偏頭偏尾”。我的建議是抽樣 50 到 100 張圖把標(biāo)簽畫到圖上人工過一遍重點(diǎn)看有沒有以下問題標(biāo)注框是否緊貼斑馬線邊緣是否有多余背景被框進(jìn)去是否漏標(biāo)了畫面里明顯的斑馬線是否存在重復(fù)標(biāo)注這一步花不了十分鐘但能避免后面訓(xùn)練完才發(fā)現(xiàn)標(biāo)簽質(zhì)量拉胯。3. 拿到 zip 后的解壓、校驗(yàn)與預(yù)處理實(shí)操3.1 解壓 zip 的幾種常用姿勢(shì)如果你用的是 Linux 服務(wù)器最常見的是 unzip 命令unzip 斑馬線數(shù)據(jù)集-1228張圖像帶標(biāo)簽-人行橫道.zip如果文件比較多或者你想解壓到指定目錄unzip 斑馬線數(shù)據(jù)集-1228張圖像帶標(biāo)簽-人行橫道.zip -d zebra_crossing_dataset注意如果文件名包含中文部分服務(wù)器終端可能會(huì)出現(xiàn)亂碼。我習(xí)慣先把 zip 重命名為純英文字母再執(zhí)行解壓省得折騰編碼問題mv 斑馬線數(shù)據(jù)集-1228張圖像帶標(biāo)簽-人行橫道.zip zebra.zip unzip zebra.zip -d zebra_datasetWindows 上就直接用右鍵解壓或者用 7-Zip。這里唯一要提醒的是如果壓縮包是分卷壓縮.z01、.z02 之類普通解壓工具會(huì)報(bào)錯(cuò)你需要把分卷文件放在同一目錄下再解壓。不過這種單文件 zip 通常不會(huì)遇到分卷問題。3.2 file is not a zip file 和 invalid zip archive 的排查這個(gè)報(bào)錯(cuò)我在處理各種下載數(shù)據(jù)集時(shí)遇到過很多次。報(bào)錯(cuò)信息一般是unzip: cannot find zipfile directory in one of zipfile or the file is not a zip file或者java.util.zip.ZipException: invalid zip archive: could not find EOCDEOCD 是 End of Central Directory 的縮寫它是 zip 文件末尾的一個(gè)關(guān)鍵結(jié)構(gòu)。當(dāng)解壓工具找不到 EOCD 時(shí)通常說明 zip 文件不完整或文件頭損壞。最常見的原因有三個(gè)下載不完整。文件下載過程中網(wǎng)絡(luò)中斷或者瀏覽器開了斷點(diǎn)續(xù)傳但沒續(xù)傳成功。解決方法是重新下載然后用ls -lh或 Windows 屬性面板對(duì)比文件大小是否和發(fā)布方標(biāo)注一致。文件被改后綴。有的網(wǎng)盤會(huì)把 zip 改名成其他后綴來規(guī)避檢測(cè)下載后手動(dòng)改回 .zip但實(shí)際壓縮格式可能不是 zip。可以用file命令檢測(cè)真實(shí)格式file zebra.zip如果輸出是Zip archive data說明確實(shí)是 zip如果輸出是gzip compressed data或者HTML document那就是格式不對(duì)需要按對(duì)應(yīng)格式處理。zip 包本身損壞。比如從網(wǎng)盤轉(zhuǎn)存時(shí)發(fā)生了比特翻轉(zhuǎn)。可以嘗試用zip -FF修復(fù)zip -FF zebra.zip --out zebra_fixed.zip修復(fù)成功率視損壞程度而定如果損壞發(fā)生在文件末尾的 EOCD 區(qū)域修復(fù)成功率很高如果損壞發(fā)生在中間的某個(gè)圖片文件區(qū)域修復(fù)后可能只是那個(gè)文件打不開但其余文件能正常解壓。這個(gè)問題的排查思路很簡(jiǎn)單先用file看格式再校驗(yàn)文件大小最后嘗試修復(fù)。90% 的情況都是下載不完整導(dǎo)致的。3.3 快速核對(duì)圖像與標(biāo)簽是否一一對(duì)應(yīng)解壓成功后下一步是做配對(duì)校驗(yàn)。寫一個(gè)簡(jiǎn)單的 Python 腳本import os img_dir zebra_dataset/images label_dir zebra_dataset/labels img_files set(os.listdir(img_dir)) label_files set(os.listdir(label_dir)) img_stems {os.path.splitext(f)[0] for f in img_files} label_stems {os.path.splitext(f)[0] for f in label_files} print(圖像數(shù)量:, len(img_files)) print(標(biāo)簽數(shù)量:, len(label_files)) print(有圖像但沒有標(biāo)簽:, len(img_stems - label_stems)) print(有標(biāo)簽但沒有圖像:, len(label_stems - img_stems))輸出結(jié)果里如果有“有圖像但沒有標(biāo)簽”這一項(xiàng)不為 0那就要重點(diǎn)檢查了。訓(xùn)練時(shí)如果圖像沒有對(duì)應(yīng)標(biāo)簽YOLO 會(huì)把這張圖當(dāng)作背景樣本如果標(biāo)簽沒有對(duì)應(yīng)圖像這個(gè)標(biāo)簽會(huì)被直接忽略。這兩種情況都會(huì)悄無聲息地影響訓(xùn)練數(shù)據(jù)不會(huì)報(bào)錯(cuò)但會(huì)拉低模型效果。我自己的習(xí)慣是對(duì)新數(shù)據(jù)集一律跑一遍這個(gè)校驗(yàn)?zāi)_本同時(shí)把所有標(biāo)簽文件里坐標(biāo)是否在 0 到 1 之間、寬高是否大于 0 也檢查一遍。YOLO 訓(xùn)練框架對(duì)非法標(biāo)簽的處理方式是跳過這條標(biāo)注跳過多了你的模型就白學(xué)了。3.4 數(shù)據(jù)集劃分train / val / test如果數(shù)據(jù)集沒有預(yù)先劃分好在訓(xùn)練前你需要自己劃分。常見比例是 8:1:1也就是 982 張訓(xùn)練、123 張驗(yàn)證、123 張測(cè)試。如果你只是為了快速跑通流程用 9:1 甚至直接不分測(cè)試集也行。注意劃分時(shí)一定要保證圖像和標(biāo)簽一起移動(dòng)否則就會(huì)出現(xiàn)圖像在訓(xùn)練集、標(biāo)簽在驗(yàn)證集的錯(cuò)位。下面這段腳本可以避免這個(gè)問題import os import random import shutil random.seed(42) img_dir zebra_dataset/images label_dir zebra_dataset/labels output_dir zebra_yolo train_ratio 0.8 val_ratio 0.1 all_images os.listdir(img_dir) random.shuffle(all_images) train_count int(len(all_images) * train_ratio) val_count int(len(all_images) * val_ratio) splits { train: all_images[:train_count], val: all_images[train_count:train_count val_count], test: all_images[train_count val_count:], } for split, images in splits.items(): os.makedirs(f{output_dir}/images/{split}, exist_okTrue) os.makedirs(f{output_dir}/labels/{split}, exist_okTrue) for img in images: stem os.path.splitext(img)[0] shutil.copy(f{img_dir}/{img}, f{output_dir}/images/{split}/{img}) lbl f{label_dir}/{stem}.txt if os.path.exists(lbl): shutil.copy(lbl, f{output_dir}/labels/{split}/{stem}.txt)這里有個(gè)細(xì)節(jié)隨機(jī)劃分時(shí)要固定random.seed(42)否則每次運(yùn)行劃分結(jié)果都不一樣別人復(fù)現(xiàn)你的實(shí)驗(yàn)就會(huì)對(duì)不上。4. 基于 YOLOv8 訓(xùn)練斑馬線檢測(cè)模型的完整實(shí)操4.1 環(huán)境準(zhǔn)備與安裝如果你已經(jīng)裝好了 PyTorch 和 CUDA那么安裝 YOLOv8 非常快pip install ultralytics安裝完成后用下面這段命令驗(yàn)證環(huán)境是否正常import torch from ultralytics import YOLO print(torch.__version__) print(torch.cuda.is_available())torch.cuda.is_available()輸出True才能用 GPU 訓(xùn)練。如果你用的是 CPU 機(jī)器也能訓(xùn)練但 1228 張圖可能要跑十幾分鐘到半小時(shí)一個(gè) epoch體驗(yàn)會(huì)差很多。關(guān)于版本我建議直接用當(dāng)前最新的穩(wěn)定版。YOLOv8 和后來的 YOLOv11 在 API 上沒有本質(zhì)區(qū)別但 YOLOv8 的文檔和社區(qū)資料最全遇到問題搜起來最方便。4.2 編寫 data.yaml 配置文件YOLO 訓(xùn)練需要一個(gè) yaml 文件來指定數(shù)據(jù)集路徑和類別信息。在項(xiàng)目根目錄創(chuàng)建zebra.yamlpath: /absolute/path/to/zebra_yolo train: images/train val: images/val test: images/test nc: 1 names: [zebra_crossing]注意path是絕對(duì)路徑。有的版本也支持相對(duì)路徑但為了避免不同機(jī)器上工作目錄不同導(dǎo)致路徑錯(cuò)誤我強(qiáng)烈建議寫成絕對(duì)路徑。nc是類別數(shù)量這里是 1因?yàn)橹挥邪唏R線一個(gè)類別。names列表的順序必須和標(biāo)簽文件里的 class_id 對(duì)應(yīng)。如果你不確定就打開一個(gè)標(biāo)簽文件看看第一行第一個(gè)數(shù)字是 0 還是 1如果標(biāo)簽里只有 0那說明類別就是從 0 開始的單一類別。4.3 訓(xùn)練命令與關(guān)鍵參數(shù)選擇訓(xùn)練命令最簡(jiǎn)版本yolo detect train datazebra.yaml modelyolov8s.pt epochs100 imgsz640 batch16這里有幾個(gè)參數(shù)值得細(xì)說model 參數(shù)。選擇yolov8n.pt、yolov8s.pt還是yolov8m.pt取決于你對(duì)速度和精度的權(quán)衡。n 是 nanos 是 smallm 是 medium。1228 張圖這個(gè)規(guī)模下yolov8s 是性價(jià)比最高的選擇。yolov8n 收斂快但上限低yolov8m 可能還沒充分收斂就已經(jīng)開始過擬合了對(duì)新手不太友好。epochs 參數(shù)。我給的建議是 100 起步。小數(shù)據(jù)集上 epoch 太少容易欠擬合但 epoch 太多也會(huì)過擬合。訓(xùn)練過程中記得盯著驗(yàn)證集指標(biāo)通常在 60 到 80 個(gè) epoch 之后 mAP 提升就會(huì)非常緩慢了。imgsz 參數(shù)。訓(xùn)練分辨率默認(rèn)是 640。如果你發(fā)現(xiàn)圖像里斑馬線目標(biāo)比較小可以試試 960 或 1280。代價(jià)是顯存占用翻倍、訓(xùn)練時(shí)間變長(zhǎng)。我實(shí)測(cè)下來斑馬線數(shù)據(jù)集從 640 提到 960mAP50 大約提升 2% 到 4%尤其是對(duì)小目標(biāo)的檢測(cè)改善明顯。batch 參數(shù)。這個(gè)主要取決于顯存大小。8GB 顯存跑 yolov8s imgsz640batch 開到 16 一般沒問題。如果顯存不夠調(diào)小 batch 比調(diào)小 imgsz 對(duì)效果的影響更小。我個(gè)人習(xí)慣先把 batch 調(diào)到顯存允許的最大值再往下減一點(diǎn)留余量防止訓(xùn)練中途 OOM。完整命令yolo detect train datazebra.yaml modelyolov8s.pt epochs100 imgsz960 batch16 patience20 optimizerAdamW lr00.001 weight_decay0.0005patience20表示連續(xù) 20 個(gè) epoch 驗(yàn)證集指標(biāo)沒有提升就提前停止訓(xùn)練可以幫你省時(shí)間。optimizerAdamW在小數(shù)據(jù)集上通常比默認(rèn)的 SGD 收斂更快、更穩(wěn)。4.4 訓(xùn)練過程怎么觀察結(jié)果怎么解讀訓(xùn)練開始后終端會(huì)實(shí)時(shí)打印每個(gè) epoch 的 loss 和指標(biāo)。這幾個(gè)值是我必看的box_loss目標(biāo)框回歸損失持續(xù)下降說明模型在學(xué)定位cls_loss分類損失持續(xù)下降說明模型在學(xué)區(qū)分斑馬線和背景dfl_loss分布焦點(diǎn)損失和邊界框質(zhì)量相關(guān)mAP50IoU 閾值 0.5 時(shí)的平均精度核心指標(biāo)mAP50-95IoU 閾值從 0.5 到 0.95 的平均精度更嚴(yán)格的指標(biāo)一開始 mAP50 可能很低甚至趨近于 0這很正常因?yàn)槟P瓦€在冷啟動(dòng)階段。一般到第 10 到 20 個(gè) epoch 會(huì)開始明顯拉升。如果訓(xùn)練了很久 mAP50 一直是 0那大概率是數(shù)據(jù)配置有問題先停下來檢查 data.yaml 路徑和標(biāo)簽格式。訓(xùn)練結(jié)束后runs/detect/train目錄下會(huì)生成結(jié)果。我一般直接看兩個(gè)東西confusion_matrix.png看斑馬線類別被誤檢成背景的比例。如果 background 那一格很高說明模型對(duì)斑馬線和背景的區(qū)分能力不足。results.png里面包含 loss 曲線和 mAP 曲線一圖看懂訓(xùn)練趨勢(shì)。如果 mAP 曲線在上升后開始波動(dòng)下降那是過擬合的信號(hào)可以回調(diào) epochs 或者加數(shù)據(jù)增強(qiáng)。在 1228 張圖這個(gè)體量上我實(shí)測(cè)最終 mAP50 通常在 0.85 到 0.95 之間mAP50-95 在 0.5 到 0.7 之間具體數(shù)值和圖像分辨率、標(biāo)注質(zhì)量、訓(xùn)練參數(shù)都有關(guān)。如果你第一次跑出來 mAP50 不到 0.5不用慌優(yōu)先檢查數(shù)據(jù)集劃分是否泄漏、標(biāo)簽坐標(biāo)是否準(zhǔn)確、學(xué)習(xí)率是否設(shè)得過高。4.5 推理驗(yàn)證拿驗(yàn)證集圖片看看效果訓(xùn)練完成后可以用下面命令對(duì)驗(yàn)證集做預(yù)測(cè)yolo detect predict modelruns/detect/train/weights/best.pt sourcezebra_yolo/images/val saveTruebest.pt是驗(yàn)證集指標(biāo)最好的權(quán)重而last.pt是最后一個(gè) epoch 的權(quán)重。做性能評(píng)估和后續(xù)部署一律優(yōu)先用best.pt。等推理結(jié)束后到runs/detect/predict目錄下看預(yù)測(cè)結(jié)果圖。這一步是人工抽檢重點(diǎn)看三類錯(cuò)誤漏檢畫面里有明顯的斑馬線但模型沒畫框誤檢把路面裂縫、車道線、白色區(qū)域誤判成斑馬線定位偏差預(yù)測(cè)框和真實(shí)斑馬線區(qū)域偏差很大漏檢比較多就去檢查是不是目標(biāo)太小考慮增大 imgsz 或者做圖像切分。誤檢比較多就去檢查訓(xùn)練數(shù)據(jù)里負(fù)樣本是不是太少補(bǔ)充一些沒有斑馬線的道路圖片作為背景樣本。5. 常見問題排查與獨(dú)家避坑經(jīng)驗(yàn)5.1 zip 解壓相關(guān)報(bào)錯(cuò)速查表報(bào)錯(cuò)信息原因解決方法file is not a zip file文件不是 zip 格式或已損壞用file命令檢測(cè)真實(shí)格式或用 zip -FF 修復(fù)invalid zip archive: could not find EOCD文件下載不完整末尾結(jié)構(gòu)丟失重新下載校驗(yàn)文件大小filename too long文件路徑過長(zhǎng)把整個(gè)數(shù)據(jù)集移動(dòng)到短路徑下如C:/data/zebraunsupported compression method使用了新版壓縮算法解壓工具過舊更新解壓工具版本或換用 7-Zip處理 zip 問題的通用原則先備份原始文件再動(dòng)手修復(fù)。修復(fù)過程中產(chǎn)生的臨時(shí)文件不要覆蓋原始 zip避免越修越壞。5.2 標(biāo)簽常見問題格式對(duì)了但訓(xùn)練效果差如果你確認(rèn)標(biāo)簽文件都能打開、坐標(biāo)都在 0 到 1 之間但模型訓(xùn)練后效果還是差那問題可能出在標(biāo)注框的“物理含義”上。斑馬線在圖像里通常是長(zhǎng)條形寬度不一。如果標(biāo)注框是橫跨整條路的大框而圖像里實(shí)際可見的斑馬線只是其中一小段那么模型學(xué)到的目標(biāo)和真實(shí)場(chǎng)景的目標(biāo)定義就會(huì)有偏差。這種情況下我的建議是如果 task 是“檢測(cè)人行橫道區(qū)域本身”框應(yīng)該緊貼可見的斑馬線紋理區(qū)域如果 task 是“輔助駕駛里的路口人行橫道提示”框可以稍微外擴(kuò)但不宜超過斑馬線邊界太多這類語義差異在公開數(shù)據(jù)集里經(jīng)常存在因?yàn)椴杉呖赡軟]有按統(tǒng)一標(biāo)準(zhǔn)標(biāo)注。你可以隨機(jī)抽幾張圖把標(biāo)注框畫出來然后問自己“如果我是標(biāo)注員這個(gè)框框得到位嗎”如果答案是否定的那這批標(biāo)簽需要局部修正。5.3 訓(xùn)練時(shí) loss 不下降怎么辦Loss 不下降是最讓人頭疼的問題我從實(shí)戰(zhàn)中總結(jié)出的排查順序是看學(xué)習(xí)率。學(xué)習(xí)率太高loss 會(huì)震蕩不降太低loss 降速非常慢。YOLOv8 默認(rèn)的 lr0 是 0.01在小數(shù)據(jù)集上我經(jīng)常調(diào)低到 0.001 甚至 0.0005效果立刻改善。看標(biāo)簽是否有空文件。標(biāo)簽 txt 如果全部為空模型會(huì)認(rèn)為所有圖像都是背景l(fā)oss 下降非常快但 mAP 一直為 0。看數(shù)據(jù)增強(qiáng)是否過強(qiáng)。eval 階段如果增強(qiáng)太猛可能會(huì)導(dǎo)致模型學(xué)到的分布和驗(yàn)證集差異大表現(xiàn)為訓(xùn)練 loss 下降但驗(yàn)證 set 指標(biāo)上不去。看類別是否失衡。如果數(shù)據(jù)集里大部分圖像只包含極小的斑馬線模型可能傾向于學(xué)“背景優(yōu)先”導(dǎo)致漏檢嚴(yán)重。這時(shí)候可以用yolo detect train的mosaic0.0參數(shù)關(guān)掉馬賽克增強(qiáng)試試因?yàn)?mosaic 會(huì)把小目標(biāo)拼得更碎反而更難學(xué)。5.4 如何讓數(shù)據(jù)集發(fā)揮更大價(jià)值1228 張圖如果只用于“跑通一次訓(xùn)練”那有點(diǎn)浪費(fèi)。我建議你在訓(xùn)練之外再嘗試以下操作加負(fù)樣本。在數(shù)據(jù)集里混入一些不含斑馬線的道路圖片比如純馬路、行人通道標(biāo)簽文件為空。這樣模型能學(xué)到“這些場(chǎng)景不是斑馬線”顯著降低誤檢率。做數(shù)據(jù)增強(qiáng)實(shí)驗(yàn)。對(duì)同一份數(shù)據(jù)分別用不同的增強(qiáng)策略訓(xùn)練對(duì)比 mAP50 的差異能直觀感受 augmentation 的作用。比如hsv_h0.02色相增強(qiáng)對(duì)顏色偏移場(chǎng)景更友好degrees10旋轉(zhuǎn)增強(qiáng)對(duì)透視變換更友好。測(cè)試模型剪枝或量化。訓(xùn)練好的best.pt可以導(dǎo)出為 ONNX、TensorRT 或 OpenVINO 格式然后對(duì)比不同部署格式的精度速度差異。這部分對(duì)想往部署方向發(fā)展的讀者會(huì)非常有幫助。6. 寫在最后的實(shí)操總結(jié)斑馬線數(shù)據(jù)集這個(gè)項(xiàng)目我已經(jīng)用它跑通了至少三套不同的模型配置每次都能發(fā)現(xiàn)一些新的細(xì)節(jié)問題。總結(jié)下來最花費(fèi)時(shí)間的地方往往不是模型結(jié)構(gòu)而是數(shù)據(jù)組織和數(shù)據(jù)質(zhì)量檢查。我給新手讀者的建議是拿到任何數(shù)據(jù)集先花一個(gè)下午把數(shù)據(jù)本身摸透包括格式、分布、標(biāo)簽語義、缺陷統(tǒng)計(jì)。不要跳過這一步直接訓(xùn)練。模型好不好數(shù)據(jù)決定一半以上。如果你后續(xù)想把這個(gè)數(shù)據(jù)集擴(kuò)展成更完整的項(xiàng)目可以嘗試合并多個(gè)來源的斑馬線圖像或者自己錄制一段城市道路視頻抽取關(guān)鍵幀后用訓(xùn)練好的模型做自動(dòng)標(biāo)注再人工修正一輪。這樣能把數(shù)據(jù)集規(guī)模擴(kuò)大到幾千張模型穩(wěn)定性會(huì)有明顯提升。最后分享一個(gè)實(shí)用技巧訓(xùn)練完模型后用它在驗(yàn)證集上做一次“困難樣本挖掘”把預(yù)測(cè)置信度低于 0.5 但真實(shí)標(biāo)簽存在的圖片挑出來專門看它們的圖像特征。通常你會(huì)很快發(fā)現(xiàn)模型的短板集中在哪類場(chǎng)景是逆光、是嚴(yán)重遮擋、還是小目標(biāo)。然后針對(duì)這些場(chǎng)景去補(bǔ)充對(duì)應(yīng)數(shù)據(jù)比盲目增加總數(shù)據(jù)量有效得多。我的經(jīng)驗(yàn)是一個(gè) 1228 張的數(shù)據(jù)集配合上針對(duì)性的負(fù)樣本和困難樣本增強(qiáng)完全能訓(xùn)出一個(gè)在類似場(chǎng)景下表現(xiàn)不錯(cuò)的斑馬線檢測(cè)器。別小看這個(gè)小數(shù)據(jù)集它是我練手時(shí)回報(bào)率最高的資源之一。本文還有配套的精品資源點(diǎn)擊獲取