资讯动态

VOC+YOLO双格式鸡数据集验收与训练避坑指南

发布时间:2026/10/18 17:07:26 来源:尧图企业网站定制
简介面向目标检测训练的鸡类视觉数据集包含525张JPEG原图和配套的Pascal VOC与YOLO双格式标注类别为单一Chicken共607个矩形标注框可帮助计算机视觉学习者快速获得干净、格式统一的训练样本。压缩包共1577个文件其中jpg原图、xml标注和txt标注各525个另有少量辅助txt整体体积约162.28MB目录简洁标注由labelImg完成边界框与目标贴合程度较好。目前已有183人学习适合用于YOLO、Faster R-CNN等检测模型的训练、数据格式转换练习或教学演示。下载后可直接复用这套VOC/YOLO双格式数据省去自行整理标注的冗杂工作也便于验证预处理流程与模型效果。1. 拿到525张的鸡数据压缩包双格式不是免检金牌从网上下载一份「鸡数据集VOC格式yolo格式525张1类别」的7z压缩包解压后看到两个顶层目录一边是VOC一边是YOLO。525张图片、单类别、两套标注格式很多人第一反应是「格式都齐了直接训练」。但做过几次检测项目就知道这种现成数据集不会随包附赠质量报告也不会告诉你哪张图的框漏标了一半更不会告诉你VOC和YOLO两份标注之间是否存在转录误差。双格式只说明作者做了格式转换不代表转换结果一定正确。这篇笔记只讲一件事把「从解压完成到训练出第一个能用的模型」之间的路程走顺——双格式结构怎么对应、验收半小时该看哪些东西、最常见的翻车位置在哪、训练参数怎么起步。适合两类读者一是农业视觉、养殖巡检这类需要单类别检测模型的开发者二是手里握着任意一份VOCYOLO双格式数据、正准备开始第一个检测训练的新手。把前面的坑提前踩平后面就能少几次深夜改代码。2. 双格式结构拆解VOC的XML和YOLO的txt如何一一对应先想清楚一个前提这个压缩包里装的是「同一批框的两种写法」不是两份不同的数据。525张图片是同一批VOC侧写了一套XML标注YOLO侧写了一套txt标注。两份标注描述的物体框完全相同区别只在坐标表达方式。搞清楚两边怎么对应后面做校验就有据可依。2.1 VOC侧XML里藏着解析所需的全部信息VOC格式的目录组织习惯是三大件JPEGImages放原图Annotations放XMLImageSets/Main放划分文件的文本列表。网上下载的数据包很多不带ImageSets因为划分文件本来就该由使用者自己生成。判断一个数据是不是「真VOC格式」核心不是目录名而是Annotations里XML的结构是否完整。打开一个XML能看到的基本字段是固定的filename、size、object。filename写这张图叫什么size里的width和height是图像的像素宽高depth一般是3object里name是类别名bndbox是物体框的左上角和右下角绝对像素坐标。一只鸡对应一个object标签如果一张图里有十几只鸡XML里就有十几个object块。annotation filenameIMG_0042.jpg/filename size width1920/width height1080/height depth3/depth /size object namechicken/name bndbox xmin512/xmin ymin330/ymin xmax780/xmax ymax620/ymax /bndbox /object /annotation注意一个容易被忽略的点XML里的filename字段不一定和文件系统里实际的jpg文件名一模一样。有的数据包在批量处理时把文件名改过但XML里没同步更新。遇到这种情况要以Annotations目录下的文件名主干为准不要以XML里的filename为准否则后面脚本匹配图片和标注时会凭空多出一堆「缺文件」的报错。bndbox是绝对像素坐标xmin和ymin是框的左上角xmax和ymax是右下角。这个坐标不需要归一化是多少就写多少和图片分辨率强相关。同一张图在1920x1080下框出来的数值和缩放到640x360之后的数值完全不同这也正是VOC格式和YOLO格式最大的差异所在。2.2 YOLO侧txt的五行数字与0号类别编码YOLO侧的组织习惯是images和labels两个平级目录图片放一边txt放另一边同名文件的扩展名不同。每张jpg对应一个同名txttxt里每一行描述一个目标框一共五个数字空格隔开。0 0.336458 0.439815 0.139583 0.268519第一个数字是类别编号这个数据只有鸡一个类别编号合法的只有0。后四个数字依次是目标中心点的x坐标、目标中心点的y坐标、目标框的宽度、目标框的高度。这四个值全部除以图片的像素宽高做过归一化所以数值范围在0到1之间和原图分辨率无关。1920x1080的画面和缩小的640x360画面算出来的txt数值完全一致。很多第一次接触的人会在这里犯迷糊类别名是chicken为什么不写chicken而写0因为在YOLO体系里类别名和编号是两回事编号从0开始递增一个类别就是0两个类别才是0和1。训练框架读txt时只认编号不认名字名字是数据集配置文件里用来给人看的映射。YOLO txt的坐标还有一个特性它记录的是中心点加宽高不是左上角加右下角。如果要把txt里的信息画回图上需要先做一次坐标换算用中心点加减一半的宽高才能得到框的左上角和右下角。这个换算关系在后面可视化抽检时会反复用到。2.3 把XML换算成txt坐标归一化的计算链路搞清楚双格式的对应关系之后可以自己写一个转换脚本。虽然这个数据包已经同时给好了两套标注不需要重新转换但这个脚本有两个实际用途一是验证数据包里两套标注是否一致二是以后自己用标注工具标了一批VOC格式数据、想转成YOLO格式训练时脚本可以直接改改复用。import xml.etree.ElementTree as ET def voc_xml_to_yolo_txt(xml_path, names(chicken,)): 把一个VOC XML转成YOLO txt格式的内容 tree ET.parse(xml_path) root tree.getroot() img_w int(root.find(size/width).text) img_h int(root.find(size/height).text) lines [] for obj in root.iter(object): name obj.find(name).text if name not in names: continue cls_id names.index(name) # 类别名转编号单类别就是0 box obj.find(bndbox) xmin int(box.find(xmin).text) ymin int(box.find(ymin).text) xmax int(box.find(xmax).text) ymax int(box.find(ymax).text) # 绝对像素坐标 - 归一化中心点 归一化宽高 x_center ((xmin xmax) / 2.0) / img_w y_center ((ymin ymax) / 2.0) / img_h w (xmax - xmin) / img_w h (ymax - ymin) / img_h lines.append(f{cls_id} {x_center:.6f} {y_center:.6f} {w:.6f} {h:.6f}) return lines这段代码的逻辑先读XML里的图片宽高再遍历所有object把bndbox的四个像素坐标取出来用中心点公式算出归一化中心坐标用宽高除以图片宽高算出归一化尺寸。names元组的顺序就是类别编号顺序单类别数据集里chicken对应0这段代码里 names.index(name) 自然算出0。用这个脚本可以反过来做一致性校验把VOC侧的XML全部转换成txt逐行和YOLO侧已有的txt做diff任何一行对不上都说明两套标注之间出现了转录误差。for xml in VOC/Annotations/*.xml; do base$(basename $xml .xml) python voc_to_yolo.py $xml /tmp/check_$base.txt diff /tmp/check_$base.txt YOLO/labels/$base.txt || echo 不一致: $base done跑完如果没有输出任何「不一致」说明两套标注严格对应后面随便用哪套都行。如果有一堆不一致千万别觉得「反正YOLO格式是后生成的以YOLO为准」——先看看是差在哪里有时候是类别编号偏移有时候是坐标小数点精度被截断这些误差虽然不大但会在训练时变成额外的标注噪声。3. 验收三步走完整性核对、可视化抽检与难度摸底训练一个检测模型之前最值得花时间的不是调参而是验收数据。数据质量直接影响模型上限标注里的一处漏标可能在训练时就让模型学会忽略某一类外观的鸡。这个数据只有525张图规模不大每一张的质量权重都很高验收更不能省。先把压缩包解开保留内部目录结构。7z压缩包用命令行解压比较省事7z x 鸡数据集VOC格式yolo格式525张1类别.7z解压后建议先看一眼目录树。正常情况下应该是VOC和YOLO两个并列目录各自带着图片和标注文件。确认目录结构符合预期后开始三步验收。3.1 完整性核对图片数、标注数与类别编号三张表对齐第一步先数数。图片数量、标注文件数量、类别编号这三张表必须对得上。find YOLO/images -name *.jpg | wc -l find YOLO/labels -name *.txt | wc -l在数据量小的前提下数量相等是基本要求。如果图片数大于标注数说明有一部分图没有标注这些图即便放进训练集也只会提供背景信息如果标注数大于图片数说明有多余的txt文件得查一下是哪来的。但数量相等并不代表一一对应还要检查文件名的主干是否完全匹配。import os img_dir YOLO/images label_dir YOLO/labels img_names {os.path.splitext(f)[0] for f in os.listdir(img_dir) if f.endswith(.jpg)} label_names {os.path.splitext(f)[0] for f in os.listdir(label_dir) if f.endswith(.txt)} print(图片数:, len(img_names)) print(标注数:, len(label_names)) print(有图无标注:, len(img_names - label_names)) print(有标注无图:, len(label_names - img_names)) # 逐行检查txt内容是否合法 bad [] for name in sorted(label_names img_names): path os.path.join(label_dir, name .txt) for line_no, line in enumerate(open(path), 1): parts line.split() if len(parts) ! 5: bad.append((name, line_no, 列数不为5, line.strip())) continue try: cid int(parts[0]) vals [float(v) for v in parts[1:]] except ValueError: bad.append((name, line_no, 包含非数字, line.strip())) continue if cid ! 0: bad.append((name, line_no, 类别编号不是0, cid)) if vals[0] 0 or vals[0] 1 or vals[1] 0 or vals[1] 1: bad.append((name, line_no, 中心点越界, line.strip())) if vals[2] 0 or vals[3] 0 or vals[2] 1 or vals[3] 1: bad.append((name, line_no, 宽高越界, line.strip())) print(疑似格式异常标注文件数:, len(bad)) for item in bad[:10]: print(item)这段脚本做四件事比对图片与标注的文件名集合、检查每行是否恰好五个字段、检查类别编号是否在合法范围内、检查归一化坐标是否在0到1之间。跑完之后正常结果应该是图片数、标注数都是525交集也是525bad列表为空。如果bad里有内容先不要急着删把异常行打出来逐条看是什么情况可能只是边缘坐标的小数截断需要人工判断。3.2 可视化抽检把标注框真实画回图上格式检查通过只说明txt语法正确不代表框的位置正确。一个框格式完全合法但可能偏了半个身子这种错误只有把框画回图上人眼才能看出来。import os import cv2 base_dir YOLO out_dir check_vis os.makedirs(out_dir, exist_okTrue) names [f for f in os.listdir(f{base_dir}/images) if f.endswith(.jpg)] names.sort() # 等间距抽20张比纯随机抽样更容易覆盖不同拍摄时段和场景 sample_names names[:: max(len(names) // 20, 1)][:20] for name in sample_names: img cv2.imread(f{base_dir}/images/{name}) h, w img.shape[:2] txt_path f{base_dir}/labels/{name[:-4]}.txt for line in open(txt_path): cid, xc, yc, bw, bh map(float, line.split()) # 归一化坐标反算回像素坐标 x1 int((xc - bw / 2) * w) y1 int((yc - bh / 2) * h) x2 int((xc bw / 2) * w) y2 int((yc bh / 2) * h) cv2.rectangle(img, (x1, y1), (x2, y2), (0, 255, 0), 2) cv2.imwrite(f{out_dir}/{name}, img)核心换算逻辑就是2.3节公式的逆运算中心点坐标减去一半宽高得到左上角加上一半宽高得到右下角。注意x方向的坐标都要乘图片宽度wy方向的坐标都要乘图片高度h这两个不能搞混否则框会直接被压缩成一条竖线或横线。画完20张图后一张张翻看重点看三件事。第一框是否贴合鸡的身体轮廓鸡是近似椭圆形的目标框的边应该刚好包住身体而不是只包住半边第二密集场景里有没有漏标如果一张图里有四五只鸡但只画了两个框这种漏标对训练伤害很大第三有没有框明显偏大把旁边的物体也包进去了。抽样结果如果一切正常可以进入下一步如果异常样本占比超过10%建议把全部525张都画出来看一遍。3.3 难度摸底分辨率、目标尺度与宽高比的现实影响抽检通过只是「看着没问题」还缺一步量化分析。同一个模型哪怕训练参数完全相同在「几百只鸡挤在一起」的密集场景和「一只鸡占半个屏幕」的稀疏场景里表现会完全两个样。先摸清数据集难度后面定训练参数才有依据。import os import glob import cv2 area_ratios [] aspects [] res_map {} for txt in glob.glob(YOLO/labels/*.txt): base os.path.basename(txt)[:-4] img cv2.imread(fYOLO/images/{base}.jpg) if img is None: continue h, w img.shape[:2] res_map[(w, h)] res_map.get((w, h), 0) 1 for line in open(txt): _, xc, yc, bw, bh map(float, line.split()) area_ratios.append(bw * bh) # 目标面积占全图比例 aspects.append(bw / bh) # 目标宽高比 print(分辨率分布:, res_map) print(目标数量:, len(area_ratios)) print(平均单张目标数:, round(len(area_ratios) / 525, 2)) print(目标面积占比均值:, round(sum(area_ratios) / len(area_ratios), 4)) print(面积占比中位数:, round(sorted(area_ratios)[len(area_ratios) // 2], 4)) print(宽高比均值:, round(sum(aspects) / len(aspects), 2))这几个数字直接影响训练策略。面积占比如果普遍在0.01以下说明绝大多数鸡只占画面很小区域属于典型的小目标场景训练时输入分辨率要开高一些anchor也要重新聚类。平均单张目标数如果超过10说明密集遮挡严重mosaic增强和损失函数里的正样本匹配策略都要做相应调整。分辨率分布如果很集中比如全是1920x1080那就不需要额外的多尺度预训练如果混着多种分辨率训练时最好开启多尺度训练。看完这三步这份数据能不能用、难度在哪里、训练时重点注意什么基本就有数了。这套动作熟练之后半小时能跑完换来的是后面少踩几个大坑。4. 避坑现场双格式数据和单类别小数据集的五个翻车点以下五个问题是我见过最多人踩的每一个都对应着真实训练失败现场。从训练报错到指标异常都有按顺序检查能省下大半天排查时间。数据预处理阶段的问题越早发现成本越低。4.1 类别ID从1开始训练直接失败现象有人看到VOC XML里类别名是chicken觉得「第一个类别应该编号为1」于是把YOLO格式txt里的0全部手动改成1。训练启动时报错或者训练能跑但检测结果全为空模型把整张图都预测成背景。原因YOLO体系里类别编号从0开始这是约定俗成的规则。一个类别的数据集合法编号只有0不存在1。VOC XML里的类别名和YOLO的类别编号不是一回事VOC没有编号概念只有名字YOLO只有编号名字靠配置文件映射。手动改编号等于把所有目标都推到不存在的类别上。解决检查所有txt第一列的最大值单类别数据合法值只能是0。awk {print $1} YOLO/labels/*.txt | sort -n | tail -1如果输出是1找到批量修改的地方改回来。以后见到任何双格式数据集先跑这条命令确认编号范围再进训练。4.2 坐标在1.0边缘的框被可视化误判为坏标注现象可视化抽检时发现一部分框贴着图像边缘或者严格校验脚本报出坐标越界看起来像是标注错误的数据。有人直接把这些样本删除结果训练集少了几十张图模型对贴边目标的检测能力明显下降。原因鸡群在画面边缘很常见鸡身体出画时标注工具会把框的边界停在画面边缘也就是xmax等于图片宽度减1。归一化之后这个值变成0.998或0.999这类靠近1.0的数。数据本身没问题是校验脚本把边缘情况一刀切判成了非法。解决区分「越界」和「贴边」两种情况。中心点坐标必须严格在0-1之间这是硬约束宽高算出来的框可以贴边因为目标本身被画面裁剪了。做校验脚本时对宽高的检查放在「宽或高不能小于等于0」和「不能比1大太多」上不要看到xmax归一化后是0.999就报错。这类贴边框要不要留取决于训练任务如果实际场景里经常有鸡出画留着反而是有价值的训练样本。4.3 jpg后缀下藏着PNG编码训练中途读图崩溃现象训练跑到某个epoch突然报图片读取错误报错指向的图片后缀是.jpg但用常规方式读图读不出来。打开这张图看有的能显示有的直接黑屏。原因数据打包时做了批量改名把原本的PNG文件直接改成.jpg扩展名文件内容编码还是PNG甚至有些文件在传输过程中已经损坏。部分训练框架读取时按jpg解码失败整个训练中断。解决训练前用图像库批量体检。from PIL import Image import glob bad [] for path in glob.glob(YOLO/images/*.jpg): try: img Image.open(path) img.verify() # 只检查文件结构不加载完整像素 except Exception as e: bad.append((path, str(e))) print(损坏或伪造图片数:, len(bad)) for item in bad[:10]: print(item)verify方法只校验文件头和解码结构不把整个图片读进内存几百张图几秒跑完。如果探出PNG编码但后缀是jpg用PIL统一转一遍重新保存成真jpg如果文件损坏无法修复直接把对应图片和标注一起从数据集中移除不要只删图片留标注那样会让训练框架报图片配不到txt。4.4 验证集指标比训练集还高为什么说这不是好事现象训练完看结果验证集mAP和精确率比训练集还高很多人第一反应是「这模型不错」。但把模型拿到自己拍的视频上一测检测框乱跳漏检严重根本没法用。原因数据划分时偷了懒直接对整个文件名列表做了一次随机切分。如果这批525张图片里有相当一部分是同一场景连拍的连续帧随机切分会把同一场景的相邻帧同时分进训练集和验证集模型在训练时其实「见过」验证集的画面。指标虚高是数据泄漏造成的假象。解决先按场景或拍摄时段对图片分组再组间划分。最简单的办法是看文件名前缀很多采集工具生成的文件名带拍摄批次编号没有命名规律的话按文件修改时间排序后分段分组。525张这样的小数据集更推荐的做法是直接做5折交叉验证每折训一个模型取平均指标比一次划分更可靠。4.5 loss在降、mAP不涨多半是标注框本身有问题现象训练曲线里loss正常下降就是验证集mAP上不去卡在一个不高的数值震荡。检查代码和超参都没问题后来把预测结果可视化出来发现框的位置整体偏大或者经常框到鸡旁边的地面。原因标注框本身有系统性误差。比如标注时习惯把框画大一圈以「确保包住」或者框的左下角普遍比真实位置偏左。深度学习模型学的是标注的统计规律如果标注系统性偏移模型学到的就是偏移后的框。解决回到3.2的可视化抽检这次重点看框和鸡身体的贴合度而不只是看有没有框。发现系统性偏移后不要手动逐张改先判断偏移方向写脚本对全部标注做统一修正比如把所有框向内收缩5%。几何修正后再训练一轮看mAP是否明显变化。这类问题在单类别小数据集上特别隐蔽因为类别单一、背景相似模型很容易把标注噪声当成特征学进去。5. 训练前的两组配置数据划分、yaml与增强参数设置数据验收通过接下来才是训练配置。单类别小数据集的参数设置和大规模多类别数据集不太一样标注数量少模型容易过拟合目标类型单一增强手段可以做针对性取舍。下面这组配置是我在这类数据上反复试过之后觉得最稳的起点。5.1 数据划分先分组再随机固定种子而不是反复重试4.4节提到随机划分可能造成数据泄漏这里给一个实操方案。525张图常规做法是按8:2切出训练集和验证集也就是420张训练、105张验证。如果还想留一份测试集可以按8:1:1切但小数据量下验证集再分薄指标波动会变大。import random import os names [f[:-4] for f in os.listdir(YOLO/images) if f.endswith(.jpg)] names.sort() random.seed(42) # 固定种子保证每次运行划分结果一致 random.shuffle(names) split int(len(names) * 0.8) train_names names[:split] val_names names[split:] with open(train.txt, w) as f: f.writelines([fYOLO/images/{n}.jpg\n for n in train_names]) with open(val.txt, w) as f: f.writelines([fYOLO/images/{n}.jpg\n for n in val_names]) print(train:, len(train_names), val:, len(val_names))固定随机种子是必须的动作。不固定种子的话每次跑脚本划分结果都不一样训练完想复现指标都做不到。这里生成的是train.txt和val.txt两个文件列表每行写一张图片的路径训练框架会按文件列表去读图片并自动寻找对应的txt标注。注意列表里写图片路径不是标注路径这是YOLO系列训练脚本的通用约定。如果发现同一场景的连拍帧污染问题就在shuffle之前先按文件名前缀分组把同一组的图片整体放入同一侧。具体写法取决于文件命名规律核心原则是「同一场景的图片不能被拆到两个集合里」。小数据量下宁可验证集比例高点也不能让指标虚高骗了自己。5.2 起步参数单类别小数据集的一组稳妥基线数据集配置文件用yaml核心内容就三块路径、训练文件列表、类别映射。path: /你的绝对路径/鸡数据集 train: train.txt val: val.txt nc: 1 names: 0: chickenpath指向数据集根目录train和val指向5.1生成的txt列表。nc是类别数单类别就是1。names里0对应chicken这个映射必须和txt文件里的编号一致。配好之后用训练入口跑python train.py --data chicken.yaml --epochs 150 --imgsz 640 --batch 16参数建议的默认值如下表这套组合在小数据量单类别场景下比较稳。参数建议值理由imgsz640 或 768鸡群场景里单只鸡面积占比常小于0.01输入分辨率调高能明显提升小目标召回batch16显存有限降到8小数据集梯度噪声大batch不宜再小epochs150单类别收敛快100轮左右基本平稳150轮留了早停裕量学习率0.01 起步小数据集学习率过高会把前期权重冲坏配3轮warmup更稳优化器SGD 带动量数据量小时SGD的泛化通常优于自适应优化器anchor自动重新聚类鸡的宽高比例和通用数据集差异大必须针对本数据重新生成早停开启patience 30防止后期过拟合指标连续30轮不涨就停imgsz是最值得关注的参数。通用目标检测训练常见imgsz640但如果3.3步统计出的目标面积占比普遍小于0.01建议直接上768。分辨率提高带来的小目标增益往往比调任何增强参数都明显。代价是训练时间变长525张图的数据量下这个代价可以接受。5.3 数据增强取舍mosaic、翻转与颜色的实际影响增强策略不是越猛越好要符合目标本身的物理规律。鸡不会倒立垂直翻转就是不合理的增强鸡左右对称水平翻转就是合理的。这一点很多人会忽略但实际影响很大。增强项建议值说明mosaic1.0模拟多尺度场景密集目标数据收益最大fliplr0.5水平翻转鸡左右对称安全flipud0.0垂直翻转后鸡像倒挂在天上模型学到无意义特征hsv_h0.2养殖场光照差异大色相扰动提升泛化hsv_s0.2饱和度扰动应对不同品种鸡的羽毛颜色差异hsv_v0.2亮度扰动应对逆光和暗光mixup0.1小数据集可用但单类别场景收益有限开小权值mosaic是这里收益最大的增强。它把四张图拼成一张相当于让模型在一张图里看到四种不同场景的鸡同时天然产生尺度变化对小目标训练非常有帮助。但mosaic有个隐藏问题四张图拼接时有些目标会被切掉一半模型需要学会对残缺目标做判断。一般训练框架会在最后几轮自动关闭mosaic让模型适配正常图像分布这个默认策略不用改。增强的整体思路是合理物理变换放开不合理物理变换关掉。颜色扰动可以给大一点因为养殖环境的自然光照本来就千变万化几何翻转要谨慎特别是垂直方向和旋转类增强。单类别数据只有一种目标增强的目的不是制造更多花样而是让模型对真实环境下会出现的差异更鲁棒。6. 把525张数据用到极致自动筛错与主动学习补标数据集只有525张训练出来的模型效果有上限这是客观事实。但这个上限能不能摸到取决于标注质量和数据利用方式。两个方向可以把这套数据的价值再榨出一些一是用脚本自动找出疑似问题标注二是用主动学习思路指导后续数据扩展。6.1 用三个几何特征自动筛出疑似问题标注人眼逐张看525张图不难但更高效的做法是先用几何特征自动筛一遍只把可疑样本留给人工看。三个特征足够筛出绝大多数问题框面积占比极端、宽高比极端、中心点贴边。def geo_check(txt_path): problems [] for idx, line in enumerate(open(txt_path)): _, xc, yc, bw, bh map(float, line.split()) area_ratio bw * bh if area_ratio 0.3 or area_ratio 0.001: problems.append((idx, 面积占比异常, round(area_ratio, 4))) if bw / bh 10 or bw / bh 0.1: problems.append((idx, 宽高比异常, round(bw / bh, 2))) if xc 0.02 or xc 0.98 or yc 0.02 or yc 0.98: problems.append((idx, 中心点贴边, (round(xc, 3), round(yc, 3)))) return problems几何异常不一定代表标注错误。面积占比大于0.3的框可能是特写镜头里一只鸡占了大半画面这是合法样本宽高比异常的框可能是鸡伸展翅膀时的瞬间姿态。这个脚本的价值是缩小人工复查范围把525张图里最可疑的几十张挑出来而不是直接当错误数据删掉。筛完之后用3.2的可视化脚本把这几十张图的框画出来快速过目。确认是错标就修正确认是极端合法样本就跳过。这一轮操作后数据集的标注置信度比最初高一个档次对后面所有训练指标都有正面影响。6.2 数据扩展主动学习补标与场景维度补强525张数据训练出的模型作为基线已经够用但不能止步于此。扩展数据最经济的方式不是去网上找更多现成数据而是用自己的模型辅助标注新数据。常见做法是先用这份数据训练一个初版模型对一批未标注的养殖场景图片做预测把置信度最低的前100张挑出来人工标注。低置信度样本往往是模型最不确定的样本信息量最大高置信度样本和已有数据高度重复标了也收益有限。这个循环跑两三轮新标的数据和原有数据合并模型效果提升通常很明显。场景维度的补强也值得做。看一下525张图里场景覆盖是否单一如果全都来自同一个养殖时段模型对清晨逆光、夜间补光场景的鲁棒性就存疑。自主补拍时重点覆盖不同光照条件、不同养殖密度、不同羽毛颜色的鸡而不是在同一个场景里重复拍几百张。最后的建议是任何外来数据集到手先把第3章的验收三件套跑完再做训练。我自己早期跳过验收直接开训翻过车后来把所有返工时间加在一起一算验收花的半小时是最值的半小时。数据集的标注质量永远比模型规模更值得花时间验证。希望帮到你。本文还有配套的精品资源点击获取

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑