
簡介建筑工地安全目標檢測數(shù)據(jù)集提供了一套面向AI視覺開發(fā)者和工地安防系統(tǒng)研發(fā)的YOLO標準訓練資源。數(shù)據(jù)源自真實工地監(jiān)控畫面共600張已標注圖片訓練集426張、驗證集117張、測試集57張覆蓋靴子、安全帽、機械、人員、安全背心等8個類別同時標注無安全帽、無口罩、無安全背心等違規(guī)行為可用于裝備佩戴檢測與違規(guī)預警。包體共1202個文件以jpg圖片與txt標注文件為主另含yaml配置及docx說明文檔整體壓縮后約37.43MB可接入YOLOv5、YOLOv8等常用框架快速部署。目前已有264人學習下載。依托這份數(shù)據(jù)用戶可開展多類別目標檢測實驗搭建工地安全智能監(jiān)控原型降低數(shù)據(jù)采集與標注成本也能為工業(yè)安全管理及高校計算機視覺研究提供貼近真實場景的支撐素材。1. 建筑工地安全目標檢測數(shù)據(jù)集600張真實監(jiān)控圖能訓出什么做工地安全監(jiān)控的人拿到這份建筑工地安全目標檢測數(shù)據(jù)集最容易犯的錯是直接丟給YOLOv8開訓。600張真實工地監(jiān)控畫面、8個類別、YOLO格式標注看起來一步就能跑通實際上拆開看才發(fā)現(xiàn)違規(guī)類無安全帽、無口罩、無安全背心和裝備類高度重疊機械類樣本稀少類名還有拼寫坑。這些信息不提前盤清楚后面盯著訓練日志調參就是瞎調。這篇文章按我拆數(shù)據(jù)集的習慣來寫先查目錄和標簽結構再配置YOLOv8跑通訓練評估時看混淆矩陣和badcase最后補兩個部署階段的實用動作。適合做工業(yè)安防、工地智能監(jiān)控以及想拿真實場景練手目標檢測的開發(fā)者。2. 先盤數(shù)據(jù)集目錄結構、YOLO標簽格式與8個類別分布拿到zip包第一件事不是解壓了就跑而是把壓縮包內的目錄結構搞清楚。這個數(shù)據(jù)集來自Roboflow導出從文件名里那一串_jpg.rf.就能看出來——這是平臺處理過后重命名的產物中間那段十六進制哈希是圖片增強鏈路的標記。真正在訓練時起作用的是文件名主體和標注文件的同名對應關系哈希部分不影響訓練但會影響你后續(xù)人工核對badcase時認圖。2.1 解壓后的目錄600張圖片和600個txt怎么對應Roboflow導出的YOLO格式壓縮包解壓后一般是train / valid / test三個子集每個子集里再分images和labels。這份數(shù)據(jù)集對應關系是訓練集426張、驗證集117張、測試集57張。images里放.jpg圖片labels里放同名.txt標注文件一個jpg對應一個txt沒有txt的圖片在訓練時會被靜默跳過。# 解壓后先核對三個子集數(shù)量 find train/images -name *.jpg | wc -l # 應為426 find train/labels -name *.txt | wc -l # 應為426 # 再檢查同名對應缺標簽的文件會被跳過 for img in train/images/*.jpg; do txttrain/labels/$(basename $img .jpg).txt [ -f $txt ] || echo missing label: $img done這段腳本的價值在于YOLO訓練框架不會因為你少幾個txt報錯而是直接把對應圖片剔除出訓練隊列。如果缺失發(fā)生在某個稀有類別上你連日志都看不出問題只會發(fā)現(xiàn)某個類的AP莫名偏低。我一般會把這個檢查腳本在train、valid、test三個子集上都跑一遍確保圖片和標注是完整配對的。另外注意test子集在訓練階段完全不用碰它是留給你最后驗證模型泛化能力的。很多新手把test也塞進訓練導致評估時分數(shù)虛高那叫自欺欺人。2.2 YOLO標簽格式歸一化坐標與標簽體檢腳本YOLO格式的每個txt文件里一行代表一個目標共5個數(shù)值類別ID、歸一化中心點x、歸一化中心點y、歸一化寬度w、歸一化高度h。所有坐標都除以了圖片寬高值域在0到1之間??床欢@個后面排查標簽越界問題就無從下手。import random from glob import glob txts glob(train/labels/*.txt) sample random.choice(txts) with open(sample) as f: for line in f.read().strip().splitlines(): class_id, cx, cy, w, h line.split() print(fclass{class_id}, cx{cx}, cy{cy}, w{w}, h{h})我們隨機抽一個標簽文件打開看class6, cx0.482, cy0.531, w0.118, h0.204。意思是類別ID為6對應Person類目標中心點在圖片水平48.2%、垂直53.1%的位置寬度占整圖11.8%高度占20.4%。要換算成像素坐標就用cx*圖片寬、cy*圖片高。這種歸一化格式的好處是和圖片分辨率解耦訓練時無論縮放到640還是1280坐標比例都不變。下一個動作是體檢檢查所有txt的坐標值是否都在0到1范圍內。越界坐標會導致訓練時邊界框計算異常輕則loss波動重則訓練崩掉。import os from glob import glob bad 0 for txt in glob(train/labels/*.txt) glob(valid/labels/*.txt): for line in open(txt).read().strip().splitlines(): cid, cx, cy, w, h map(float, line.split()) if not (0 cx 1 and 0 cy 1 and 0 w 1 and 0 h 1): print(fout-of-range: {txt} - {line}) bad 1 print(ftotal bad lines: {bad})這個腳本看起來簡單但實際作用很大。常見情況是某些增強腳本把物體放到了畫布外導致w或h超過1模型在loss計算時對這類框給出的梯度是畸形的。我見過有人因為這類越界標簽訓練了50輪loss都降不下去最后定位到是幾百個臟標注在拖后腿。2.3 8個類別逐個拆解裝備類、違規(guī)類和機械類數(shù)據(jù)集涵蓋8個類別按語義可以分成三組安全裝備Boots、Hardhat、Safetyvest、違規(guī)行為No-Hardhat、No-mask、No-safetyvest、以及人和設備Person、Machinary。類別ID按摘要里列出的順序從0到7排列實際以壓縮包內data.yaml的names字段為準我按常見順序整理如下類別ID名稱類型業(yè)務含義0Boots裝備工地防護靴1Hardhat裝備佩戴安全帽2Machinary設備起重機等施工機械3No-Hardhat違規(guī)未佩戴安全帽4No-mask違規(guī)未佩戴口罩5No-safetyvest違規(guī)未穿反光安全背心6Person人員工地工作人員7Safetyvest裝備穿戴反光安全背心這里有兩個容易被忽略的細節(jié)。第一Machinary這個類名在數(shù)據(jù)集里就是拼寫錯誤的正確拼寫是Machinery但訓練時千萬別手滑改成正確拼寫因為標簽txt里的類別ID和data.yaml的names是一一對應的改名字不改ID不影響改錯位置就會錯位。第二違規(guī)類和裝備類是成對出現(xiàn)的一個人戴了安全帽圖上會有Person和Hardhat兩個框沒戴安全帽就會有Person和No-Hardhat。這就是第4章要展開講的標簽語義重疊問題它直接影響你在混淆矩陣里看到的誤檢分布。從業(yè)務視角看這個數(shù)據(jù)集對應的就是一個智能安全巡檢系統(tǒng)識別工人有沒有戴安全帽、穿反光背心、佩戴口罩同時識別工地上的大型機械。600張圖對8個類別來說屬于中小規(guī)模數(shù)據(jù)集如果某個類別的樣本量特別稀少比如機械訓練時就需要特殊處理這個在第4章的Machinary問題里具體展開。3. 用YOLOv8把它訓起來目錄整理、data.yaml與訓練命令數(shù)據(jù)集結構盤清楚了接下來就是把它喂給YOLOv8。這里我不推薦拿著Roboflow原始目錄結構直接用而是建議統(tǒng)一成Ultralytics官方推薦的布局images和labels兩個大目錄內部再按train/val/test切分。這樣做的好處是后續(xù)換數(shù)據(jù)集、換模型版本時訓練腳本和data.yaml可以完全復用。3.1 統(tǒng)一目錄結構與data.yaml配置先建目錄、把文件歸位。這一步純粹是體力活但目錄不統(tǒng)一后續(xù)每次訓練都要改路徑很煩。mkdir -p datasets/site_safety/images/train mkdir -p datasets/site_safety/images/val mkdir -p datasets/site_safety/images/test mkdir -p datasets/site_safety/labels/train mkdir -p datasets/site_safety/labels/val mkdir -p datasets/site_safety/labels/test cp train/images/*.jpg datasets/site_safety/images/train/ cp train/labels/*.txt datasets/site_safety/labels/train/ cp valid/images/*.jpg datasets/site_safety/images/val/ cp valid/labels/*.txt datasets/site_safety/labels/val/ cp test/images/*.jpg datasets/site_safety/images/test/ cp test/labels/*.txt datasets/site_safety/labels/test/復制完之后用前面的find | wc -l再核對一遍確保每個子集的圖片和標簽數(shù)量一致。然后創(chuàng)建data.yaml。這里注意path字段使用相對路徑不要寫/home/xxx/這種絕對路徑否則換機器跑就得改配置。# datasets/site_safety/data.yaml path: ./datasets/site_safety train: images/train val: images/val test: images/test names: 0: Boots 1: Hardhat 2: Machinary 3: No-Hardhat 4: No-mask 5: No-safetyvest 6: Person 7: Safetyvestnames的順序必須和標簽txt里的類別ID完全對齊這是YOLO系列訓練框架的硬性要求錯一位就是災難性的類別錯位。test字段寫上并不會影響訓練只是在訓練完調用val時可以指定用test子集來評估這樣得到的指標才是模型在沒見過的數(shù)據(jù)上的真實表現(xiàn)。3.2 訓練命令與關鍵超參img、batch、epochs怎么定600張圖、8個類別這個規(guī)模下我不建議直接用YOLOv8m或者更大的模型。常見做法是從最小的yolov8n開始用COCO預訓練權重做遷移。COCO上訓過的權重已經學會了通用的邊緣、紋理和物體形狀特征遷移到工地場景能顯著緩解小數(shù)據(jù)量帶來的欠擬合問題。# 在項目根目錄執(zhí)行 yolo detect train \ modelyolov8n.pt \ datadatasets/site_safety/data.yaml \ epochs100 \ img640 \ batch16 \ patience20 \ projectruns/site_safety \ nameyolov8n_600img逐項說明參數(shù)含義。modelyolov8n.pt表示加載COCO預訓練權重啟動訓練而不是隨機初始化如果不加這個參數(shù)從零訓練600張圖的效果會差很多。epochs100對600張圖是合理范圍配合patience20早停機制如果驗證集mAP連續(xù)20輪不漲就自動停止避免浪費時間。img640是訓練分辨率也是默認推理分辨率如果你發(fā)現(xiàn)監(jiān)控畫面里遠處的人很小可以嘗試img1280效果可能有明顯提升但顯存占用和推理耗時都會上漲。batch16在8GB顯存上剛好如果顯存告急就降到8。Ultralytics默認開啟了mosaic、hsv擾動等數(shù)據(jù)增強在小數(shù)據(jù)集上默認配置通常不用改這也是YOLOv8這類框架對小數(shù)據(jù)集友好的原因之一。我自己在600張圖規(guī)模上一般不加額外增強參數(shù)先跑一個baseline有問題再針對性地開增強。這里隱含的策略是先拿baseline暴露問題而不是一上來就堆技巧。3.3 訓練產物best.pt、results.csv、confusion_matrix去哪找訓練結束后輸出目錄下會有完整的過程記錄和控制臺輸出的匯總ls runs/site_safety/yolov8n_600img/ # weights/ best.pt last.pt # results.csv 每輪的loss、mAP、PR曲線數(shù)據(jù) # confusion_matrix.png 驗證集混淆矩陣圖 # PR_curve.png 每個類別的PR曲線 # train_batch*.jpg 訓練批次的增強可視化這里最重要的兩個文件是weights/best.pt和weights/last.pt。best.pt是驗證集mAP最高那輪的權重后續(xù)做推理、導出ONNX都用它last.pt只是最后一輪的狀態(tài)通常直接用best。results.csv是判斷訓練是否健康的關鍵依據(jù)看loss曲線是否平穩(wěn)下降、mAP50是否逐步爬升。如果loss降了但mAP不動說明模型在死記訓練集而沒有學到可泛化的特征這種問題在標簽語義重疊的數(shù)據(jù)集里特別常見下一章展開說。4. 常見問題排查這份工地數(shù)據(jù)集訓練時的五個坑這一章是整篇文章里最值錢的部分。前面幾章是流程這里是我實際拆數(shù)據(jù)時踩過的坑。每一條都按“現(xiàn)象→原因→解決”來寫你在訓練這份數(shù)據(jù)集時如果碰到類似癥狀直接對號入座。4.1 標簽體檢漏掉圖片比預期少某個類完全學不出來現(xiàn)象訓練日志里顯示的圖片數(shù)比426少或者某個類別在混淆矩陣里一整行都是黑的AP數(shù)值在0.05以下徘徊。原因jpg和txt不同名導致圖片被靜默跳過。Roboflow導出的文件名很長里面帶哈希和rf標記有些人用腳本批量移動文件時按.切割文件名切出來的主體對不上造成label丟失。還有一種情況是txt里存在空文件YOLO訓練框架讀到空標簽會跳過該圖。解決訓練前強制跑一遍2.1和2.2里的腳本把缺失標簽的圖片和空txt文件全部列出來。缺失的看能不能從原始數(shù)據(jù)補補不了就直接刪掉對應圖片保證訓練集“圖標配對”是干凈的。從那以后我每次拿到新數(shù)據(jù)集都會先做這一步幾分鐘的時間能省下后面好幾輪的排查。4.2 安全帽和人員互相誤檢Hardhat與Person嚴重混淆現(xiàn)象驗證集上Hardhat的檢出框經常壓在Person框上明明沒戴安全帽的人也被打上Hardhat標簽?;煜仃嚴颒ardhat和Person兩塊交叉位置亮度很高。原因這是標注語義本身的問題。一個戴安全帽的工人圖片上同時有Person框和Hardhat框兩個框的中心高度重疊模型學到的特征是“凡是像人的地方大概率有安全帽”。如果訓練數(shù)據(jù)里戴帽子的正例遠多于背景反例模型就會把Person和Hardhat當成強綁定關系。解決先看混淆矩陣確認混淆程度然后再決定策略。輕度的可以用后處理規(guī)則修正——同一位置如果同時出現(xiàn)Hardhat和No-Hardhat按置信度取高者嚴重的可以考慮干脆把標注合并成二分類只檢測Hardhat戴帽和No-Hardhat沒戴帽去掉Person類讓模型專注解決戴沒戴的問題。我在類似場景做過這種刪類合并因為對工地安全監(jiān)控來說真正要報警的就是“有人且沒戴帽”Person類本身并沒有獨立業(yè)務價值。4.3 Machinary類持久學不出來mAP一直趨近于0現(xiàn)象loss正常下降其他類別AP都在漲只有Machinary類的AP曲線貼著0軸走混淆矩陣里這一行幾乎全黑檢測結果偶爾把它預測成Person或背景。原因機械類樣本太少。這份數(shù)據(jù)集總共600張圖、8個類別分配到Machinary上的可能只有幾十個實例而且起重機和挖掘機在不同角度、不同距離下的外觀差異極大幾十個樣本根本覆蓋不了類內差異。模型在有限的迭代輪次里只能記住訓練集里那幾張圖的樣子泛化自然無從談起。解決短期內把Machinary類別從訓練里去掉把它對應的框忽略掉先保住其他7個類別的精度。長期看如果你真的需要機械檢測就得單獨補充機械類數(shù)據(jù)哪怕補100張也比在這600張圖里硬扛強。另外注意一個操作細節(jié)刪類時標簽txt里的其他類別ID要重新排不能留空洞否則ID對不上names。4.4 遠處安全帽漏檢近處能檢遠處一塌糊涂現(xiàn)象靠近攝像頭的工人檢測效果不錯越遠的畫面漏檢越嚴重。mAP50可能還行但mAP50-95低得離譜。原因640分辨率下遠處一個安全帽可能只有十幾個像素寬的小目標特征。YOLOv8n本身對小目標不敏感加上訓練分辨率壓到640小目標信息在特征圖下采樣過程中被抹掉了。工地監(jiān)控的特點是視野寬、目標密集這個問題幾乎一定會出現(xiàn)。解決第一步把img提到1280訓練和推理通常小目標AP會有肉眼可見的提升代價是顯存占用翻倍、推理速度變慢。如果后期要部署到實時監(jiān)控就用切圖推理把大圖切成512×512的塊分別檢測再合并結果。這個方案現(xiàn)在已經很成熟推薦給有實時需求的場景。4.5 訓練中途loss變成NaN先查臟標簽和壞圖現(xiàn)象訓練進行到十幾輪loss突然變成nan之后每個epoch的loss都是nan訓練實際上已經失效。原因最常見的是數(shù)據(jù)集里混入了損壞圖片jpg文件不完整或者標簽里有極端坐標值比如w或h為0的框甚至類別ID超出names長度。這種臟數(shù)據(jù)在訓練中被隨機采樣到導致loss計算出現(xiàn)除零或梯度爆炸。解決寫一個腳本遍歷所有圖片用OpenCV讀取讀不出來的標記為損壞并剔除同時用2.2的越界檢查腳本把所有txt過濾一遍發(fā)現(xiàn)w或h為0的行直接刪掉。如果是梯度爆炸導致的把lr0從默認的0.01降到0.005再試但優(yōu)先還是處理數(shù)據(jù)。5. 驗證模型而不是相信訓練日志val評估、PR曲線與badcase分析訓練完看loss曲線覺得“穩(wěn)了”就收工是很多新手的習慣。但在這個數(shù)據(jù)集上訓練loss下降只能說明模型記住了訓練集驗證集上的表現(xiàn)才是真正要關注的。第3章里訓練日志最后輸出的mAP值只是訓練過程中對驗證集的一個快照遠不夠全面。這里用測試集做獨立評估再結合badcase分析得到的是可落地判斷。5.1 用測試集評估命令與指標取舍# 用57張測試集圖片評估而不是默認的驗證集 yolo detect val \ modelruns/site_safety/yolov8n_600img/weights/best.pt \ datadatasets/site_safety/data.yaml \ splittest \ conf0.25 \ iou0.5splittest是這里的要點。Ultralytics默認用val目錄做評估但我們在第3章配置了test字段加上這個參數(shù)就會用那57張從未參與訓練和驗證的圖片來評估結果更接近部署時的真實表現(xiàn)。conf0.25是默認置信度閾值iou0.5是NMS的IoU閾值剛開始評估就用默認值跑出baseline再說。輸出會給出每個類別單獨的mAP50和mAP50-95這才是判斷每個類健康狀況的第一手資料。mAP50和mAP50-95的區(qū)別要明確mAP50只要求預測框和真實框交并比超過0.5就算對比較寬容mAP50-95會對從0.5到0.95的一系列IoU閾值平均要求極其嚴格。小目標居多的數(shù)據(jù)集mAP50-95普遍偏低這不必焦慮——工地安全監(jiān)控這個場景框的位置大致準就行mAP50才是主要參考指標mAP50-95用來橫向對比模型版本。5.2 混淆矩陣的讀法重點看哪幾個位置confusion_matrix.png是一個8類背景的方陣行代表真實類別列代表預測類別對角線越亮越好。拿到圖先不急著看整體準確率而是盯著三塊位置一是Hardhat行里和Person列交叉的地方亮則代表安全帽被誤檢成人員二是No-Hardhat行里和背景列交叉的地方亮則代表未戴帽違規(guī)行為被漏檢三是背景行里如果有大塊亮區(qū)說明模型在沒有任何目標的地方畫了框這類誤檢在巡檢場景會直接觸發(fā)誤報。讀混淆矩陣還有一個技巧不要只看亮不亮要看同行的其他列是否出現(xiàn)“結構性偏斜”。比如Person行里Hardhat列也很亮說明模型本質上把“人”和“帽子”耦合了這就是4.2說的語義重疊問題在圖上會表現(xiàn)為戴帽和沒戴帽的檢測結果互相打架。解決方向在前面已經說了合并類別或者加后處理規(guī)則而不是單純堆訓練輪次。5.3 badcase可視化按置信度排序找最難樣本指標是匯總數(shù)據(jù)badcase才是具體問題。用訓練好的模型跑一遍測試集把預測結果可視化輸出然后人工翻圖。注意不要隨機翻按置信度排序來看。from ultralytics import YOLO model YOLO(runs/site_safety/yolov8n_600img/weights/best.pt) results model.predict( sourcedatasets/site_safety/images/test, conf0.25, saveTrue, # 把標注了框的圖片存下來 projectruns/badcase, nametest_pred, save_txtTrue, # 同時輸出預測的txt標注方便后續(xù)對比 )跑完之后runs/badcase/test_pred里每張圖都畫了預測框。我一般先從置信度最高的誤檢看起——高置信度還檢錯說明模型學到了一個錯誤模式這是最要命的然后看漏檢特別是No-Hardhat的漏檢因為這是工地安全監(jiān)控的核心報警項。corresponding的txt文件可以用來和真實標注做IoU對比IoU低的那批圖就是你需要針對性補數(shù)據(jù)的樣本或者需要調整后處理邏輯的樣本。6. 進階部署到工地實時監(jiān)控前先做這兩個動作訓練好的模型要真正放到工地監(jiān)控里光有best.pt是不夠的。工地現(xiàn)場跑的一般是邊緣計算盒子或者帶GPU的NVR設備PyTorch直接推理在性能和部署友好度上都不過關。第一步先把模型導成ONNX格式。yolo export modelruns/site_safety/yolov8n_600img/weights/best.pt \ formatonnx \ opset12 \ imgsz640導出后得到一個best.onnx用ONNX Runtime或者OpenVINO都能直接跑。opset12是兼容性比較好的版本老設備也能識別。導出前可以先跑一遍val對比ONNX和PyTorch的mAP因為量化或opset轉換偶爾會帶來精度損失如果掉了超過1個點就要檢查哪層出了問題。第二個動作是設計報警后處理規(guī)則這是工地場景區(qū)別于通用目標檢測的地方。監(jiān)控視頻每秒25幀不可能每幀都報警否則誤報會淹沒真實違規(guī)。常見做法是幀采樣加持續(xù)確認每5秒取一幀做檢測檢測結果不直接觸發(fā)報警而是送入一個計數(shù)器連續(xù)N幀確認存在違規(guī)才推送告警。# 偽代碼安全帽違規(guī)報警邏輯 frame_count 0 warn_count 0 while True: frame capture_next_frame() # 每5秒抽一幀 dets model(frame) # 目標檢測 hardhat_off [d for d in dets if d.cls 3] # No-Hardhat persons [d for d in dets if d.cls 6] # Person # 核心規(guī)則違規(guī)框和人員框位置匹配才算數(shù) for h in hardhat_off: if has_overlap(h, persons, iou_thresh0.3): warn_count 1 break if warn_count 3: # 連續(xù)3次抽查都發(fā)現(xiàn)違規(guī) send_alert(工人未佩戴安全帽) warn_count 0 if frame_count 10: # 一段時間后重置計數(shù)避免重復報警 warn_count 0這段偽代碼里最值得注意是has_overlap這一步。前面花了很長的篇幅說Hardhat和Person標簽語義高度重疊那么在推理階段No-Hardhat框如果沒有和Person框重疊大概率是誤檢不應該進入報警計數(shù)。另外No-Hardhat和Hardhat同時出現(xiàn)在同一位置時按置信度取高者這個規(guī)則能過濾掉相當一部分模型自身的不穩(wěn)定輸出。工地安全監(jiān)控這個場景模型的mAP只要夠用就行真正決定產品體驗的是后處理規(guī)則能不能把誤報率壓下去。從那以后我每次拿到一個新的目標檢測數(shù)據(jù)集都會強制先跑一遍標簽體檢腳本把越界坐標、缺失標簽、類別分布打印出來貼到項目文檔里。這個習慣救過我很多次希望幫到你。本文還有配套的精品資源點擊獲取