基于YOLO的茶树芽检测:100张图小数据集训练与部署实战
发布时间:2026/9/28 17:16:53来源:尧图网络
简介本资源为面向YOLO系列目标检测算法的茶树芽检测数据集适用于农业视觉识别、茶芽生长监测等场景可帮助初学者与算法工程师快速搭建训练与验证流程。包内共201个文件包含100张jpg图像、100个txt标注文件及1个yaml配置文件压缩包约6.59MB图像与标签一一对应yaml文件用于定义数据集路径与类别信息标签采用归一化中心点与宽高格式可直接用于yolov5、yolov8、yolov9、yolov7、yolov10及yolo11等模型训练也可转换为VOC格式。数据集已划分好训练与验证集省去预处理环节适合作为课程设计、科研实验或算法对比的基准数据。目前已有234人学习下载读者可借此快速验证模型在茶芽检测任务上的表现并在此基础上进行数据增强或迁移学习。1. 茶树芽检测为什么值得用 YOLO 啃100 张图的小数据集能跑出什么茶园里采茶最头疼的不是没茶可采而是分不清哪一芽能采、哪一芽还得等。一芽一叶、一芽二叶、单芽等级差一档收购价能差出三成。人工分拣靠眼力一天下来眼睛发花漏检和误采全凭运气。茶树芽检测数据集配 YOLO 算法解决的正是这个「把嫩芽从老叶背景里抠出来」的问题。标题里这份 tea-shoot-detection 数据集只有 100 张带标签图像规模不大但恰好卡在一个很实用的位置够跑通 YOLO 训练全流程够验证一个茶芽检测想法能不能立住也够让新手把数据标注、格式转换、训练调参、推理部署这条链路完整走一遍。它适合两类人——想入门目标检测但被 COCO 那种大工程劝退的开发者以及手里有茶园图像、想先拿小样本试水再决定要不要扩标的农业技术团队。100 张图不是终点是探路成本最低的起点。2. 从 100 张图到可训练数据集茶芽标注与 YOLO 格式转换2.1 茶芽检测的类别定义与标注边界拿到 100 张茶树芽图像第一件事不是急着喂给模型而是把「什么算一个茶芽」定死。茶芽检测最常见的类别划分有三种单芽、一芽一叶、一芽二叶。如果数据集只标一个 tea-shoot 类那标注框就只圈最顶端那个嫩芽如果分三级每个框的边界就要严格按叶位切。我一般建议小数据集先做单类原因很直接——100 张图分三类每类平均三十来张YOLO 的每个类别分支都吃不饱混淆矩阵会糊成一团。标注工具用 LabelImg 或 X-AnyLabeling 都行导出格式选 YOLO txt。每张图对应一个同名 txt每行格式是class_id x_center y_center width height全部归一化到 0 到 1 之间。这里有个血泪经验茶树芽在图像里往往偏小标注框如果贴得太紧训练时数据增强一裁剪芽就被切没了。框可以比芽的实际边缘外扩 2 到 3 个像素给增强留余量。标注完要检查两件事一是有没有漏标二是框的宽高有没有为 0 的异常值。漏标会让模型学到「这里不是芽」的错误信号零宽高框则会在计算损失时直接报 NaN。2.2 目录结构与 data.yaml 配置YOLO 系列对目录结构有固定期待。100 张图按 8:1:1 切分训练 80 张、验证 10 张、测试 10 张。目录这样摆tea_shoot_dataset/ ├── images/ │ ├── train/ # 80 张 jpg │ ├── val/ # 10 张 jpg │ └── test/ # 10 张 jpg ├── labels/ │ ├── train/ # 80 个 txt │ ├── val/ # 10 个 txt │ └── test/ # 10 个 txt └── data.yamldata.yaml 是训练入口内容如下path: ./tea_shoot_dataset train: images/train val: images/val test: images/test nc: 1 names: 0: tea_shootpath写数据集根目录train/val/test写相对路径。nc是类别数单类就写 1。names的键从 0 开始和标注 txt 里的 class_id 一一对应。这里翻车最多的地方是路径层级——有人把 path 写成绝对路径换台机器就找不到有人 train 写成images/train/带尾斜杠某些版本会解析出空列表。写完 yaml 后跑一行 Python 验证图像和标签能对上import os img_dir ./tea_shoot_dataset/images/train lbl_dir ./tea_shoot_dataset/labels/train imgs {os.path.splitext(f)[0] for f in os.listdir(img_dir)} lbls {os.path.splitext(f)[0] for f in os.listdir(lbl_dir)} print(图像数:, len(imgs), 标签数:, len(lbls)) print(缺标签的图:, imgs - lbls) print(缺图的标签:, lbls - imgs)这段代码做集合差运算输出为空才说明配对完整。如果imgs - lbls有值说明有图没标lbls - imgs有值说明有标签文件但原图丢了。两种情况都会让训练中途报错提前查比训练到一半崩掉省事。2.3 小样本下的数据增强策略100 张图直接训模型见过的角度、光照、遮挡太少验证集精度会虚高换一批图就崩。YOLO 内置增强够用但参数要按茶芽场景调。默认的 mosaic 增强把四张图拼一张对小目标检测有帮助但茶芽本身占比小拼完可能只剩几个像素。我一般把 mosaic 概率从 1.0 降到 0.5同时开 mixup 到 0.1让模型别太依赖拼接后的上下文。HSV 增强里色调偏移hsv_h设 0.015 就够茶树芽的绿色调变化不大调猛了反而让模型把黄叶当芽。饱和度hsv_s和明度hsv_v可以给到 0.7 和 0.4模拟阴天、逆光、露水反光这些茶园常见光照。缩放scale设 0.5允许图像随机缩放一半提升对远近芽的适应。翻转flipud和fliplr都开 0.5茶树芽没有固定朝向上下左右翻都合理。注意增强参数写在训练命令里还是写进 yaml取决于 YOLO 版本。较新版本支持在 data.yaml 同级放hyp.yaml老版本只认命令行参数。不确定时先跑一轮默认参数看训练日志里增强是否生效。3. YOLO 训练茶芽检测模型参数怎么设、日志怎么看3.1 选 YOLOv8 还是 YOLOv5小数据集的取舍茶芽检测这种 100 张图的小任务选模型不是越新越好。YOLOv8 的 anchor-free 头对小目标更友好但默认超参是按 COCO 规模调的小数据集上容易过拟合。YOLOv5 的 anchor 机制在茶芽这种固定形状目标上反而稳而且社区里小数据集的调参经验多遇到问题搜得到。我的做法是先用 YOLOv8nnano 版跑一轮基线看验证集 mAP50 能不能过 0.6。能过就继续用 v8 调过不了换 YOLOv5s 对比。nano 版参数量小100 张图不至于把它喂撑。如果显存够v8s 比 v8n 多一层特征融合茶芽这种小目标召回会好一点但训练时间翻倍100 张图下差距不明显。预训练权重直接用官方 COCO 权重。有人觉得茶芽和 COCO 类别不搭预训练没用——这是误解。COCO 里虽然没有茶芽但模型在预训练阶段学到的边缘、纹理、颜色对比特征对茶芽检测照样管用。从零训 100 张图mAP 大概率停在 0.3 以下。3.2 训练命令与关键参数逐项说明YOLOv8 的训练命令长这样yolo detect train \ data./tea_shoot_dataset/data.yaml \ modelyolov8n.pt \ epochs200 \ imgsz640 \ batch8 \ lr00.01 \ lrf0.01 \ patience50 \ device0 \ projecttea_shoot_runs \ nameexp1epochs200对小数据集不算多因为每轮见过的样本少需要更多轮次收敛。imgsz640是 YOLO 默认输入尺寸茶芽在原图里可能只占几十像素640 下缩得更小如果发现漏检严重可以提到 1024但显存和速度要重新评估。batch8是 100 张图下的保守值显存 8G 以上可以试 16。lr00.01是初始学习率小数据集上可以降到 0.005避免早期震荡。lrf0.01是最终学习率系数和余弦退火配合让学习率从 0.01 平滑降到 0.0001。patience50表示验证集指标 50 轮不提升就早停防止过拟合。训练日志里重点盯三个数box_loss、cls_loss、mAP50。box_loss 管框的位置准不准cls_loss 管类别判得对不对。两个 loss 都该稳步下降如果 box_loss 降但 cls_loss 不降说明框找到了但类别分不清可能是标注类别不一致。mAP50 是 IoU 阈值 0.5 下的平均精度茶芽检测能到 0.7 以上算可用0.5 到 0.7 之间需要看具体漏检在哪。3.3 训练曲线与混淆矩阵的读法训练完在tea_shoot_runs/exp1/下会生成results.png、confusion_matrix.png、val_batch0_pred.jpg这些文件。results.png 里横轴是 epoch纵轴是各项指标。重点看 train 和 val 的 loss 曲线是否同步下降——如果 train 一直降而 val 平了甚至翘头就是过拟合需要加增强或减模型容量。混淆矩阵在单类检测里看着简单但有个坑YOLO 输出的混淆矩阵默认包含背景类。如果背景列的值很高说明模型把大量背景误判成茶芽也就是误检多。这时候要看val_batch0_pred.jpg里的预测框是不是把老叶、茶梗也框进去了。如果是回去检查标注里有没有把非芽区域误标或者降低置信度阈值再观察。提示YOLO 混淆矩阵在不同版本里归一化方式不同有的按行归一化有的按列。看之前先确认坐标轴标签否则会把召回和精确率读反。4. 茶芽检测推理与部署从单张图到视频流4.1 单张图像推理与置信度阈值调优训练完拿测试集里的图跑推理from ultralytics import YOLO model YOLO(tea_shoot_runs/exp1/weights/best.pt) results model.predict( source./tea_shoot_dataset/images/test, conf0.25, iou0.45, saveTrue, projecttea_shoot_infer, nametest_run ) for r in results: print(r.path, 检测到, len(r.boxes), 个茶芽)conf0.25是置信度阈值低于这个值的框直接丢掉。茶芽检测里这个值很关键设高了漏检嫩芽设低了老叶误检。我一般从 0.25 起步看val_batch0_pred.jpg里漏了哪些、多了哪些再以 0.05 为步长调。iou0.45是 NMS 的 IoU 阈值两个框重叠超过 45% 就只留置信度高的那个。茶芽密集时这个值可以提到 0.5 到 0.6避免相邻芽被误合并。推理结果里每个 box 有xyxy坐标、conf置信度、cls类别。如果要做采摘决策可以按置信度排序只取前 N 个高置信芽或者按框的中心点位置判断哪一芽最靠顶端。4.2 视频流推理与帧间去重茶园实际场景是摄像头连续拍单帧检测会有闪烁——同一芽这帧检出、下帧丢了。处理视频流时除了逐帧推理还要做帧间关联。简单做法是用 IoU 匹配相邻帧的检测框IoU 超过 0.5 认为是同一个芽用卡尔曼滤波平滑它的位置。这样输出的芽位置稳定不会跳来跳去。import cv2 from ultralytics import YOLO model YOLO(tea_shoot_runs/exp1/weights/best.pt) cap cv2.VideoCapture(tea_garden.mp4) while cap.isOpened(): ret, frame cap.read() if not ret: break results model.predict(frame, conf0.3, verboseFalse) for box in results[0].boxes: x1, y1, x2, y2 map(int, box.xyxy[0]) cv2.rectangle(frame, (x1, y1), (x2, y2), (0, 255, 0), 2) cv2.imshow(tea shoot, frame) if cv2.waitKey(1) 0xFF ord(q): break cap.release() cv2.destroyAllWindows()这段代码把每帧的检测框画出来。verboseFalse关掉每帧的日志输出否则控制台刷屏。实际部署时把cv2.imshow换成推流或存盘帧率取决于模型大小和硬件。YOLOv8n 在普通 GPU 上跑 640 输入能到 60 FPS 以上够实时。4.3 模型导出与边缘设备部署如果要把模型放到茶园边缘设备上导出 ONNX 或 TensorRT 能提速。YOLOv8 导出命令yolo export modeltea_shoot_runs/exp1/weights/best.pt formatonnx imgsz640导出后在 ONNXRuntime 里加载推理不依赖 PyTorch内存占用小一半。如果设备是 Jetson 系列再转 TensorRTFP16 量化后速度能再提一倍。量化时注意校准集要用茶芽图别拿 COCO 图校准否则茶芽这种小目标的精度掉得厉害。注意导出 ONNX 时imgsz要和训练时一致训练用 640 导出也用 640。改了尺寸anchor 或特征图对不上检测框会整体偏移。5. 避坑与排查100 张图训练茶芽检测的 5 个翻车现场5.1 现象训练 loss 正常下降但验证集 mAP 始终为 0原因通常是标签格式不对。YOLO 要求 class_id 从 0 开始有人从 1 开始标模型学到的类别索引和 names 对不上验证时全部判错。另一个可能是归一化坐标算错x_center 或 y_center 超出 0 到 1 范围YOLO 会直接忽略这些框。解决用脚本抽查几个标签文件确认 class_id 是 0坐标都在 0 到 1 之间。如果坐标是像素值没归一化除以图像宽高重新生成。5.2 现象训练到一半报 NaN loss茶芽标注框宽高为 0 是常见诱因。标注时手抖点两下同一个位置生成的框宽高就是 0计算 IoU 时分母为零loss 变 NaN。另外学习率设太大早期梯度爆炸也会 NaN。解决跑一遍标签检查脚本过滤掉宽高小于 1 像素的框。学习率从 0.01 降到 0.005 或 0.001 再试。5.3 现象验证集精度很高但换一批茶园图就检测不到100 张图如果全来自同一片茶园、同一个时间段模型学到的是那片茶园的光照和背景特征换片茶园就失效。这不是模型问题是数据分布问题。解决如果条件允许采集不同茶园、不同天气、不同时段的图哪怕每类只加 20 张泛化性也会明显提升。实在加不了就在增强里加大 HSV 和亮度扰动逼模型学茶芽本身的形状和纹理而不是背景。5.4 现象推理时同一芽被框了好几次NMS 的 IoU 阈值设太高相邻的重复框没被合并。茶芽密集时一个芽可能被多个 anchor 同时命中NMS 阈值 0.45 不够要提到 0.55 甚至 0.6。解决调iou参数从 0.45 逐步提到 0.6观察重复框是否减少。同时看conf是不是设太低低置信度的冗余框也会导致重复。5.5 现象训练速度极慢一张图要好几秒imgsz设太大是主因。640 换成 1280计算量翻四倍。另外batch太小GPU 利用率上不去也会显得慢。还有人忘了开amp自动混合精度FP32 跑比 FP16 慢一倍。解决确认imgsz是否必要那么大茶芽检测 640 通常够。batch调到显存允许的最大值。训练命令加ampTrueYOLOv8 默认开老版本要手动加。6. 小数据集茶芽检测的进阶技巧伪标签与主动学习100 张图训出来的模型直接上线肯定不够。但它的价值在于能当「预标注器」用——这就是伪标签和主动学习的思路。先用这 100 张图训一个基线模型拿它去推理未标注的茶园图把高置信度的检测框导成 YOLO 标签人工只做修正标注效率能提三到五倍。修正后的新数据加进训练集再训一轮模型精度涨一截再拿去标更多图形成循环。具体操作用基线模型对 500 张未标注图跑推理conf设 0.5 以上只保留高置信框。导出标签时用 YOLO 的save_txtTrue每个图的检测结果存成 txt。然后人工过一遍删掉误检、补上漏检。这批修正后的图按 8:1:1 并入原数据集重新训练。第二轮模型因为见过更多场景mAP 通常能涨 5 到 10 个点。主动学习的关键是选哪些图给人工标。不是随机选而是选模型「最不确定」的图——比如检测框置信度在 0.3 到 0.5 之间的图或者同一芽在不同帧里置信度波动大的图。这些图信息量最大标一张顶随机标十张。实现上可以按平均置信度排序优先标置信度低的。策略标注量预期 mAP50适用阶段仅用 100 张原图1000.60-0.70基线验证伪标签 人工修正 200 张3000.72-0.80快速扩标主动学习选 100 张难例2000.75-0.82精度攻坚全量人工标 500 张5000.80-0.88上线部署这个循环跑两三轮数据量到 300 到 500 张茶芽检测模型基本能到可用状态。再往上堆数据边际收益递减除非引入更难的场景——比如雨天、强逆光、芽叶粘连。我自己踩过的坑是第一轮伪标签conf设太低0.2 就导结果误检框全进了训练集第二轮模型反而更差。后来固定conf不低于 0.5且人工必须过一遍才稳定涨点。小数据集做检测数据质量比数量重要100 张标得准的图比 500 张标得糊的图管用。希望帮到你。本文还有配套的精品资源点击获取
网站建设高端定制企业官网