ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

YOLOv5建筑工地安全数据集:目录格式、训练避坑与实战指南

YOLOv5建筑工地安全数据集:目录格式、训练避坑与实战指南 简介面向目标检测入门与工程落地的建筑工地安全隐患数据集采用YOLOv5标准目录格式覆盖头盔、口罩、车辆等10个常见安全相关类别适用于施工现场安全帽佩戴检测、人员行为预警等场景。图像统一为640×640 RGB并已完成Mosaic增强四张拼接后的图片可直接用于模型训练与验证无需额外格式转换。包体内训练集含2605张图及对应标签、验证集含196张图及对应标签同时附带可视化Python脚本随机传入一张图片即可绘制边界框并保存方便快速核对标注效果。资源共2000个文件其中1999个txt标签文件和1个py脚本压缩包整体148.9MB目录按YOLOv5标准组织开箱即用。已有611人学习下载适合需要现成安全检测数据集的开发者与研究人员直接投入实验。1. 建筑工地安全隐患检测数据集一上来就选YOLOV5目录格式省掉一半弯路建筑工地安全隐患检测这些年越来越多地落在端侧摄像头和巡检无人机上而大多数项目卡住的第一个关卡不是算法是数据集。手里这份按YOLOV5目录格式整理好的目标检测数据集10个类别直接对应工地上最常见的风险对象拿到手不用再为标签格式、目录约定、train/val划分这些琐事折腾可以马上把精力投进训练和调参。这个标题指向的正是这层价值它把「工地安全识别」从想法变成可复现的工程。适合刚入门YOLOv5想快速验证效果的开发者也适合做安全信息化项目的实施工程师。说实话这类数据集真正的价值不只在于图片张数而在目录结构和标签质量——这两点直接决定你后面所有调参是否还有意义。2. 把YOLOV5目录格式拆开看images、labels、data.yaml三处对齐才叫能训2.1 YOLOV5目录格式约定的三个组成部分一份规范的YOLOv5目标检测数据集的目录结构长这样construction-dataset/ ├── images/ │ ├── train/ # 训练图片 │ ├── val/ # 验证图片 │ └── test/ # 可选不是必须 ├── labels/ │ ├── train/ # 训练标签 │ ├── val/ │ └── test/ └── data.yaml # 数据集配置这个结构是YOLOv5约定俗成的既不神秘也不复杂。images目录只放图片labels目录放对应的txt标签文件两边通过文件名一一对应。比如images/train/site_001.jpg对应labels/train/site_001.txt后缀可以不同文件名主体必须完全一致。如果图片是.jpeg或.png标签文件仍然是.txt这个匹配关系才是唯一让训练器找到标签的依据。每个txt标签文件里的每一行代表图片中的一个目标框格式固定为五个字段字段含义取值范围class_id类别ID从0开始0 到 nc-1x_center框中心点的归一化横坐标0.0 到 1.0y_center框中心点的归一化纵坐标0.0 到 1.0width框宽除以原图宽0.0 到 1.0height框高除以原图高0.0 到 1.0还有一层关键点YOLOv5的类别ID从0开始计数所以「10类别」的ID范围是0到9不是1到10。data.yaml里的nc: 10和names列表也要从这个约定去理解。你拿到数据集后第一件事应该是把labels目录随机打开几个文件按上面表格核对一遍坐标值是否在0到1之间。如果发现有人把VOC格式的像素坐标直接塞进txt那训练器即便不报错loss也永远降不下来。2.2 用一段脚本统计10个类别的样本分布目录结构合理只代表「形式正确」不代表「内容可用」。建筑工地场景里「未戴安全帽」和「戴安全帽的人」常常同时出现在一个画面里类别分布如果不均衡模型会被大样本类别带偏。我拿到这类数据集的第一习惯是写个脚本把每个类别的框数量统计出来在训练前就对家底有数。from collections import Counter from pathlib import Path label_dir Path(labels/train) cls_counter Counter() box_count 0 empty_files [] format_errors [] for txt_path in label_dir.glob(*.txt): lines txt_path.read_text(encodingutf-8).strip().splitlines() if not lines: empty_files.append(txt_path.name) continue for line in lines: parts line.strip().split() if len(parts) ! 5: format_errors.append((txt_path.name, line)) continue cls_id int(parts[0]) cls_counter[cls_id] 1 box_count 1 print(类别ID - 框数量) for cid, count in sorted(cls_counter.items()): print(cid, count) print(f空标签文件数: {len(empty_files)}) print(f总框数: {box_count}) if format_errors: print(f格式错误行数: {len(format_errors)}, 前3条: {format_errors[:3]} else:) print(格式校验通过)这段脚本的逻辑很简单逐个读取labels/train下的txt文件空文件记录在案每行按五个字段解析类别ID计数。运行后如果出现ID为9以上的数字说明标签里有超出10类范围的类别训练时模型会强行忽略或直接报错如果空标签文件占比超过1%说明有相当一部分图片没有标注最佳实践是把这些空txt连同对应图片一起移出训练集。统计完分布之后你还要留意一个细节这类建筑工地数据集的names顺序是谁定义的就决定训练结果里每个类别的显示名称。data.yaml里的排序即使和txt里的ID不一致YOLO训练时也不会报错但评估阶段出来的混淆矩阵会全是错位名称极容易让你误判模型效果。所以第一步永远是先核对labels里的实际ID分布再去映射names别让这个顺序问题变成后面的黑匣子。3. 训练自己的数据集从哪里开始环境、data.yaml与train.py一条龙跑通3.1 搭建环境并做一次完整的目录体检拿到这份建筑工地数据集后我会先把环境准备好。常见做法是克隆Ultralytics的YOLOv5仓库用conda建独立环境然后按requirements安装依赖。下面这套在无GPU机器上也能训只是速度相差很大。conda create -n yolo python3.8 -y conda activate yolo git clone https://github.com/ultralytics/yolov5.git cd yolov5 pip install -r requirements.txt环境装完后先别急着训练。把你数据集的目录结构完整检查一遍图片和标签是否同名对齐、是否有损坏图片、labels里是否有误放进去的.class或.xml文件。这一步我通常会写一个几行的bash循环去做比任何可视化工具都趁手。数据体检的价值在于把后期训练报错的前置问题提前暴露而不是等train.py跑了一半才回头排查。cd construction-dataset for img in images/train/*.jpg; do stem${img##*/} base${stem%.jpg} [ ! -f labels/train/${base}.txt ] echo 缺标签: $base done for lbl in labels/train/*.txt; do stem${lbl##*/} base${stem%.txt} [ ! -f images/train/${base}.jpg ] [ ! -f images/train/${base}.jpeg ] echo 缺图片: $base done echo 目录体检完成这个脚本的作用是双向核对先检查图片有无对应标签再检查标签有无对应图片。这里容易踩的坑是扩展名大小写不统一.JPG和.jpg在Linux下是两种文件所以第二个循环里我用[ ! -f ]把两种常见后缀都做了判断。如果你数据集中既有jpg又有png把循环里的后缀判断扩展一下或者干脆在上面的Python脚本里统一用Path.stem对比更快。这类体检脚本建议留着后面每次往数据集里追加现场图片时都要再跑一遍。3.2 data.yaml配置与训练命令的六个关键参数目录体检通过后写data.yaml。这里我给出的类别名只是示意你拿到数据集后以本地实际标注含义为准但文件结构必须保持下面这个形态# construction.yaml path: /home/you/datasets/construction # 改成你的实际绝对路径 train: images/train val: images/val nc: 10 names: 0: hardhat 1: no-hardhat 2: safety-vest 3: no-safety-vest 4: smoke 5: fire 6: worker 7: excavator 8: truck 9: danger-area很多新手在这个文件上报错原因往往是path用了相对路径而YOLOv5在读取时会基于当前工作目录去拼train和val一旦你不在预期目录下执行命令就会找不到图片。我一般直接用绝对路径这条经验能省掉大量无意义的报错排查。另外要注意names里类别名称改来改去不会影响训练txt里数字ID才是训练时的唯一依据但如果你改动了ID顺序就等于把整份标签的语义全部打乱所以names只许改名不许换位置。配置写好之后训练命令按下面这个组合跑cd yolov5 python train.py \ --data /home/you/datasets/construction.yaml \ --weights yolov5s.pt \ --img 640 \ --batch 16 \ --epochs 100 \ --device 0 \ --cache这里七个参数是工地检测项目最常见的起手组合逐个说明--weights yolov5s.pt用小型预训练权重做迁移学习。工地检测对象不算冷门COCO预训练特征能带来明显加速收敛。显存吃紧就换yolov5n效果优先就上yolov5m。YOLOv5网络结构图上s、m、l逐层加宽加深但训练时间和显存占用也是递增关系。--img 640训练分辨率。工地场景里安全帽这类小目标尤其多640是速度与精度的平衡点。显存够用且小目标漏检严重时调到1280收益显著。--batch 16单卡16在大多数场景下都能跑显存不够就降到8或4。batch翻倍时学习率通常也要相应调整但新手阶段保持默认lr即可。--epochs 100工地方案100轮基本能收敛。如果你看到val曲线在60轮后已经走平提前停掉没有损失。--device 0指定GPU。没有GPU就写--device cpu但训练耗时会长很多请做好心理准备。--cache把图片缓存进内存加速第一个epoch之后的数据读取。显存与内存都够时这是性价比最高的提速手段。3.3 训练常见报错第一时间不能慌训练命令敲下去最常见的情况不是顺利出loss而是几秒钟后报错。第一类报错是AssertionError: train: No labels in ...原因一般是data.yaml的train路径指到了images目录但labels目录不存在或名字拼错。第二类是CUDA out of memory这个后面避坑章节会细说。第三类是权重文件下载失败因为网络原因拉不下来预训练权重可以手动下载后放到yolov5目录下再执行同一条命令。训练正常启动后你会在终端看到一个表格里面有当前epoch的box_loss、cls_loss、obj_loss以及验证集的mAP0.5。看这个表格时的正确心态是前几个epoch的mAP是0.0几甚至0.0非常正常因为模型还在把特征层从COCO预训练往工地场景迁移。真正需要警惕的是前10个epoch里loss完全不动或者mAP一直为0那大概率是标签文件解析出了问题。这时候停掉训练回到第2章的统计脚本再查一遍。训练结束后runs/train/exp目录下会生成weights/best.pt和weights/last.pt。best.pt是验证集mAP最高的权重后面做推理和部署时一律用这个文件。很多人惯性拿last.pt去部署结果是验证时还行、实际跑起来差一截这种细节差别在工地安全项目里可能就是一次误报和漏报的区别。4. 训练避坑清单五条让我返工最多的现场记录4.1 标签文件全对训练器却报FileNotFoundError现象目录结构看起来毫无问题images和labels文件一一对应运行train.py后却在数据加载阶段直接崩溃报FileNotFoundError或AssertionError: train: No labels in ...。有时候还会提示某个文件名找不到对应图片。原因这类问题最常见的根源是YOLOv5在拼接数据集路径时要求data.yaml里的path加train拼接出的目录真实存在。如果你的path指向的是datasets根目录而train写的却是construction/images/train或者反过来写重复了目录层级就会找不到图片。另外网上很多CSDN博客里的示例习惯在train:后面写txt文件路径列表那个格式是旧版YOLOv3/v4时代的写法YOLOv5不认。解决把data.yaml简化成上面第3.2节的样子path用绝对路径train: images/train、val: images/val。然后手动在终端里进到path设置的目录下ls确认images/train和labels/train都在。再不行就回到第3.1节的体检脚本把两端文件名拉出来diff一下总能定位到具体是哪个文件匹配不上。4.2 训练不报错mAP却一直停在0.3以下现象训练流程完全正常loss在下降但验证集mAP0.5始终在0.2到0.3之间打转上不去。logs里每个epoch的mAP都是那个死样子。原因这是典型的「数据本身有问题不是模型不行」。最常遇到的情况有三类一是某个类别的框数量极少比如「危险区域」总共只有20多个框无法学习二是标签框大面积遮挡或割裂比如安全帽的检测框把帽檐和头部各框了一半三是坐标归一化错误某个标注工具导出的是未归一化的像素坐标直接导致损失函数无法正确收敛。这些原因全都不会让训练报错只会让模型静静变笨。解决先跑第2.2节的统计脚本看每个类别的框数。如果确实有极稀少的类别可以选择把这个类别并入相近类或者用数据增强增加该类别样本。如果类别分布均匀但mAP依然低那就打开几十张训练图查看标注框是否正确框住目标重点看遮挡、截断、过大的背景框。修标签比模型调参有效得多这点我在工地上反复验证过。4.3 显存一开mosaic就爆炸现象训练在第一个epoch中段突然报CUDA out of memory或者跑完一个batch后直接OOM退出。把batch降到4还是崩。原因YOLOv5默认开启mosaic增强会让四张训练图拼接成一张大图。工地原图本来就常是4000×3000的监控截图即使缩放到640边长4张拼在一起带来的中间特征图显存占用也远高于单图。如果你的GPU只有8G显存mosaic是第一个需要被干预的元凶。解决先加上--mosaic 0关掉mosaic再启动训练确认能跑后再逐步加回。显存不足时另一个手段是--img 480先把分辨率降下来。还有一条被我多次验证的经验把batch从16降到8训练稳定性不会有想象中那么大的损失在工地数据集上反而常能获得更好的泛化。如果真的必须开mosaic又不炸显存可以在训练后期用--mosaic 1.0并配合--cache但这不是必经之路。4.4 安全帽这类小目标一直漏检现象训练完跑valmAP还行但打开推理结果发现画面远处工人头上的安全帽几乎全部漏检近处则正常。跑步检测视频时更是每隔几秒就丢一个目标。原因建筑工地的摄像头通常安装在制高点或围挡边缘画面里一个安全帽可能只占十几个像素。YOLOv5默认的输入分辨率是640这意味着一张4000像素宽的图片被压缩到640后十像素的帽子直接被下采样抹掉了。这不是训练不充分而是分辨率策略与目标尺度不匹配。解决最简单直接的手段是把训练和推理分辨率从640提高到1280。显存不够时可以退一步用1280推理、640训练效果不如两端都高但比不做要好。另一个常见做法是切片检测把原图切成四块或九块分别通过模型检测再合并结果。这个方案能保住小目标的原始像素代价是推理耗时增加。如果这两步都做了漏检还严重检查是不是数据集中小目标样本本身就少——先统计检测框的宽高中位数低于0.05的占比如果很大就必须补小目标样本。4.5 推理时误报比训练时严重得多现象训练集验证mAP有0.85但拿到现场新拍的图片上一跑满屏红框反光条、铁皮板、塑料布全被识别成目标。哪怕把置信度阈值调到0.5还是止不住。原因训练图片和现场图片之间的分布差距被低估了。工地数据集常常是在某个时间段集中拍摄的光照条件、拍摄高度、背景环境相对单一。模型学到的不只是「安全帽」的语义特征还捎带记住了「这个工地下午的阳光和黄色墙壁」。部署到另一个工地或换成早晚光线后原本稳定的特征被干扰项覆盖误报自然激增。解决第一步先把置信度阈值从默认的0.25调到0.35甚至0.4牺牲一些召回率换现场可用性。第二步是采集现场不同时段、不同角度的图片补充进去做增量训练。如果现场部署的是固定摄像头直接从视频流里抽帧补标效果立竿见影。这个问题的本质是数据分布漂移靠调参压不住只能靠喂真实数据。5. 进阶用法把静态数据集变成持续进化的工地数据管线5.1 用混淆矩阵和PR曲线判断模型还能不能继续用runs/train/exp/目录里除了权重文件还保存了confusion_matrix.png和PR_curve.png这两张图比终端里的mAP数值更值得花时间解读。混淆矩阵里如果「戴安全帽」和「未戴安全帽」两个类别的交叉格数值偏高说明这两类的边界特征在训练集里就没打清楚这时候你需要去看原始标注里是否存在大量「以帽檐颜色判断是否佩戴」的主观标准并统一修正标签。PR曲线在召回率0.8之前如果曲线快速下坠说明模型的高置信度预测集中在少数易识别样本上大量困难样本被漏掉——这份数据集不适合直接上线需要先补难例。这两个判断方法顺手、直观不依赖额外的代码比玄学调参可靠得多。5.2 难例挖掘与增量训练的正确姿势训练好的best.pt别直接下线先拿它跑一遍现场采集的视频或截图把所有置信度低于0.35的检测框全部导出来人工过目。这个动作在工程上叫难例挖掘hard example mining是让模型持续变强的核心手段。import torch # 用训练好的权重加载模型 model torch.hub.load(ultralytics/yolov5, custom, pathruns/train/exp/weights/best.pt, force_reloadTrue) # 对现场图片/视频做推理 results model([site_day.jpg, site_night.mp4]) # 过滤出低置信度结果便于后续人工判定 df results.pandas().xyxy[0] # 单张图时可以这样取 low_conf df[df[confidence] 0.35] print(low_conf[[name, confidence, xmin, ymin, xmax, ymax]])这个脚本的意义在于把人工精力聚焦在「模型犹豫的地方」而不是整段视频从头看到尾。导出低置信度框之后拿图片查看器逐张判读确实是目标就补标不是目标就记录成负样本。把这些新数据混入原数据集后不要直接在旧的best.pt上继续训练几千轮那样模型会遗忘之前学到的特征形成灾难性遗忘。增量训练的正确做法是把新旧数据合并用小学习率比如--lr0 0.001从best.pt继续跑20到30轮或先冻结backbone只训练检测头几轮再统一微调。我做工地安全检测项目时踩过最深的坑就是轻信了网上现成模型的验证精度拿一个看起来mAP很高的权重直接部署到现场结果被误报淹没。后来把难例挖掘和增量回灌变成例行工作后模型才真正稳下来。这份数据集的价值从来不是一次性交付而是作为你这个工地检测系统最优质的起跑线——先把数据管线建起来后续每一帧现场画面都会变成它的养分。希望帮到你。本文还有配套的精品资源点击获取
返回列表