ARTICLE DETAIL

资讯详情

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

起重机数据集YOLO训练:VOC转YOLO格式与迁移学习实战

起重机数据集YOLO训练:VOC转YOLO格式与迁移学习实战 简介起重机目标检测数据集以YOLO与VOC两种主流格式整理共包含689张清晰起重机图片及对应标注文件面向计算机视觉入门与进阶学习者可用于目标检测模型的训练、验证与效果对比。压缩包内文件总数约2000个主要类型为txt标注、xml标注和jpg图片整体大小34.35MB其中XML对应VOC格式TXT可直接适配YOLO系列框架目录按JPEGImages、Annotations、labels三类划分便于快速读取。数据集唯一标签为Mobile_crane共标出764个矩形框图片未做增强能较真实反映实际场景适合用以练习起重机识别模型构建、参数调试及格式转换。目前已有170人学习下载适合需要规范化起重机械检测数据的开发者与教学场景使用。1. 起重机目标检测数据集689张图片到底能不能直接用这个数据集的压缩包名字很直白起重机数据集YOLOVOC双格式689张图片。我拆过不少标注数据包说实话689张不算多但它是带完整矩形框标注的——764个Mobile_crane框意味着平均每张图1.1个目标属于稀疏检测场景。对于做工业监控、港口调度、工程车辆识别的朋友来说这种带准确标注的垂直场景数据比通用数据集更难得因为它不用你自己去筛图、清洗和重新标注。适合谁用想快速验证YOLO训练流程的新手、正在做工程车辆检测但还没凑够私有数据的工程师、需要一份干净标注做迁移学习起点的研究者。把这份资源当作训练的启动燃料是合理的但指望689张图训出上线级模型不现实。2. VOC与YOLO双格式的目录结构先看懂标注再谈训练2.1 JPEGImages、Annotations、labels 三件套的对应关系压缩包解压后是三个文件夹命名对用过VOC的人非常友好JPEGImages放图片、Annotations放XML标注、labels放YOLO格式的TXT标注。这套结构是从Pascal VOC迁移过来的目录习惯。关键是对应关系。689张jpg、689个xml、689个txt文件名主体是同一个比如sl_images582.jpg对应sl_images582.xml和sl_images582.txt。这意味着你在做任何训练之前第一步应该核对文件名一致性和数量一致性。我在拿到这类资源时第一件事不是直接喂给YOLO而是先跑一个统计脚本来核对三件套数量是否真的对得上以及每张图的标注框是否为空。#!/bin/bash # 核对三件套数量与文件名对应 IMGDIRJPEGImages XMLDIRAnnotations TXTDIRlabels echo 图片数量: $(ls $IMGDIR | wc -l) echo XML数量: $(ls $XMLDIR | wc -l) echo TXT数量: $(ls $TXTDIR | wc -l) # 检查同名文件是否存在 for img in $IMGDIR/*.jpg; do base$(basename $img .jpg) if [ ! -f $XMLDIR/$base.xml ]; then echo 缺少XML: $base fi if [ ! -f $TXTDIR/$base.txt ]; then echo 缺少TXT: $base fi done这段脚本做的事情就是遍历所有图片检查对应的XML和TXT文件是否存在缺哪个就把哪个文件名打出来。先把这一步做了避免训练到一半才发现有些图片没有任何标注。严格来说文件名主体一致是VOC和YOLO生态的共同假设。Ultralytics的YOLO训练流程会自动读取图片路径然后找同名的txt文件如果文件名对不上数据加载器会直接跳过那张图等于你的训练集悄悄少了几张图val指标会变得不可解释。2.2 XML里的关键节点从 object 到 bounding box 的坐标语义打开任意一个XML文件会看到Pascal VOC标准结构。关键节点是object里面包含name和bndbox。name是类别名这个数据集里固定是Mobile_crane只有一个类别bndbox下有四个子节点xmin、ymin、xmax、ymax分别表示矩形框左上角和右下角的像素坐标。annotation folderJPEGImages/folder filenamesl_images582.jpg/filename size width1920/width height1080/height depth3/depth /size object nameMobile_crane/name bndbox xmin532/xmin ymin287/ymin xmax1241/xmax ymax866/ymax /bndbox /object /annotationsize节点里的width和height最好和实际图片分辨率核对一下我遇到过标注尺寸和原图分辨率不一致的数据包这种情况在转YOLO格式时会导致框全部偏移。值得注意的一点是这里面的坐标是绝对像素坐标单位是像素不是归一化值。你在写转换脚本时xmin/ymin这些值直接除以图片宽度/高度即可得到YOLO归一化坐标。2.3 YOLO 格式的 txt 是怎么从 XML 转出来的含转换脚本TXT文件的格式是YOLO生态的标准写法每行代表一个目标框五个值按空格分隔依次是class_id x_center y_center width height。class_id从0开始这个数据集只有一个类所以所有行的class_id都是0四个坐标值全部归一化到[0,1]区间。由于资源已经同时提供了TXT文件你可以直接拿一只文件来肉眼检查比如看某个TXT里坐标是否越界。如果你想从XML重新生成TXT比如想统一做数据清洗常见做法是用一小段Python脚本完成。import xml.etree.ElementTree as ET import os def xml_to_yolo(xml_path, txt_path, class_names): tree ET.parse(xml_path) root tree.getroot() size root.find(size) img_w int(size.find(width).text) img_h int(size.find(height).text) lines [] for obj in root.findall(object): name obj.find(name).text if name not in class_names: continue class_id class_names.index(name) bbox obj.find(bndbox) xmin float(bbox.find(xmin).text) ymin float(bbox.find(ymin).text) xmax float(bbox.find(xmax).text) ymax float(bbox.find(ymax).text) x_center (xmin xmax) / 2 / img_w y_center (ymin ymax) / 2 / img_h width (xmax - xmin) / img_w height (ymax - ymin) / img_h lines.append(f{class_id} {x_center:.6f} {y_center:.6f} {width:.6f} {height:.6f}) with open(txt_path, w) as f: f.write(\n.join(lines)) class_names [Mobile_crane] xml_to_yolo(Annotations/sl_images582.xml, labels/sl_images582.txt, class_names)脚本核心逻辑不算复杂解析XML里的size拿到图像宽高遍历object节点把xmin、ymin、xmax、ymax转成中心点加宽高的归一化四元组。注意class_names列表的顺序决定了class_id如果你后续要加第二类数据务必保持同一个列表顺序否则标注类别会全部错位。这里有个坐标语义的细节VOC的bbox四个值都是像素级整数而YOLO的四元组是浮点归一化。中间任何一步用错了除数比如用width去归一化y坐标框会歪得离谱。我自己一般会写一个反向脚本把TXT再转回XML用OpenCV画框对比原图视觉验证一遍坐标是否合理。3. 在 YOLOv8 上把 689 张图跑起来数据配置与训练参数3.1 数据集目录整理与 yaml 配置拿到数据集后直接把它放到YOLOv8项目里用目录结构需要稍微调整。YOLOv8默认的布局是images/train、images/val、labels/train、labels/val这样的结构但当前数据集只有一个总体文件夹所以需要自己划分训练集和验证集。常见做法是用脚本做比例划分。689张图是小规模数据我一般按 8:1:1 划成 train/val/test但test集可以暂时不参与调参留到最后验证用。下面这段脚本把图片和对应的标注同步移动确保图片train和标注train严格对应。import os import shutil import random random.seed(42) base_dir crane_dataset img_files sorted(os.listdir(os.path.join(base_dir, JPEGImages))) txt_files sorted(os.listdir(os.path.join(base_dir, labels))) assert len(img_files) len(txt_files) 689 random.shuffle(img_files) train_num int(len(img_files) * 0.8) val_num int(len(img_files) * 0.1) splits { train: img_files[:train_num], val: img_files[train_num:train_num val_num], test: img_files[train_num val_num:] } for split, files in splits.items(): os.makedirs(fdata/{split}/images, exist_okTrue) os.makedirs(fdata/{split}/labels, exist_okTrue) for img in files: base os.path.splitext(img)[0] shutil.copy(os.path.join(base_dir, JPEGImages, img), fdata/{split}/images/{img}) shutil.copy(os.path.join(base_dir, labels, base .txt), fdata/{split}/labels/{base}.txt)划分完目录之后训练前的最后一步是写YOLOv8的数据配置yaml。这里面的路径建议写相对路径配合path字段指向项目根目录这样换机器跑不需要改动配置。# crane.yaml path: ./data train: train/images val: val/images test: test/images nc: 1 names: 0: Mobile_craneyaml里的nc是类别数这个数据集只有一类所以是1names要和TXT里的class_id顺序完全一致。这里有个容易翻车的点names是一个字典key必须是整数0顺序不能乱。如果你的标注txt里类别id是0但yaml里names的0对应名字写错了训练能跑但推理输出和可视化class名字会全错。3.2 训练命令与关键超参数说明目录和yaml都就绪后在YOLOv8环境下运行训练命令yolo train datacrane.yaml modelyolov8n.pt epochs100 imgsz640 batch16 device0我用的是yolov8nnano版作为起始权重原因很简单数据集只有689张图模型太大反而容易过拟合nano参数量小训练速度快先跑通流程再说精度。上面的命令行里epochs100对这个小数据集来说偏多通常跑到50轮左右val损失就已经到底了batch16在显存足够的情况下可以往大调小数据集每个batch的样本多样性有限batch大一点会更早稳定。参数理解上要区分两个概念训练轮次epochs和早停机制。YOLOv8默认开着早停patience默认是100实际上如果val指标连续多轮不涨训练会自动中断。对689张图这种规模的数据50-80轮通常是甜点区间太多轮只会让模型在训练集上背答案。3.3 损失函数与评价指标怎么对应到这个小数据集YOLOv8的损失函数由三部分组成box损失CIoU、分类损失BCE、DFL损失Distribution Focal Loss。小数据集下这三个损失的比重表现和COCO大训练集有差异。我训练完后会先看损失曲线如果box_loss和cls_loss都在稳步下降说明标注质量没问题如果loss震荡剧烈优先怀疑标注里混入了异常框。项目里给的描述说标签是矩形框764个框分布在689张图中意味着有部分图片是空图没有目标或者一张图多个目标。处理空图时对应的TXT文件是空文件这是合法的不需要删除但要注意空图片在训练时只参与背景学习。关于评价指标小数据集上的mAP往往虚高得厉害。因为验证集小任何一次随机初始化差异都可能让mAP波动5个点以上。我的习惯是看mAP0.5的同时强制关注mAP0.5:0.95后者能真实反映框的定位精度。如果两者差距很大说明框偏得厉害但大致位置对。4. 标注质量核查脚本用 Python 验证 764 个框有没有问题4.1 统计脚本图片数、XML 数、TXT 数逐项核对数据集简介里写了689张图、689份xml、689份txt总框数764。我拿到数据后不会直接信这句话先跑脚本把框数统计出来和764这个基准值对齐。这是因为标注数据集在压缩、上传、下载的过程中偶尔会有文件缺失文件名乱码也会让某些标注无法被正确解析。import os import glob def count_labels(txt_dir): total_boxes 0 class_count {} empty_files [] for txt_path in glob.glob(os.path.join(txt_dir, *.txt)): with open(txt_path, r) as f: lines [line.strip() for line in f if line.strip()] boxes len(lines) total_boxes boxes if boxes 0: empty_files.append(os.path.basename(txt_path)) for line in lines: parts line.split() cls_id int(parts[0]) class_count[cls_id] class_count.get(cls_id, 0) 1 return total_boxes, class_count, empty_files total, class_count, empty_files count_labels(data/labels) print(f总框数: {total}) print(f类别分布: {class_count}) print(f空标注文件数: {len(empty_files)}) print(f空文件列表: {empty_files[:10]})这段脚本逐行读取每个TXT文件统计总框数和每个类别id的框数同时把空标注文件单独列出来。如果你的统计结果和简介里写的764有出入就要警惕数据在传输过程中出了问题而不是盲目开训。4.2 坐标越界与空标注检查坐标越界是标注数据里最常见也最隐蔽的问题。YOLO格式的归一化坐标理论上应该在[0,1]区间内但标注工具偶尔会把框的一边拉出图像边缘导致x_center width/2 1这种越界情况。这类框在训练时会让损失函数异常波动。import glob import os def check_out_of_bounds(txt_dir, eps0.001): problems [] for txt_path in glob.glob(os.path.join(txt_dir, *.txt)): base os.path.basename(txt_path) with open(txt_path, r) as f: for line in f: parts line.strip().split() if len(parts) ! 5: problems.append(f{base}: 字段数量异常 {parts}) continue _, cx, cy, w, h map(float, parts) if w 0 or h 0: problems.append(f{base}: 宽或高非正数) if cx -eps or cx 1 eps or cy -eps or cy 1 eps: problems.append(f{base}: 中心点越界 cx{cx}, cy{cy}) if w 1 eps or h 1 eps: problems.append(f{base}: 宽高超界 w{w}, h{h}) return problems out check_out_of_bounds(data/labels) for p in out: print(p)我一般用宽松的上限1.001来检查因为个别标注工具在导出时会有极小浮点舍入误差。如果越界数值达到了1.5这种程度那肯定不是舍入问题而是转换脚本写错了比如没除以图像宽度就直接拼接。4.3 数据增强与类别不平衡的现实考量这个数据集只有一个类不存在类别不平衡问题但689张只有764个框平均每张图只有1.1个目标大量图片可能只有单目标甚至空背景。这种分布会让模型训练时对小目标、多目标场景泛化明显不足。数据增强是缓解小数据集过拟合的主要手段。YOLOv8自带一系列增强参数hsv_h、hsv_s、hsv_v控制颜色扰动translate控制平移scale控制缩放fliplr控制水平翻转。对起重机这种目标颜色扰动和安全别太激进。我的建议预算fliplr0.5可以放心开起重机左右对称翻转不改变语义scale0.3让模型适应目标尺度变化translate0.1不能太大因为很多起重机车体在图中占的比例不小平移多了容易让目标主体出画。如果训练时发现loss曲线有周期性尖峰多半是增强参数太激进把标注框连同目标一起移出了图像边界。5. 常见问题与避坑指南小数据集训练的三个深坑5.1 坑一压缩包解压后中文路径和空格导致训练报错现象数据集解压到某个带中文或空格的目录后yolo train命令刚启动就报文件找不到或者报RuntimeError: Dataset not found。原因Ultralytics在处理路径时对中文路径和空格支持不完整特别是一些Windows环境下从zip解压出来的路径带着中文字符数据加载器在拼接路径时出现编码错乱。解决把数据集全部放到纯英文路径下目录名不要带空格例如D:\datasets\crane_dataset。压缩包内文件夹名如果是中文解压后先整体重命名成英文再做划分。我在处理zip文件时习惯先看一遍压缩包内根目录确认没有中文目录结构再解压。5.2 坑二类别名不一致导致训练静默出错现象训练能跑loss也能降但最终验算时发现模型把所有目标都当成背景mAP接近0。原因XML里name是Mobile_crane但转换脚本里的类别列表写成了mobile_crane或mobile-crane大小写或连字符不一致导致object被直接跳过生成的TXT全是空标注。解决训练前一定要跑一遍第2.1节的核验脚本再单独检查TXT文件的非空比例。经验法则764个框除以689张图平均每图1.1个框如果统计出来的非空TXT比例低于90%大概率有标注没被正确解析。我从那以后每次处理新数据集都会先打印一次类别分布跟数据集说明里给出的框数对齐再开训。5.3 坑三小数据集过拟合严重val指标虚高现象训练到后期train loss持续下降val loss却在某轮之后开始反弹mAP曲线看起来特别漂亮但实际推理效果很差。原因689张图的验证集规模太小比如10%就是69张模型在训练集上记住了一些背景纹理和固定构图验证集刚好在分布偏差范围内导致指标虚高。解决三个手段一起用。第一降低epoch数我前面建议过50-80轮第二开启更积极的数据增强hsv_h0.015、scale0.5、fliplr0.5这类配置可以让小数据集变得更大第三用K折交叉验证代替单次train/val划分拿5折的平均mAP作为可信指标。K折在小数据集上能从数据利用率上缓解val虚高代价是训练时间翻几倍但689张图的数据量5轮训练也就几十分钟的事。5.4 坑四VOC与YOLO坐标换算出现偏移现象训练完用yolo predict测试检测框和实际目标错位半个身位或者框明显偏向目标的一侧。原因XML转TXT时有人把x_center直接写成了(xmin xmax) / 2没有除以图像宽度也有的人把xmin和ymin直接当成了归一化坐标导致整体偏移。解决写一个可视化脚本用OpenCV把TXT里的bbox画回图片抽查20张图人眼确认。import cv2 def draw_yolo_boxes(img_path, txt_path): img cv2.imread(img_path) h, w img.shape[:2] with open(txt_path, r) as f: for line in f: cls_id, cx, cy, bw, bh map(float, line.strip().split()) x1 int((cx - bw / 2) * w) y1 int((cy - bh / 2) * h) x2 int((cx bw / 2) * w) y2 int((cy bh / 2) * h) cv2.rectangle(img, (x1, y1), (x2, y2), (0, 255, 0), 2) cv2.putText(img, fcls{int(cls_id)}, (x1, y1 - 5), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 1) cv2.imshow(check, img) cv2.waitKey(0)这段脚本把归一化坐标乘回图片宽高画框展示。坐标语义如果错得离谱这里一眼就能看出来。这个操作也被我列为数据集验收的固定动作之一不再跳过。6. 用迁移学习把小数据集训练到可用的最后一步689张图训出来模型直接用于生产很可能翻车但配合迁移学习可以把它推到接近可用的程度。预训练权重里已经包含了丰富的通用特征尤其是COCO里的卡车、公交车等类别和起重机在形状上有部分共享特征。我在用这个数据集时默认从yolov8n.pt或yolov8s.pt开始而不是随机初始化。固定主干层数或者只微调检测头的做法在这个数据规模下值得优先尝试。训练完成后的验证动作也有讲究不只看mAP图。我习惯在抽30张未见过的起重机图片跑一遍推理观察框的稳定性同一个目标在不同帧之间的框是否抖动明显远距离小目标的框是否经常丢失。配合第4.2节的绘制脚本把结果叠加到原图上人眼判断比任何指标都直观。如果发现数据量确实不足导致泛化不够下一步是从生产环境里自己补标注常见做法是用当前模型做半自动预标注把置信度高的框直接采纳置信度低的框人工修正这样补几百张标注只需要几个小时。这批689张标注数据恰好可以作为半自动标注的种子模型。想充分利用这个数据集我的习惯是把它作为垂直场景的底座而不是终极训练数据。从yolov8n开始跑通流程后再用yolov8s或m型号在大一点的私有数据上续训这样迭代经济性最高。从那以后我每次做小数据集训练都强制走一遍框数核对、坐标可视化、迁移学习三步再匆忙也会把这套流程跑完。这批689张起重机的标注框质量在同类资源里算规整的正适合拿来当这个过程的练手数据。希望帮到你。本文还有配套的精品资源点击获取
返回列表