ARTICLE DETAIL

资讯详情

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

579张图跑通荔枝成熟检测:VOC/YOLO格式与YOLOv8训练避坑指南

579张图跑通荔枝成熟检测:VOC/YOLO格式与YOLOv8训练避坑指南 简介荔枝成熟检测数据集包含579张实拍标注图片覆盖绿、半红、红三种成熟度类别共2911个目标框green 1387、half 892、red 632适合目标检测入门者、农业AI开发者及算法评测使用。数据采用labelImg人工标注同时提供Pascal VOC格式xml与YOLO格式txt可直接导入YOLOv5、MMDetection等主流框架。整个zip压缩包共1739个文件包含579张jpg原图、579个xml标注、579个yolo txt以及少量辅助txt包体约29.5MB结构简洁已有297人浏览学习。该数据集可帮助使用者省去自行采集与标注的耗时专注模型调优和成熟度判别逻辑类别覆盖从青果到全红的完整过渡适合用于果园产量预估、采摘机器人视觉等场景整体标注框数充足为训练稳定的检测模型提供了基础数据支持。1. 荔枝成熟检测数据集579张图为什么够你跑通一个农业检测项目579张图的荔枝成熟检测数据集绿、红、半红三个类别看起来规模不大但如果你只想验证目标检测在农业场景下的可行性这个体量刚好卡在“能跑通”和“不会浪费算力”之间。做农业视觉的人都知道果园现场的数据不是缺是乱——光照不均、枝叶遮挡严重、同一串荔枝上三种成熟度并存这种数据拿通用目标检测模型直接跑十有八九会翻车。这套数据集的实用价值在于让你用最短时间跑通“解压→看标注→转格式→训练→验证”这条链路而不是追求一个虚高的mAP。适合三类人刚入门目标检测的学生、要做农产品分级demo的工程师、以及想评估成熟度检测项目投入产出比的团队。接下来我会把这些格式细节和训练路径拆开讲。2. 拆开这份VOCYOLO格式的数据集目录结构、标注文件与3类标签拿到zip包第一件事不是解压就训练而是先摸清目录结构。目标检测数据集压缩包解压后要么是VOC风格要么是YOLO风格这份同时给了两种省去了格式互转的第一步。但两类格式的存放约定差异很大搞混了目录训练脚本连图片都找不到数据加载阶段就会报错。2.1 数据集目录长什么样先搞清VOC和YOLO两套标注的存放方式VOC格式的约定来自PASCAL VOC竞赛目录通常长这样解压后一般是一个VOCdevkit或VOC2007命名的顶层目录VOC2007/ ├── Annotations/ # 每张图片对应的xml标注文件 │ ├── 000001.xml │ └── 000002.xml ├── JPEGImages/ # 原始图片 │ ├── 000001.jpg │ └── 000002.jpg └── ImageSets/ └── Main/ # 按任务划分的图片名清单 ├── train.txt ├── val.txt └── ...这里ImageSets/Main下的txt文件每行存一个不带扩展名的文件名比如“000001”而不是“000001.jpg”。训练时按清单去JPEGImages里找图、去Annotations里找标注所以清单里的文件名写错即使图片和xml都存在也会被跳过。很多新手把jpg文件放到了Annotations目录、xml放到JPEGImages或者把文件名带扩展名写进ImageSets都会导致训练时数据加载异常。YOLO格式的目录约定和VOC不一样它把图片和标注分成images和labels两个顶层目录dataset/ ├── images/ │ ├── train/ # 训练图片 │ └── val/ # 验证图片 └── labels/ ├── train/ # 训练标注txt └── val/ # 验证标注txtYOLO的txt标注文件名和图片文件名必须完全一致不含扩展名一张图片对应一个txt。txt里每行描述一个目标格式是“class_id x_center y_center width height”坐标全部归一化到0到1之间。注意class_id是从0开始的整数而VOC的xml里存的是类别名字符串这一步映射关系是后续很多坑的源头。拿到双格式数据集我一般会先跑两条命令确认图片和标注数量对得上find JPEGImages -name *.jpg | wc -l find Annotations -name *.xml | wc -l如果图片数和xml数不一致说明标注不完整得先把缺标注的图片挑出来不能直接训练。这个动作在579张图的小数据集上几秒钟跑完但能省掉后面排查数据加载异常的大量时间。如果两套格式都存在我还习惯额外对比一下VOC里的ImageSets/Main/train.txt和YOLO里images/train目录的图片数确认两套划分是否一致。提示VOC的xml文件名和图片文件名一致是PASCAL的硬性约定。解压后先随机抽查三个xml确认object节点里没有空name或空bndbox再做格式转换。2.2 XML和TXT标注互转一个脚本看懂两类格式的字段映射如果数据集提供的是VOC标注而要喂给YOLO系列模型训练就必须把xml转成txt。转换的核心是把xml里的绝对像素坐标换算成归一化的相对坐标。这里给出一段我常用的批量转换脚本import xml.etree.ElementTree as ET import os class_names [green, red, half_red] # 顺序必须和data.yaml里的names一致 def convert_voc_to_yolo(xml_path, out_txt_path): 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 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) # 四个坐标分别clip到图片边界内防止转换后越界 xmin max(0, min(xmin, img_w)) xmax max(0, min(xmax, img_w)) ymin max(0, min(ymin, img_h)) ymax max(0, min(ymax, img_h)) # 中心点坐标和宽高都归一化到[0,1] x_center (xmin xmax) / 2.0 / img_w y_center (ymin ymax) / 2.0 / img_h box_w (xmax - xmin) / img_w box_h (ymax - ymin) / img_h lines.append(f{class_id} {x_center:.6f} {y_center:.6f} {box_w:.6f} {box_h:.6f}) with open(out_txt_path, w) as f: f.write(\n.join(lines)) xml_folder Annotations out_folder labels os.makedirs(out_folder, exist_okTrue) for xml_file in os.listdir(xml_folder): if xml_file.endswith(.xml): txt_name xml_file.replace(.xml, .txt) convert_voc_to_yolo(os.path.join(xml_folder, xml_file), os.path.join(out_folder, txt_name))这段脚本的核心逻辑是先读xml里的图片宽高遍历object节点取类别名和bndbox四个像素坐标再把坐标换算成中心点加宽高的归一化表示。我特别加了一步clip操作原因是标注工具偶尔会留下越界的框YOLO训练时对超出0到1区间的坐标会告警大量越界框还会拉低前几个epoch的稳定性。class_names的顺序必须和最终训练用的data.yaml里names的顺序一致。比如你在yaml里把names写成[green, red, half_red]转换脚本里也必须是这个顺序否则类别索引错位模型会把绿荔枝当成红荔枝来学。我在实际转多类别数据集时踩过一次这种坑教训是转换前先看一眼yaml和脚本里的names对不上就先改脚本再跑。还有一个经常被忽视的小问题就是xml文件的编码。有些标注工具导出的是UTF-8带BOM格式ElementTree默认解析一般没问题但如果你在Windows上用记事本改过xml有时候会出现“xml.parsers.expat.ExpatError: not well-formed”这类错误。遇到这种报错先确认文件内容里没有特殊字符或者用Python以errorsreplace方式重读再不行就换个文本编辑器重新保存成无BOM的UTF-8。2.3 标签分布与类别平衡绿、红、半红三类在实际果园里的比例579张图、3类目标看起来不多但每张图里可能有多个目标先统计每个类别的标注框总数判断数据是否平衡import glob import os txt_files glob.glob(labels/train/*.txt) counts {0: 0, 1: 0, 2: 0} for txt in txt_files: with open(txt) as f: for line in f: line line.strip() if not line: continue cls_id int(line.split()[0]) counts[cls_id] 1 print(counts)如果某个类别只有几十个框说明样本严重不足模型大概率学不好这一类。荔枝成熟检测里最典型的是“半红”类别又少又难标注它介于绿和红之间标注员的判定标准经常不一致同一张图不同人标出的类别可能不一样。我的做法是先把判定模糊的样本单独挑出来和标注源头统一一套标准。比如约定果实表面红色区域占比超过80%算红低于20%算绿其余算半红。标准定下来之后再看哪一类样本不够考虑补充数据还是做重采样。类别不平衡时不要急着上focal loss或调loss权重。579张图的小数据集先试两类操作一是对少数类做数据增强比如针对半红样本做小幅亮度扰动二是把少数类图片在训练集里按一定倍率重复采样进去让模型每个epoch多看到几次。这样比直接改损失函数更可控效果也更直观。还有一种思路是用类别权重把少数类的loss放大但在小数据集上容易放大噪声标注的影响我一般放在最后考虑。在这个体量下我还建议做一个图片级别而不是框级别的分析。比如某一类图片特别多但每张图只有1个框另一类图片很少但每张图有10个框统计框数并不完全等价于样本丰富度。实操里我同时统计图片数和框数两个指标如果少数类别的图片数少于50张即使框数看着还行也要小心模型学不稳。3. 用YOLOv8在本地跑通荔枝成熟检测从数据集划分到训练启动数据集确认无误后下一步就是让检测模型跑起来。我优先用YOLOv8系来做小数据集验证原因是ultralytics的流程足够简单数据加载、增强、训练、验证都封装好了579张图从启动到收敛只需要一个命令。YOLOv5、YOLOv6、YOLO11也都可以做法大同小异核心是先把数据和配置文件准备对。3.1 准备环境与数据集目录yaml文件怎么写才不会报错YOLOv8运行时要求你准备一个data.yaml描述数据集路径和类别名称。写错一个路径或类别名训练命令跑不到第二个epoch就会崩。下面是我针对这份荔枝数据集的yaml模板path: /home/user/lychee_dataset # 数据集根目录绝对路径或相对路径 train: images/train # 训练图片目录相对于path的路径 val: images/val # 验证图片目录 nc: 3 # 类别总数绿、红、半红 names: 0: green 1: red 2: half_redpath字段在YOLOv8里是所有相对路径的基准train和val都写相对于path的子路径。如果你习惯用绝对路径可以把train和val写成完整的绝对路径同时把path留空或用“.”但这样在换机器时容易踩路径不一致的坑我通常统一用相对路径加根目录path。names的顺序和转换脚本里的class_names顺序要严格对应。另外yaml里不要有多余的空格尤其是“0: green”这种键值对缩进错误会让YAML解析报错报错信息有时候还不容易看懂。在第一次跑训练之前我习惯先确认环境和设备状态python -c import torch, ultralytics; print(torch.__version__, ultralytics.__version__) nvidia-smi如果输出正常再执行训练命令。如果nvidia-smi没有输出或torch.cuda.is_available()为False说明CUDA没配对纯CPU训练579张图虽然也能跑但会慢很多建议先把驱动和PyTorch版本对齐。很多新手一上来就报错其实不是代码问题而是显卡驱动太老或者PyTorch的CUDA版本匹配不上。3.2 划分训练集/验证集随机划分与按场景分组划分的差别数据划分直接决定验证集是否可信。随机划分适合图片来源同质、场景差异小的数据但果园数据往往来自不同果园、不同树、不同时间随机划分可能把同一棵树的连续帧同时分进训练集和验证集让验证分数虚高。如果图片文件名里带着拍摄位置或时间信息推荐按场景做分组划分。下面先给一个随机划分脚本import random import os import shutil images [f for f in os.listdir(images) if f.endswith(.jpg)] random.seed(42) random.shuffle(images) train_imgs images[:int(len(images) * 0.8)] val_imgs images[int(len(images) * 0.8):] os.makedirs(images/train, exist_okTrue) os.makedirs(images/val, exist_okTrue) os.makedirs(labels/train, exist_okTrue) os.makedirs(labels/val, exist_okTrue) for img in train_imgs: shutil.move(fimages/{img}, images/train/) shutil.move(flabels/{img.replace(.jpg, .txt)}, labels/train/) for img in val_imgs: shutil.move(fimages/{img}, images/val/) shutil.move(flabels/{img.replace(.jpg, .txt)}, labels/val/)脚本把图片按8:2随机分成训练集和验证集同时把对应的txt标注同步移动到labels目录下。注意seed42固定住随机数保证可复现。如果你的图片名包含果园或果树编号比如farm01_tree02_001.jpg这样的命名建议先按farm分组再划分而不是全局随机。因为同一棵树的图片背景非常相似一旦同时出现在训练集和验证集模型很可能通过背景就能认出目标验证集mAP看着很高一到新果园就掉一半。按组划分的思路是把图片按farm编号分组再把farm列表随机打乱后按比例分配代码逻辑比随机划分稍长但能换来更可信的验证指标。如果你的数据里没有这类分组信息那就只能用随机划分同时接受mAP可能虚高的风险并在后续做视频抽帧测试时重点验证场景泛化能力。3.3 训练命令与参数imgsz、epochs、batch对不同显存怎么配训练命令在Ultralytics里收敛得很简洁我一般用下面的模板yolo train datadata.yaml modelyolov8n.pt imgsz640 epochs100 batch16 device0关键参数逐个说modelyolov8n.pt是nano版权重文件小、训练快最适合只有579张图的小数据集。如果你的显存足够且想要更高精度可以换yolov8s.pt但训练时间会明显上涨而且小数据集上从nano换到s收益有限因为瓶颈在数据量不在模型容量。imgsz训练输入尺寸默认640。荔枝果实在整张图里可能只占几十个像素如果漏检严重试试imgsz960但显存占用会显著上升。epochs小数据集上100轮起步但不要无脑跑300轮。数据少模型容易过拟合训练到后期验证指标可能先升后降建议打开早停。batch显存不够就调小batch比如8或4同时调低workers。batch越大梯度越稳定但小数据集上batch过大反而容易过拟合我用16居多。不同显存下我一般按这个表来配参数参数6GB显存8GB显存12GB以上imgsz6409601280batch88-1616-32modelyolov8nyolov8n/syolov8s/m训练开始后前10个epoch盯着loss曲线看。如果loss直线不降或者干脆发散立刻停下排查别让它跑完100轮才发现白跑。训练过程中每轮会输出Box P、R、mAP50、mAP50-95等指标。小数据集上mAP50-95和mAP50的差距通常比较大比如mAP50有0.85、mAP50-95只有0.5这很正常因为IoU阈值提高后小目标的定位偏差会被放大。如果你的mAP50-95明显偏低优先考虑提高标注框的贴合度而不是加训练轮数。训练结束后用runs/detect/train/weights/best.pt做验证推理别用last.pt小数据集上last.pt在后期往往已经过拟合。4. 训练前先做数据检查标注可视化与3类常见标注错误不管数据集是买来的、下载的还是自己标的先可视化标注再进训练这一步能省的时间远比你想的多。579张图不多全量可视化也就十几分钟但你能直观看到三类成熟度的框标得准不准、有没有把树叶当成荔枝、有没有漏标背景里的果实。4.1 用OpenCV画框检查一眼看出错标、漏标、越界写个脚本把标注画回原图人工扫一遍最有说服力import cv2 img_path JPEGImages/000001.jpg txt_path labels/000001.txt img cv2.imread(img_path) h, w img.shape[:2] with open(txt_path) as f: for line in f: parts line.strip().split() if len(parts) ! 5: continue cls_id, xc, yc, bw, bh [float(p) if i 0 else int(p) for i, p in enumerate(parts)] x1 int((xc - bw / 2) * w) y1 int((yc - bh / 2) * h) x2 int((xc bw / 2) * w) y2 int((yc bh / 2) * h) color (0, 255, 0) if cls_id 0 else ((0, 0, 255) if cls_id 1 else (0, 165, 255)) cv2.rectangle(img, (x1, y1), (x2, y2), color, 2) cv2.putText(img, str(cls_id), (x1, y1 - 5), cv2.FONT_HERSHEY_SIMPLEX, 0.6, color, 2) cv2.imwrite(check_000001.jpg, img)这段脚本把归一化坐标还原成像素坐标在原图上画框和类别id。可视化检查重点看四类问题一是框是否贴着果实边缘还是把整簇枝叶包进去二是一个果实是否被画了两个重叠框这是标注重复三是框的边界是否超出图片范围这是转换时坐标没clip四是类别id和框内果实的实际成熟度是否对得上尤其是把半红标成红这类错标。只要发现其中任何一类问题就先修数据再训练。宁可花半天修标注也不要让模型用错误标注学100轮后者纯属浪费算力。抽检时不要只看训练集验证集也要看一遍。后续的mAP评估只看验证集如果验证集本身有错标模型的正确预测反而会被当成错误框拉低mAP。这种假性掉点最让人抓狂因为你会误以为是模型能力问题实际是评估集脏了。4.2 检测小目标的技巧荔枝在树冠场景下究竟算不算小目标目标检测社区里有个粗略约定目标边长小于32像素算小目标。荔枝挂在树上远距离拍摄时果实直径经常只有20到30像素所以这份数据很可能包含不少小目标样本。小目标检测最常见的问题是漏检和定位偏差解决方向有三个第一是用带P2层的高分辨率输出模型YOLOv8的P2模型在特征图中增加了浅层对小目标更友好第二是训练时把imgsz加到960或1280相当于把目标在输入端放大第三是切图推理把2048x1536的大图切成若干640x640的分块分别推理再合并结果。分辨目标尺寸的另一个办法是跑一条统计脚本把所有标注框的像素面积分布打出来。如果超过一半的框边长小于32像素就可以确定这是小目标场景。在小目标为主的数据集上输出分辨率不足往往比模型容量不足更致命所以先加imgsz再考虑换模型是更稳的顺序。我用这份小数据集的经验是P2模型因为浅层参数多在579张图上更容易过拟合不建议一上来就用。先跑imgsz640的nano模型如果漏检率高再考虑imgsz960或者切图推理。切图推理不需要重新训练只影响推理阶段实施成本最低适合快速验证到底是不是小目标引起的漏检。4.3 数据增强要不要做针对成熟度检测的增强策略YOLOv8默认开启了马赛克、随机仿射、HSV扰动等增强小数据集上这些增强能明显提升泛化能力。但荔枝成熟度检测有一个特殊点颜色是核心判据。半红这个类别完全靠绿和红的比例区分如果HSV增强里的色调和饱和度变化幅度太大会把红荔枝扰成橙荔枝、绿荔枝扰成黄荔枝反而模糊类别边界。我建议做两件事一是把HSV增强的强度调低尤其是hsv_h和hsv_s保留hsv_v亮度变化为主二是自己加一组亮度对比度增强模拟果园里不同时段的光照。在Ultralytics的配置里通常这样改hsv_h: 0.01 hsv_s: 0.3 hsv_v: 0.5 scale: 0.5 fliplr: 0.5 mosaic: 0.8这里hsv_h调得很低是为了防止色相偏移打乱红/绿判定hsv_v保留较大幅度来模拟顺光逆光变化。mosaic保留0.8但如果你发现训练早期loss降不下去可以把mosaic降到0.5因为四图拼接会让小数据集上的样本分布变化太剧烈有些图片里的荔枝甚至被截掉大半。补充一个实践细节增强策略可以按类别来调。半红类别因为样本少可以给它单独做一点裁剪或缩放增强而绿和红类别保持默认。虽然YOLOv8的增强配置是全局的但你可以通过喂入数据时复制少数类样本的方式变相提高少数类在增强中的出现概率。注意数据增强不是越多越好。579张图的数据集增强太猛会让模型看到大量失真样本经常表现为训练loss降到一定程度就卡住不动验证指标也跟着停滞。这时候把增强强度降一档往往立竿见影。5. 荔枝成熟检测避坑指南5个让人翻车的真实问题下面的问题我在农业检测项目里不止一次遇到过每一条都按“现象→原因→解决”来写基本覆盖了小数据集训练成熟度模型时最容易翻车的地方。5.1 现象训练前10轮loss不降或者剧烈震荡新数据集上经常遇到这种情况loss一直挂在5到7之间epoch之间的波动肉眼可见模型看起来完全没在学。原因通常有两个一是学习率初始值太大优化器在损失面里跳来跳去二是labels目录里混入了空标注文件也就是某张图没有对应txt或者txt内容为空模型在这些样本上拿到的是负样本噪声。解决方法是先统计空txt文件数量把空文件对应的图片从训练集里剔除然后用小学习率重新跑比如在命令里加lr00.001。YOLOv8默认lr0是0.01对579张图这种小规模数据集其实偏高直接降到0.001能解决大部分不收敛的问题。排查时先看日志里前10个epoch的box_loss和cls_loss曲线如果cls_loss完全不动而box_loss在降问题多半在标注或类别定义如果两个loss都在震荡优先调低学习率。5.2 现象类别标签错乱绿色果实被模型判成红色训练过程一切正常loss也降了但验证结果里明显看到模型把绿荔枝成片地判成红荔枝。最常见的原因就是转换脚本里的class_names顺序和data.yaml里names的顺序不一致。比如转换时用的是[red, green, half_red]yaml里写的是[green, red, half_red]那么所有标注的类别索引全部错位。解决办法其实不复杂但很考验细心程度统一转换脚本、yaml、训练代码三处的类别顺序转换后随机抽5个txt文件打开看txt里的class_id再打开对应的xml看name字段人工核对每一行是否对应。为了降低这类风险我建议在目录里固定一份class_names.txt把类别顺序写死所有脚本都从这份文件读类别而不是各自维护一份列表。这个习惯看起来笨但在2到3个类别的小项目里确实能救命。5.3 现象半红样本几乎全部被漏检或误判半红类别的样本数量本来就少模型容易把它当成过渡状态既不往红上靠也不往绿上靠表现为验证集上半红类别的precision和recall都明显低于另外两类。原因有两个层面一是样本数量不足模型见过的半红实例太少二是标注标准不统一标注员A认为果面30%变红就算半红标注员B认为必须一半以上变红才算边界样本的标注互相矛盾模型很难学到稳定特征。我的建议是先把所有半红样本拉出来重新过一遍原图按统一标准重新标注边界样本。如果时间不允许至少把分歧严重的样本剔出训练集保留标注置信度高的样本再用重复采样补充半红类别的出现频次。如果真的不想重标还有一种退路把半红和目标颜色最接近的类别合并比如把半红并入红把3类检测降成2类检测。这种操作适合业务只关心红不红、不需要精确区分半红的场景。5.4 现象验证集mAP很高到新场景里几乎失效这是小数据集过拟合的典型表现验证集mAP能到0.8以上但把模型拿到另一片果园或另一天拍的视频上检测框数量锐减置信度全部掉到0.3以下。原因通常是训练图和验证图来自同一场景模型的底层特征更多依赖背景纹理而不是荔枝本身的颜色和形状可以直接理解成把背景记住了。解决方法是重新划分数据集或新增外部数据确保验证集里的果园、树和拍摄角度尽可能和训练集没有重叠。另一个验证技巧是挑几段不同时间段拍摄的视频做抽帧测试静态图片集测不出场景泛化能力。快速验证过拟合的方法是用模型跑训练集自己如果训练集mAP接近1.0而验证集mAP明显低于训练集过拟合基本坐实。这种时候增加数据多样性比增加模型复杂度更有用比如补充不同果园、不同光照、不同拍摄距离的图片。5.5 现象训练能跑但画出来的框位置偏左上或右下这类问题的典型场景是模型能检出目标但可视化时框和目标有系统性偏移。原因几乎都出在坐标归一化环节转换脚本里如果用了全局平均的图片宽高而不是每张xml里size字段的宽度高度那么分辨率不一致时框就会整体偏移。解决方式是检查转换脚本确认读的是当前xml的size值并加一轮全量可视化抽检。如果用我前面给的脚本计算x_center和y_center时都用的是img_w和img_h这个bug天然规避掉了。但如果是手工改过或半自动生成的标注必须复查这一步。再补充一个检查点如果txt坐标都在0到1之间但画框位置整体偏移注意看是不是归一化时x用了width、y用了height但坐标计算时乘反了。比如把x_center乘了图像高度框就会在竖直方向偏。这类手误很常见可视化抽检是最好的防线。6. 让模型更贴近果园现场两类数据重采样与一个验证技巧当你把上面这套流程跑完、模型在验证集上mAP也能看之后别急着收工。579张图训练出来的模型离真正到果园里扛住各种光照变化还有距离。这里分享一个我常用的收尾技巧先把全部样本按场景维度重新组织然后做两类重采样。第一类是困难样本重采样。把模型预测置信度低于0.5的样本全部挑出来人工确认是不是错标或特殊光照样本。这份数据里最容易出问题的往往是逆光下拍的半红荔枝颜色失真严重模型置信度天然就低。把这些样本复制三份放回训练集再做一次微调比直接加训练轮数有效得多因为模型看到的是它最不擅长的样本收敛方向更明确。第二类是验证集场景分桶。不要只保留一个验证集而要把图片按光照条件分桶顺光、逆光、阴影、雨天共四桶分别跑mAP并记录。这样你会发现验证集总分也许不错但逆光桶的mAP可能只有0.3。找到短板桶之后把对应样本挑出来做亮度增强微调效果提升肉眼可见。如果某些桶里样本太少至少做一个正检率抽样检查记录漏检框个数为后续补数据提供依据。验证技巧上用视频抽帧代替静态图集。拿手机在果园拍一段30秒视频抽帧50张加进验证集跑一遍。静态数据集容易让人高估模型现场表现视频抽帧会暴露目标在不同角度、不同遮挡程度下的漏检。我有一个习惯最终交付前一定会做一次视频抽帧测试因为真的在果园里翻过车——当时静态验证mAP有0.86到了现场视频里漏掉了一半小目标。这套数据集本身质量不错VOC和YOLO双格式也省事但数据量就摆在那里不要指望一次训练出完美模型多做两轮样本筛选和重采样比换更大的模型更划算。希望这些经验能帮你少走弯路也祝你的荔枝成熟检测项目顺利落地。本文还有配套的精品资源点击获取
返回列表