
简介这份咖啡叶片检测数据集面向目标检测方向的学习者与算法工程师适用于yolov5、yolov7、yolov8、yolov9、yolov10、yolo11等主流YOLO系列模型可直接用于模型训练、验证与测试。资源共2000个文件包含999张jpg叶片图像、1000个txt标注文件以及1个yaml配置文件压缩包整体约24.53MB已按常用结构划分好数据集省去手动整理与划分的步骤。标签采用YOLO标准格式每行记录类别索引及归一化后的目标框中心点坐标、宽度和高度清晰规范yaml文件则定义了类别名称与数据集路径配合主流YOLO框架即可快速启动实验。对于需要开展咖啡叶片检测、农业目标识别或对比不同YOLO版本性能的读者来说这份数据集能帮助节省标注和预处理时间聚焦模型调参与效果优化也适合作为课程设计或算法验证的配套数据。目前已有57人学习下载可作为入门与实践的参考数据使用。1. 咖啡叶片检测为什么绕不开YOLO1000张图能做什么咖啡种植园里最贵的人工巡检正在被目标检测模型一步步替代。但当你拿到一份「咖啡叶片检测数据集1000张图像带标签」的压缩包时事情远没有解压、训练、收工这么简单。1000张图不是大数据量可如果每张图里都密集分布着健康叶和带病斑的叶片这个规模已经足够微调出一个能下地的YOLO模型前提是把标签格式、目录结构、训练参数的每一步都走对。这篇笔记就从这套数据集出发覆盖数据校验、训练、验证、避坑到导出ONNX的完整路径。适合刚拿到数据准备开训的算法工程师也适合正在评估这个方向值不值得投入的技术负责人。2. 拆解数据集包从zip到YOLO可用的目录结构2.1 先确认标签格式是YOLO的txt还是VOC的xml拿到压缩包第一件事不是急着解压跑训练而是确认里面的标注格式。YOLO系列的官方训练接口ultralytics支持三种标签格式YOLO txt格式、VOC xml格式、COCO json格式。其中txt格式最直接因为框架默认就按txt读取每行对应一个目标框五个数字依次是类别id、归一化中心点x、归一化中心点y、归一化宽度w、归一化高度h。解压后我一般先执行这样的命令unzip yolo算法-咖啡叶片检测数据集-1000张图像带标签-叶子testing-detection-zsmzd.zip -d coffee_leaf/ cd coffee_leaf find . -maxdepth 3 -type f | head -30这个命令把压缩包解压到coffee_leaf目录然后用find列出前三层目录里所有文件的前30个。通过这一步能快速看出数据集的组织方式如果看到images和labels两个兄弟目录说明标签已经按YOLO格式组织好如果看到JPEGImages和Annotations那是VOC风格的老目录结构需要额外做格式转换。判断标签到底是检测框还是分割掩膜有个小技巧用wc -l统计每个txt文件的行数再对比对应图片里肉眼可见的叶片数量。如果行数和叶片数大致吻合说明是检测框如果一行数据里有几十上百个坐标点那可能是实例分割标签需要换YOLOv8-seg来训。咖啡叶片这种场景检测框一般够用分割反而在叶面积估算时才更有优势。2.2 标签坐标系检查归一化坐标为什么常翻车YOLO txt格式的坐标是归一化到0-1之间的相对坐标中心点x除以图片宽度框宽也除以图片宽度。最常翻车的情况是脚本生成标签时用了绝对像素坐标却忘了做归一化。这种错误不影响文件被读取但训练时loss会一直震荡mAP曲线反复横跳看起来像玄学。写一个快速校验脚本把某张图的标签坐标还原成像素坐标并画在原图上import cv2 img cv2.imread(images/train/leaf_001.jpg) h, w img.shape[:2] with open(labels/train/leaf_001.txt) as f: for line in f: cls, cx, cy, bw, bh map(float, line.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, str(int(cls)), (x1, y1 - 5), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 1) cv2.imwrite(check_leaf_001.png, img)这段代码的核心逻辑是把归一化的cx、cy、bw、bh乘回图片真实宽高得到矩形框的左上角和右下角像素坐标然后绘制到原图上。如果框的位置和叶片完全重合说明坐标系没问题如果框整体偏到角落或者大小明显不对那就是归一化没做或者类别id映射错了。对1000张图的数据集抽样检查10到20张就够了重点是覆盖不同光照、不同角度和不同病斑程度的图片。我也习惯顺便把类别id打印出来确认一遍看0和1分别代表什么。不少数据集的类别定义不写README只在文件名或父目录名里暗示。这种时候类别顺序搞反了模型训完等于白训推理阶段的类别名称全都会错位。2.3 目录结构统一一份可以直接喂给ultralytics的布局ultralytics的YOLOv8训练接口对数据集目录结构有固定要求根目录下必须有images和labels两个兄弟目录各自再按train和val分子目录。图片和标签的文件名必须一一对应主名一致而后缀可以不同。很多从网上下载的数据集不是这种布局需要做一次重组。我常用的重组脚本先建目录骨架mkdir -p coffee_leaf_yolo/images/{train,val} mkdir -p coffee_leaf_yolo/labels/{train,val}然后按8比2比例把图片分到train和val目录对应的txt标签同步复制到labels目录下。对1000张图的数据集我倾向于不额外划分test集把val集当测试集用。再拆三份会让每份都太小训练集不足会导致模型欠拟合。这里有个分工细节容易被忽略val集用于训练过程中每轮结束后的指标评估主要用来观察过拟合test集是模型定稿后才碰的数据用来估算真实泛化性能。小数据集上把val和test合并是务实的选择把更多样本留给训练同时靠早停和更强的数据增强控制过拟合风险。3. 用YOLOv8在本地跑通咖啡叶片检测从环境到训练日志3.1 环境准备conda虚拟环境与最小依赖训练咖啡叶片检测模型不需要多豪华的配置一张8GB显存的显卡就够跑YOLOv8s只有CPU也能训但速度会慢到影响调参节奏。我习惯先用conda建一个干净的环境避免和已有的TensorFlow或旧版PyTorch打架conda create -n coffee_yolo python3.10 -y conda activate coffee_yolo pip install ultralytics opencv-pythonpython3.10是ultralytics当前稳定支持的版本区间3.11和3.12在部分旧显卡驱动场景下偶尔会有编译兼容问题。opencv-python是推理和可视化必需的ultralytics虽然装了依赖项里也带opencv但显式安装一次能避免版本被其他包覆盖。装完后用python -c import ultralytics; print(ultralytics.version)确认安装成功。后续还涉及数据集路径管理。因为文件比较多我建议把数据集和训练代码放在同一个用户目录下并用相对路径在data.yaml里引用。这样换机器跑不用改一堆绝对路径也方便把整套流程复制给同事复现。3.2 写data.yaml小数据集的第一个关键文件YOLOv8训练时用data.yaml描述数据集位置和类别信息。这个文件格式非常固定写错一个字段训练直接报错。# coffee_leaf.yaml path: ../coffee_leaf_yolo train: images/train val: images/val nc: 2 names: 0: healthy_leaf 1: rust_leafpath字段是数据集根目录相对于data.yaml文件位置的相对路径。这里把data.yaml放在训练代码目录下数据集在上一级的coffee_leaf_yolo目录所以写../coffee_leaf_yolo。train和val字段写的是images目录下的子目录名即可ultralytics会基于path字段做拼接。nc是类别总数names的id顺序必须和标签txt里的编号一一对应这里假设0是健康叶片、1是叶锈病叶片。如果数据集只标了叶子这一个类别把nc改成1names底下只写一个leaf就行。data.yaml里的names顺序会影响训练日志的类别显示名但不影响训练效果本身。真正影响效果的是标签txt里的id。如果标签里id0原本代表锈病叶而在这个文件里把0写成了健康叶训练照样能跑但val阶段的混淆矩阵是错的推理时也会把类别张冠李戴。3.3 启动训练命令、参数与日志解读环境就绪、data.yaml写好后训练命令比想象中短cd coffee_yolo yolo detect train \ modelyolov8s.pt \ datacoffee_leaf.yaml \ epochs100 \ imgsz640 \ batch16 \ patience20 \ projectcoffee_leaf_runs \ nameexp1这条命令加载YOLOv8s的预训练权重在咖啡叶片数据集上微调100个epoch输入图像统一缩放到640x640每批16张如果连续20个epoch验证集mAP没有提升就自动早停所有输出写到coffee_leaf_runs/exp1目录。参数选择上imgsz640是YOLOv8的默认值。对叶片检测来说分辨率太低会漏掉小病斑太高则显存吃紧。显卡在12GB以上可以试imgsz800让小病斑更清晰但batch要相应降到8或更低。batch16是8GB显存跑yolov8s的保守值报CUDA out of memory时先把batch降到8而不是换模型这个顺序能快速判断是显存瓶颈还是配置问题。训练跑起来以后终端每50个batch打印一行日志包含当前epoch、loss值和GPU利用率。真正需要盯的是每轮epoch末尾输出的验证指标precision、recall、mAP50、mAP50-95。如果看到precision和recall在头20个epoch里快速上升、之后趋平说明迁移学习起了作用如果两个值反复震荡先怀疑学习率太高或标注里有噪声而不是急着调模型结构。训练结束后coffee_leaf_runs/exp1目录下会生成weights/best.pt和last.pt还有混淆矩阵、PR曲线、F1曲线等可视化图。best.pt是根据验证集mAP选出的最优权重后续导出和推理都该用它。last.pt是最后一个epoch的权重没有参考价值除非你想继续接着训。4. 训练效果验证与参数调优1000张图怎么训出稳定模型4.1 指标怎么读precision、recall与mAP50-95训练完第一件事是打开confusion_matrix.png和results.png。confusion_matrix里对角线越亮越好如果健康叶片被大量误判为锈病叶说明两类在视觉上过于相似或者标注边界不清晰。results.png里有loss曲线、precision曲线、recall曲线和mAP曲线四组子图。mAP50和mAP50-95是判断模型质量最直接的两个数字。mAP50只计算IoU阈值0.5时的平均精度对定位精度不敏感适合粗看mAP50-95是在0.5到0.95之间取十个IoU阈值算平均更严格能反映框是否框得准。做叶片检测时我一般要求mAP50在0.85以上、mAP50-95在0.6以上才敢拿到田里试。如果mAP50-95明显低于mAP50的一半说明模型框定位不准通常是标签框画得随意或者imgsz太小。还要看precision和recall的平衡状态。precision高但recall低说明模型只捡着把握最大的检漏检多recall高但precision低说明模型把背景和叶片边缘都当成了目标误报多。农业场景里漏检比误报更伤因为漏掉一片病叶可能导致病害蔓延。所以两者不可兼得时我宁愿多花点精力做后处理过滤也要把recall保住。4.2 冻结层训练小数据集的后悔药1000张图直接全量微调YOLOv8s很容易过拟合尤其当数据集拍摄环境单一时。一个有效的策略是两阶段训练先冻结主干网络只训练检测头再解冻全部层用低学习率微调。yolo detect train \ modelyolov8s.pt \ datacoffee_leaf.yaml \ epochs50 \ imgsz640 \ batch16 \ freeze10 \ lr00.005 \ projectcoffee_leaf_runs \ nameexp2_frozen yolo detect train \ modelcoffee_leaf_runs/exp2_frozen/weights/best.pt \ datacoffee_leaf.yaml \ epochs50 \ imgsz640 \ batch16 \ lr00.001 \ projectcoffee_leaf_runs \ nameexp3_unfreezefreeze10表示冻结模型前10层。YOLOv8s的主干网络大约有二十多层冻结前10层相当于保住最底层的边缘和纹理特征提取能力让ImageNet预训练特征不被小数据集带偏只让高层特征去学习咖啡叶片特有的模式。第一阶段能调的参数少学习率可以调到0.005而不会震荡第二阶段参数量变多学习率降到0.001让所有层在稳定状态下协同微调。这种两阶段做法的本质是把1000张图的训练压力集中在教会模型什么是咖啡叶片上而不是让它从头学怎么提取边缘纹理。实际项目里这个操作通常能把mAP50-95提升3到5个百分点代价只是多跑50个epoch性价比很高。不少人在小数据集上直接全量训练导致过拟合回头怪模型不行其实只是没把迁移学习拆开用。4.3 数据增强参数让1000张图变成10000张ultralytics的默认增强策略已经比较完善但对叶片这种形状相对固定、背景又杂的目标可以针对性调整几个参数。我习惯直接在训练命令行里加增强配置yolo detect train \ modelyolov8s.pt \ datacoffee_leaf.yaml \ epochs100 \ imgsz640 \ batch16 \ hsv_h0.02 \ hsv_s0.6 \ hsv_v0.4 \ degrees15 \ translate0.1 \ scale0.3 \ fliplr0.5hsv_h、hsv_s、hsv_v是色调、饱和度、亮度的随机扰动幅度。咖啡叶片的颜色是模型识别的重要特征扰动太大会让叶片颜色失真太小又起不到泛化作用。0.02的色调扰动和0.6的饱和度扰动是经验值配合0.4的亮度扰动可以模拟不同光照条件。degrees15表示图片最多随机旋转15度叶片在自然图像里的朝向没有固定方向这个值放宽到30也没问题。translate和scale分别控制平移比例和缩放比例模拟不同拍摄距离下叶片大小和位置的变化。数据增强的作用不仅是提升鲁棒性更是在间接扩大数据集规模。同样的1000张图每个epoch经过不同的随机变换模型看到的是大量变体等效于把训练集扩大了一个数量级。但要注意增强不是万能药标注框本身画偏了的话再怎么增强都是放大错误。标注质量决定模型的下限增强只是在撑上限。5. 咖啡叶片检测的踩坑实录从标签到推理的五个典型问题5.1 训练loss不降反升标签坐标系被写成了像素值现象训练前10个epoch的box_loss从2.0左右开始不降反升后面一直震荡val mAP基本为0。原因数据集的txt标签里存的是像素坐标没有归一化到0-1。YOLO读取坐标后把它当作归一化值处理框的位置和大小全部偏移模型根本无从学习。解决写脚本批量把像素坐标换算成归一化坐标分别除以图片的宽和高后重新写回txt。换算完抽样画框验证确认框与叶片重合再开始训练。这个坑在网上下载的数据集里出现概率极高很多标注工具默认输出VOC格式的绝对像素坐标打包者转换时漏做了归一化。5.2 验证集mAP高但自己拍的图检测全废光照和背景过拟合现象在数据集划分的val集上mAP50达到0.93但把自己用手机拍的咖啡叶片图喂进去要么漏检要么框乱飘。原因数据集的1000张图可能是同一台相机、同一天、同一个种植区拍摄的背景和光照高度一致。模型学到的是特定背景下的叶片模式不是叶片本身的通用特征。解决训练阶段就预留一部分外部图片做快速验证不要只盯着val集的数字。同时在增强参数里加大hsv_v亮度扰动和translate平移人为破坏背景的统计稳定性。外部验证仍然不行的话最有效的手段是补充不同光照、不同角度、不同背景的图片进训练集。1000张里哪怕只有50张新环境图泛化能力都会有明显改善。5.3 叶片重叠区大面积漏检NMS阈值过严现象单张图上30片叶子只检出25个框漏掉的几乎全是重叠区域的叶子而且被漏掉的框置信度并不低。原因YOLO推理时默认的NMS IoU阈值在0.45左右会对高度重叠的框做抑制。叶片在自然状态下互相遮挡是常态重叠区域的框被当成同一个目标的后选而丢弃这个默认值对密集目标确实偏严格。解决推理时把NMS的IoU阈值调高到0.6yolo detect predict \ modelcoffee_leaf_runs/exp3_unfreeze/weights/best.pt \ sourcetest_images/ \ conf0.25 \ iou0.6IoU阈值调太高会让同一片叶子被重复画两个框所以建议从0.5开始每次加0.05观察漏检和误检的平衡点。对咖啡叶片这种密集场景0.6通常比默认值效果好但不同数据集的最优值不一样只能实测确定。5.4 训练时CUDA out of memory先改batch还是先改imgsz现象训练命令一跑就报RuntimeError: CUDA out of memory或者跑几个epoch后才崩溃。原因batch16和imgsz640同时占用的显存超过显卡容量。YOLOv8s本身的参数量不大但反向传播需要保存中间激活值显存峰值取决于batch大小和图像尺寸的乘积。解决先改batch从16降到8再不行降到4。batch尽量保持2的幂次ultralytics内部部分算子对2的幂次效率更高。如果batch4还不够才考虑把imgsz从640降到512因为图像尺寸降太多会影响小病斑的检测效果。另一个容易被忽略的点是Dataloader的workers数量默认8个worker会预加载大量数据到内存内存不足时报的错可能和显存报错混在一起显式设成workers4能减少干扰项。5.5 训练时间远超预期模型在CPU上跑现象单个epoch的耗时从几十秒变成几分钟训练日志开头显示Device: cpu用nvidia-smi看GPU利用率一直是个位数。原因ultralytics在某些情况下会回退到CPU训练。常见诱因是conda环境里安装的PyTorch是CPU版或者系统里存在多个Python环境yolo命令实际调用的解释器不是装了GPU版PyTorch的那个。很多人以为装了ultralytics就等于自动装好了GPU支持实际不是一回事。解决先确认训练日志顶部的Device字段再检查当前Python环境里torch.cuda.is_available()是否为True。如果为False需要装对应当前CUDA版本的GPU版PyTorch。装完后重新启动训练这一步能省下的是以小时计的白跑时间。6. 从实验到田间导出ONNX模型跑CPU推理训练出来的best.pt是PyTorch格式在开发机上跑没问题。但要部署到不带GPU的田间终端、边缘盒子或Web服务里一般先导出成ONNXyolo export modelcoffee_leaf_runs/exp3_unfreeze/weights/best.pt formatonnx imgsz640导出后生成best.onnx。这个文件是跨框架的标准格式可以用ONNX Runtime、OpenCV DNN或其他推理引擎加载。对农业现场来说一台只有CPU的工业平板就能跑ONNX模型不必背着带显卡的笔记本电脑下地。用ONNX Runtime做推理的代码import cv2 import numpy as np import onnxruntime as ort session ort.InferenceSession(best.onnx) input_name session.get_inputs()[0].name img cv2.imread(field_leaf.jpg) img_resized cv2.resize(img, (640, 640)) blob img_resized[:, :, ::-1].transpose(2, 0, 1).astype(np.float32) / 255.0 blob np.expand_dims(blob, axis0) outputs session.run(None, {input_name: blob})[0] print(outputs.shape)这段代码做了四件事加载ONNX模型、读图并缩放到640x640、把BGR转为RGB并归一化、送入模型拿到输出。输出张量的shape一般是[1, 6, 8400]这样的结构6对应cx、cy、w、h四个坐标加两个类别概率8400是YOLOv8三个尺度特征图上的候选框总数。类别数变成N时中间维度跟着变成4N。注意这里为了演示简洁直接用cv2.resize把图压到640x640实际部署建议用letterbox等比缩放加灰边补齐因为训练时YOLO内部也是用letterbox处理输入的。两者对接近方形的图片差异不大但对瘦长图会有几个点的精度波动。推理时置信度阈值conf调到0.25比较合适太低会出一堆假框农业场景的假框直接影响防治决策。输入尺寸也要和训练时的imgsz保持一致训练用640推理用416精度会掉得莫名其妙。我自己的习惯是每次部署完都先拿当天在田里拍的20到30张图跑一遍记录每张图的检测结果人工复核后把出错图挑出来补进训练集。这个闭环是我做农业视觉项目最依赖的一环。1000张带标签的数据集只是起点模型是在使用中慢慢养大的。希望这篇笔记能帮你在咖啡叶片检测这个方向上少走几段弯路。本文还有配套的精品资源点击获取