
簡介面向智能小車賽道自動駕駛場景提供了一套已標注的交通指示牌目標檢測數據集按YOLOv5目錄格式整理完畢可直接用于模型訓練和驗證免去自行采集與標注圖像的繁瑣過程。整套壓縮包共2000個文件以txt標簽文件1127個與jpg圖像872個為主附帶1個可視化Python腳本資源包大小約10.31MB解壓后目錄結構即符合YOLOv5訓練要求。數據劃分為訓練集和測試集訓練集含901張圖片及對應標簽txt測試集含225張圖片及對應標簽txt覆蓋左轉、右轉、紅燈、綠燈、人行道等8類常見賽道指示牌。圖像分辨率為200*120的RGB圖片契合智能車競賽、機器人實訓及自動駕駛入門實驗場景便于快速進行數據準備與算法驗證。另附可直接運行的腳本隨機傳入圖片即可繪制邊界框以檢查標注效果已有151人瀏覽學習。1. 自動駕駛小車缺的就是這種數據集200×120、8類指示牌、YOLOV5開箱即用做智能小車的人都有個共同痛點網上能找到的目標檢測數據集大多是 COCO、VOC 那種大場景通用圖分辨率高、類別雜拿來訓練自己的小車模型要么學到的特征跟賽道實際光線完全不搭要么預處理要把大圖縮到 tiny損失一堆細節(jié)。這份數據集恰恰相反它來自智能小車賽道的真實場景圖像分辨率固定在 200×120包含 8 類交通指示牌——左轉、右轉、紅燈、綠燈、人行道等。數據按 YOLOV5 的目錄格式整理訓練集 901 張圖配 901 個標簽 txt驗證集 225 張配 225 個標簽總共 11 MB下載下來不用轉換格式直接就能進訓練流程。適合正在做自動駕駛小車項目、參加競賽、或者想用一份「小圖小類別」數據集把 YOLOV5 從配置到部署完整跑通的人。2. 拆解YOLOV5目錄格式數據組織、標簽規(guī)范與配套腳本2.1 訓練集與驗證集901 張與 225 張的目錄結構拿到資源先別急著訓練先把目錄結構看懂。YOLOV5 官方對數據集的目錄約定是 images 和 labels 兩個分支并行images 里放圖片labels 里放同名 txt兩張目錄下的文件名一一對應。這份資源的組織方式也是這個套路常見的落盤結構是這樣的datasets/ ├── images/ │ ├── train/ │ │ ├── 0.jpg │ │ ├── 1.jpg │ │ └── ... │ └── val/ │ ├── 64.jpg │ ├── 75.jpg │ └── ... └── labels/ ├── train/ │ ├── 0.txt │ ├── 1.txt │ └── ... └── val/ ├── 64.txt ├── 75.txt └── ...訓練集和驗證集的分配比例接近 8:2901 張訓練、225 張驗證這個配比符合 YOLO 系數據集的常規(guī)習慣。需要注意一點原資源描述里寫的是「測試集」但在 YOLOV5 的語境下驗證集和測試集在訓練流程中的作用不同——驗證集用來每輪評估 mAP 和 loss測試集是最終部署前才去碰的。這份資源里那個 val 目錄實際承擔的就是驗證集功能訓練時 data.yaml 里直接指給它就行不用再手動拆分。還有個小細節(jié)值得注意圖片和標簽的同名對應關系是按文件名去后綴匹配的所以不能出現兩張不同格式的圖片共用同一個文件名比如0.jpg和0.png同時存在標簽0.txt到底歸誰就成了說不清的懸案。我拿到任何數據集都會先跑一遍文件名查重這個習慣幫我擋掉了不止一次訓練集樣本數對不上的問題。2.2 標簽 txt 的格式類別 ID 與歸一化坐標的約定每個 txt 文件里每一行代表一個檢測目標行內容分五列類別 ID、歸一化中心 x、歸一化中心 y、歸一化寬度 w、歸一化高度 h。歸一化的意思是坐標值除以圖片的寬或高所以數值范圍在 0 到 1 之間和圖片分辨率無關。這個設計讓同一份標注可以適配不同輸入尺寸——你訓練時把圖縮到 320 還是 224標注都不需要重新算。寫個小腳本就能把一行的含義拆出來。with open(datasets/labels/train/0.txt, r) as f: for line in f: parts line.strip().split() class_id int(parts[0]) # 類別ID從0開始計數 x, y, w, h map(float, parts[1:]) # 歸一化中心坐標和寬高 # 換算回 200x120 原圖像素坐標 x_px, y_px x * 200, y * 120 w_px, h_px w * 200, h * 120 print(fclass{class_id}, 中心({x_px:.0f},{y_px:.0f}), 寬{w_px:.0f}, 高{h_px:.0f})這段腳本做的事就是把 txt 里的歸一化坐標還原成 200×120 圖像上的像素坐標方便直接觀察標注目標在原圖上的實際大小和位置。很多新手拿到數據集不檢查標注直接丟給 train.py等訓練出來才發(fā)現某個類別一個框都沒學到回頭排查時用這個腳本掃一遍所有 txt能快速發(fā)現三類典型錯誤坐標越界x 或 y 大于 1或寬高加上中心點后超出圖像范圍、寬高為負值、以及類別 ID 超出 names 列表長度。這三類錯誤在 YOLOV5 里有些會被跳過有些會直接炸訓練進程越早發(fā)現越省事。2.3 類別字典文件8 個類別的順序為什么不能亂資源里附帶一個類別字典 txt這個文件很多人會忽略但它是整份數據的「翻譯表」。YOLO 標簽里的 class_id 是一個整數意思是「第幾個類別」而具體是左轉還是右轉、紅燈還是綠燈要靠字典文件把順序對齊。我的習慣是拿到資源第一件事就是打開這個 txt確認前幾個類別是否符合預期比如 0 對應左轉、1 對應右轉、2 對應紅燈、3 對應綠燈、4 對應人行道剩下三個類別以資源里實際寫的為準。這個順序在訓練和推理時必須全局一致訓練用的 data.yaml 里 names 列表順序、類別字典文件的順序、推理結果里類別 ID 的含義三者要一一對應。最常見的翻車方式是在訓練的時候把 names 寫成另一種順序推理時又按原來的順序輸出結果模型檢測框位置完全正確但標簽全部錯位——紅燈識別成綠燈這在自動駕駛場景里是致命事故。YOLO 的類別 ID 沒有任何額外元數據兜底全靠這個順序對齊所以先讀字典文件再寫配置是最穩(wěn)的一步。2.4 可視化腳本先看懂它再決定要不要改項目里附帶了一個可視化 py 文件作用是隨機取一張圖片讀取同名 txt把邊界框畫在圖上并保存到當前目錄腳本默認配置下可以直接運行。這種腳本在目標檢測數據集里屬于「驗貨工具」圖片和標簽都是文本加像素只有畫出來才能確認標注框是否貼合指示牌、類別 ID 是否正確。我通常建議拿到手先跑一遍如果圖上框的位置和物體輪廓明顯不匹配說明標注質量有問題這種資源需要慎重使用如果框都貼合再進訓練流程不遲。腳本的核心邏輯不復雜無非是 cv2 讀圖、解析 txt、循環(huán)畫矩形框、cv2.imwrite 保存隨機部分用 random 模塊從文件列表里取一個文件名。如果后續(xù)需要一次導出多張檢查圖可以把隨機取數改成循環(huán)遍歷再給輸出文件加上序號。這個改動很輕量但能大幅提高檢查效率——畢竟一張張隨機抽抽十次才能覆蓋完所有類別循環(huán)遍歷一次就能把所有帶框圖畫出來。3. 上手實操可視化驗貨腳本與三項訓練前數據體檢3.1 目錄擺放與第一個驗證命令拿到資源后先把整個 datasets 目錄放到一個干凈的工程路徑下。我一般會建一個 yolo_study 工程文件夾里面放 datasets、從官方倉庫 clone 下來的 yolov5 目錄、以及后面要寫的自定義 yaml 配置文件。擺放結構清晰有個好處訓練時給 data.yaml 的 path 字段寫相對路徑不容易出現因為絕對路徑寫錯導致找不到圖片的問題。目錄放好之后先進入可視化驗貨環(huán)節(jié)。python visualize_demo.py這是資源自帶可視化腳本默認的運行方式。腳本內部會從圖片目錄隨機選取一張 jpg自動去 labels 目錄尋找同名 txt解析出所有邊界框用 OpenCV 的 rectangle 函數把框畫上去并保存為一個新的圖片文件到當前目錄。運行完你會得到一張帶框的圖如果畫出來的框和指示牌邊緣基本吻合說明這份數據的標注是可用的。如果腳本支持傳參指定圖片也可以像下面這樣定向查看某一個具體樣例。python visualize_demo.py 790.jpg3.2 數據體檢一圖片與標簽文件配對檢查在正式訓練之前我強烈建議做一次「配對檢查」遍歷 images 和 labels 兩個目錄找出那些有圖片但沒有標簽、以及有標簽但沒有圖片的文件。YOLOV5 在訓練時對缺失標簽的處理并不總是報錯有時候會默默跳過某些樣本導致實際訓練圖數比預期少而很多人直到訓練完看曲線才察覺問題回頭查數據已經浪費了好幾個小時。import os img_dir datasets/images/train lab_dir datasets/labels/train imgs {f.split(.)[0] for f in os.listdir(img_dir) if f.endswith(.jpg)} labs {f.split(.)[0] for f in os.listdir(lab_dir) if f.endswith(.txt)} print(缺標簽的圖片:, imgs - labs) print(缺圖片的標簽:, labs - imgs)這個腳本把兩個目錄的文件名去掉后綴后取集合差兩邊各自獨有的名字就是問題文件。正常情況應該輸出兩個空集合因為這份資源在交付時就已經做過配對但下載傳輸過程中可能丟文件、解壓可能出錯花十秒鐘跑一遍能避免后面所有莫名其妙的訓練中斷問題。如果你的數據集是別人二次打包過的這個檢查就更不能省。3.3 數據體檢二空標簽與面積過小目標篩查空標簽比缺標簽更隱蔽文件存在但 txt 里一行都沒有代表這張圖沒有任何目標。訓練集里混入少量空標簽不致命YOLOV5 有背景樣本的概念但比例過高會讓模型訓練變成「在空圖上找鬼」浪費樣本也拖慢收斂。面積過小的目標則是老問題圖片本身只有 200×120如果某個指示牌標注框只有幾個像素寬模型幾乎不可能學會它。import os lab_dir datasets/labels/train for name in os.listdir(lab_dir): path os.path.join(lab_dir, name) with open(path, r) as f: lines f.readlines() if len(lines) 0: print(空標簽:, name) continue for line in lines: _, _, _, w, h map(float, line.strip().split()) if w * 200 8 or h * 120 8: # 還原為像素后小于8px print(小目標:, name, f{w*200:.0f}x{h*120:.0f}px)這里的 8 像素閾值是我自己定的經驗值你可以根據賽道相機的實際成像調整到 5 或 10。小目標識別本來就是 YOLO 系列的相對弱項如果這類樣本集中在某一個類別里訓練時就要額外關注那個類的 recall 曲線甚至考慮擴充該類別的小圖樣本來平衡。跑完這段腳本你對這份數據里「哪些類好學、哪些類難搞」就有了一個初步判斷這個判斷會直接影響后面超參數怎么調。3.4 數據體檢三類別分布統(tǒng)計類別分布不均會直接導致模型偏向樣本多的類這是目標檢測里最常見的玄學之一——不是模型結構有問題是數據本身就不均衡。通過統(tǒng)計所有 txt 中每個 class_id 出現的次數可以很快判斷需不需要做類別重加權或者需不需要對某些類別做針對性擴充。from collections import Counter import os lab_dir datasets/labels/train counter Counter() for name in os.listdir(lab_dir): with open(os.path.join(lab_dir, name), r) as f: for line in f: counter[int(line.strip().split()[0])] 1 for cid in sorted(counter): print(f類別{cid}: {counter[cid]}個目標)如果發(fā)現某個類別的目標數只有其他類的三分之一訓練時可以把這個類別的 loss 權重調高YOLOV5 自帶的自適應訓練模式也會做部分平衡但自己心里有數更重要。這一步做完這份數據集的「健康狀況」基本摸清可以放心進入訓練流程了。三份體檢腳本跑完不到一分鐘比起訓練跑一半才發(fā)現數據有問題這個時間成本幾乎可以忽略。4. 訓練自己的8類檢測器data.yaml編寫、超參數選擇與產物解讀4.1 寫 data.yaml路徑、類別數、names 順序對齊YOLOV5 的訓練入口 train.py 需要一個數據配置文件一般命名為一個自定義的 yaml 文件比如 track_signs.yaml。里面包含三類信息數據集路徑、類別數量 nc、類別名稱列表 names。這里最需要注意的是路徑寫法YOLOV5 較新版本支持 path 加相對路徑的方式train 和 val 可以寫成 images/train、images/val 這種相對路徑路徑的基準是 datasets 所在的目錄位置。path: ../datasets train: images/train val: images/val nc: 8 names: 0: left_turn 1: right_turn 2: red_light 3: green_light 4: crosswalk 5: class_5 6: class_6 7: class_7names 列表的 0 到 7 必須和類別字典文件完全一致后面的 class_5、class_6、class_7 只是占位名實際類名要打開資源自帶的字典 txt 核對后填進去。很多訓練報錯源頭就在這里字典文件里明明 8 個類yaml 里 nc 卻寫了 9或者 names 列表長度和 nc 對不上train.py 啟動時直接拋標簽數量異常。寫 yaml 時還有一個容易忽略的點path 要用相對路徑時train.py 的工作目錄必須在 yolov5 倉庫內部否則路徑基準變了相對路徑就失效。4.2 模型與輸入尺寸為什么不要照抄 640YOLOV5 官方默認輸入是 640×640那是為 COCO 那種大圖準備的而這份數據的原始分辨率只有 200×120。如果直接設置 img640程序會把小圖拉伸到六倍面積指示牌上的文字和邊緣細節(jié)全部糊掉訓練出的模型在真實賽道上表現會很差。我建議把訓練輸入設成 320甚至 224既能保留足夠細節(jié)又能大幅降低推理耗時——這一點在后期部署到小車上時感受尤其明顯。模型體量方面yolov5n 和 yolov5s 是首選。n 是 nano 版本參數量最小適合樹莓派、Jetson 這類算力受限設備s 是 small 版本精度略高但對 CPU 推理壓力更大。在小車自動駕駛這種實時性要求高、目標本身又不復雜的場景里先跑通 n再酌情升級到 s是性價比最高的路線。這份數據總共只有 1126 張圖用 m 或 l 級別的大模型幾乎必然過擬合還拖慢訓練迭代速度。下面是幾個核心超參數的經驗區(qū)間參數推薦值說明--img320 或 224原圖 200×120640 會嚴重拉伸--batch8 到 16顯存不夠就調小配合梯度累積--epochs100 起步配合 early stopping不用硬等--mosaic0.3 或 0小圖拼貼會干擾目標尺度特征--weightsyolov5n.pt官方預訓練權重遷移學習4.3 訓練命令與超參數實操鏈路訓練命令需要把數據配置、預訓練權重、輸入尺寸、輪數、batch 全部串起來。文件夾結構這里我一般會在 datasets 的同級目錄放 YOLOV5 官方倉庫然后進入倉庫目錄執(zhí)行命令。python train.py \ --data ../track_signs.yaml \ --weights yolov5n.pt \ --img 320 \ --epochs 100 \ --batch 16 \ --device 0 \ --mosaic 0.3幾個參數的取舍邏輯需要說清楚--weights 用官方預訓練權重做遷移學習比從零訓練收斂快得多尤其適合小數據集--img 320 是依據原圖分辨率定的目標最小邊大約 20 像素320 輸入下能被有效放大讓特征提取器有足夠信息可用--epochs 100 是給足訓練輪次并配合 early stopping防止過擬合的同時不浪費算力--mosaic 0.3 表示 mosaic 增強的概率降為 30%因為 mosaic 會把四張小圖拼成一張對 200×120 的小圖來說拼貼后目標尺度更混亂默認的 1.0 概率容易讓損失函數震蕩。--device 0 表示使用第一張 GPU如果沒有 GPU 則改成 --device cpu速度會慢很多但流程完整可跑。從這份數據本身的體量來看100 輪訓練在消費級 GPU 上大約半小時到一小時能完成即使只用 CPU只要能等訓練流程也能完整跑通。訓練過程中可以隨時打開 runs/exp 目錄里的 results.png 實時查看 loss 和 mAP 曲線不用等全部結束才看結果。如果訓練中途斷了不用從頭再來加一行--resume參數就能從斷點繼續(xù)這是 YOLOV5 一個很實用但總被忽略的功能。4.4 訓練產物解讀weights、標注圖和 results 曲線訓練完成后runs/exp 目錄里會出現 best.pt 和 last.pt 兩個權重文件best.pt 是驗證集 mAP 最高的一輪保存的權重last.pt 是最后一輪的權重部署時優(yōu)先用 best.pt。同目錄下的 val_batch0_labels.jpg 是驗證集某批圖片的標注框預覽圖能直觀看出模型學到的框是否準確貼合目標、類別標簽有沒有錯亂。results.png 則匯總了 box_loss、cls_loss、mAP0.5 等曲線的變化趨勢是整個訓練過程最濃縮的「體檢報告」。一個值得注意的點是YOLOV5 的 loss 曲線不能只盯著 box_loss 的絕對值看因為不同輸入尺寸、不同增強策略下 loss 的量級差異很大重點是看它有沒有穩(wěn)定下降并收斂。mAP0.5 曲線在正常訓練下應該逐漸趨平如果幾十輪后還像過山車一樣劇烈波動說明學習率太高或數據里有臟樣本需要回頭檢查第 3 章的三項體檢結果。記得把 runs/exp 里的 best.pt 單獨復制出來按項目名加日期命名免得后續(xù)訓練新模型覆蓋掉這個好不容易調出來的權重。5. 常見問題排查五個訓練與部署翻車場景的血淚記錄5.1 翻車場景一訓練一啟動就報標簽類別數越界現象運行 train.py 后立刻報錯提示某個標簽的 class 值超出范圍或者 AssertionError 指出 labels 的維度不對訓練進程直接退出。原因有兩個可能一是 data.yaml 里 nc 寫錯8 個類寫成了 9導致模型輸出通道數與標簽不匹配二是標簽 txt 里出現了類別 ID 為 8 或更大的行這通常是數據集制作時類別編號寫錯造成的。解決先打開類別字典文件數一遍類別數再寫一個小腳本掃描所有 txt 的第一列找出最大 ID確認它小于 nc。這類報錯 90% 是 nc 與 names 數量不一致把配置改對立刻就好。5.2 翻車場景二bbox_loss 高位震蕩五六十輪不收斂現象訓練 loss 一直穩(wěn)定在 3 以上震蕩沒有隨輪次逐步下降的趨勢results.png 里曲線像鋸齒一樣。原因常見兩個輸入尺寸設成 640把 200×120 小圖強行拉伸特征完全失真或者 mosaic 增強概率保持默認 1.0四張小圖隨機拼貼后目標尺度混亂。解決把 --img 降到 320 或 224--mosaic 降到 0.3 甚至 0這兩個參數調整后 loss 曲線通常會立刻變得平滑。這類問題屬于超參數和數據結構不匹配和模型結構關系不大先動數據增強再考慮換模型排查路徑更短。5.3 翻車場景三訓練 loss 正常但 val mAP0.5 始終為 0現象訓練過程一切正常loss 在下降但驗證集 mAP 一直為 0無論訓練多少輪都紋絲不動。原因通常不是模型問題而是驗證集標簽和訓練集標簽不一致最典型的是 names 順序錯位比如訓練集里類別 0 是左轉驗證集標注時類別 0 卻對應了右轉模型輸出和標簽對不上號mAP 自然算不出來。另一類是 val 路徑寫錯data.yaml 的 val 指向了一個空目錄或不存在路徑。解決先用第 3 章的配對腳本檢查 val 目錄文件是否齊全再隨機打印兩個 val 標簽 txt 對照類別 ID 和實際目標語義最后確認 data.yaml 的 val 路徑真實存在。這類問題排查起來不復雜但很磨人因為訓練流程全程無報錯。5.4 翻車場景四部署到小車上推理延遲高檢測框亂跳現象把 best.pt 加載到樹莓派或 Jetson 上做實時推理一幀處理時間超過 200 毫秒小車轉彎的時候檢測框還上下左右亂跳沒法穩(wěn)定跟蹤指示牌。原因模型輸入尺寸和推理尺寸都繼承訓練時的 640加上權重是 fp32 全精度在小算力設備上負擔很大框跳動的直接原因是單幀檢測缺少時間維度的平滑。解決推理時把輸入壓到與訓練一致的 224用 half 精度加載權重推理耗時通常能降一半以上框跳動最常見的處理方式是對連續(xù)幀的檢測框中心做 EMA 平滑ema_x 0.8 * ema_x 0.2 * detect_x ema_y 0.8 * ema_y 0.2 * detect_yEMA 系數 0.2 表示新檢測結果只貢獻 20% 權重能有效抑制單幀誤檢帶來的抖動同時保留真實轉向的跟隨能力。如果還嫌慢可以導出 ONNX 再走 TensorRT 或 OpenVINO 加速這類工具在嵌入式小車場景里是成熟方案代價是部署鏈路多一環(huán)建議放在模型精度驗證通過之后再碰。5.5 翻車場景五訓練集 mAP 高驗證集明顯偏低過擬合現象訓練到 80 輪左右訓練集 mAP 接近 1.0驗證集卻只有訓練集的一半左右兩條曲線明顯分叉。原因很明確1126 張圖對 YOLOV5 來說屬于小樣本模型參數太多把訓練數據里的噪聲細節(jié)也背下來了。解決思路有三條按優(yōu)先級排第一換 yolov5n 這種參數量更小的模型限制模型容量第二增強數據多樣性在 hyp 超參數里把 hsv_h、hsv_s、fliplr 適當調大讓模型見到的形態(tài)更多第三不要盲目加到 300 輪用 early stopping 停在驗證集最優(yōu)的輪次附近。過擬合在小數據集上無法完全消除但把訓練和驗證的 mAP 差距從一倍縮小到 20% 以內對這個體量的數據來說是完全可以做到的。6. 進階驗證三連類別AP分析、現場照片測試與半精度推理6.1 用驗證集統(tǒng)計每個類別的 AP定位短板類訓練結束后runs/exp 里的 val 結果會打出每個類別的 Precision、Recall、mAP0.5 列表。別只盯著整體 mAP 看逐類看一遍找到 mAP 最低的那個類。如果這個類在訓練集中出現的次數本來就少那補該類的圖片比調任何超參數都有效如果樣本數不少但 recall 低說明目標尺寸太小或者特征不鮮明需要針對性做增強。6.2 收集 10 張真實賽道照片做驗證模型訓練時見過的都是數據集里的場景實際賽道的光線、角度和指示牌距離會有差異。我一般會在賽道現場拍 10 張照片不經過數據集的任何預處理直接丟給模型推理用漏檢數和誤檢數作為是否部署的硬指標。import torch model torch.hub.load(ultralytics/yolov5, custom, pathbest.pt, force_reloadTrue) result model(track_spot_01.jpg) result.print()這一步用 torch.hub 加載自定義權重核心目的是驗證數據流和推理鏈路本身沒問題。如果現場照片上模型表現明顯比 val 集差先看是不是拍攝距離比訓練集更遠導致目標變小是的話就考慮把訓練輸入從 320 再調低或回到第 3 章的體檢腳本補小樣本。6.3 半精度推理與嵌入式導出的最后一步在確認類別和現場表現都達標后我才會做推理優(yōu)化。半精度是壓測里效果最直接的一步把權重轉成 half 精度推理在 GPU 或帶 NPU 的板子上能拿到接近翻倍的推理速度內存占用也減少一半。權重轉換不需要重新訓練加載模型后加一行model.half()即可導出時選擇對應的 half 版本就行。這些年我做小車部署每次都強制把「逐類看 AP → 現場拍照實測 → 轉半精度再驗一遍」完整走完少一步都會在比賽或答辯現場翻車這套流程幫我把很多隱患攔截在上車之前希望幫到你。本文還有配套的精品資源點擊獲取