ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

药品板蓝根颗粒检测:110张VOC+YOLO数据集训练与避坑指南

药品板蓝根颗粒检测:110张VOC+YOLO数据集训练与避坑指南 简介这份数据集面向计算机视觉开发者与药品检测场景旨在解决板蓝根颗粒袋装产品的自动识别与定位问题。资源采用Pascal VOC与YOLO双格式标注并保留原始JPG图片能够直接用于YOLO系列、SSD、Faster R-CNN等主流目标检测模型的训练与评估。压缩包共335个文件包含111张JPG图片、111个XML标注文件和113个TXT文件整体大小仅3.71MB轻量易用适合快速验证检测流程或作为教学示例。标注内容覆盖两个类别999ganmaoling与banlangen共134个目标框类别区分明确所有标注均由labelImg工具完成格式规范便于二次整理或迁移。目前这份数据集已有121人学习使用对需要扩充药品数据集的算法工程师、相关专业学生以及药品盘点系统开发者均有参考价值也可作为数据增强与模型调优的基础语料能帮助使用者更高效地完成目标检测模型迭代。1. 药品板蓝根颗粒检测数据集110张图能做什么先别急着删做目标检测的同行看到“110张”这个数字第一反应多半是“这也太小了”。但板蓝根颗粒识别这个任务难点不在数据量而在目标本身——颗粒小、颜色接近背景、密集堆叠且相互遮挡属于典型的小目标密集检测场景。这类场景下即便给你几千张图标注质量跟不上训练照样过拟合。110张VOCYOLO双格式标注数据配合预训练权重和数据增强足够跑通一个能用的检测基线用于药品包装质检、药房库存盘点、说明书防错漏装等场景的前期验证。本文讲清楚这套数据怎么解压、怎么训练、坑在哪以及哪些情况不值得往里投入时间。2. 从zip到能训练的数据VOC与YOLO双格式的目录结构和标注关系2.1 拿到压缩包先看目录骨架VOC格式与YOLO格式的组织差异解压前先别急着双击Linux下用命令行处理更稳。zip格式在Windows上解压可能嵌套出一层同名目录训练脚本一跑就报“路径找不到”这种问题在数据集上反复出现。unzip 药品板蓝根颗粒检测数据集110张VOCYOLO格式.zip -d ./banlangen解压后看目录结构典型做法是数据集内同时存在VOC风格和YOLO风格的目录分别命名类似VOC2007和YOLOFormat。VOC风格的核心是AnnotationsXML标注、JPEGImages原图、ImageSets/Main训练/验证划分YOLO风格的核心是images原图和labelstxt标注。两套目录共享同一批图片只是标注文件格式不同。你用LabelImg或其他打标工具导出的格式取决于保存选项但这份数据集直接给了双份省去转换步骤。先核对图片和标注数量是否一一对应这是老手拿到数据集的第一个动作find ./banlangen -name *.xml | wc -l find ./banlangen -name *.jpg | wc -l如果数量对不上后面训练会出现“找不到标签”的报错。110张图不算多目测检查一遍也能全部过目但数量核对命令始终比肉眼可靠。提示解压后先看README或数据说明文件如果有里面通常写了类别名称、标注规范和图来源。没有说明文件时用file或图片查看器抽查几张图确认标注内容与图像内容一致。2.2 VOC的XML标注与YOLO的txt标注逐字段对照VOC格式的XML标注核心块长这样annotation folderJPEGImages/folder filenameIMG_0001.jpg/filename size width640/width height480/height depth3/depth /size object namebanlangen_granule/name bndbox xmin100/xmin ymin80/ymin xmax260/xmax ymax220/ymax /bndbox /object /annotation对应的YOLO格式txt文件内容如下一行一个目标0 0.28125 0.3125 0.25 0.29167坐标转换关系是x_center (xmin xmax) / 2 / widthy_center (ymin ymax) / 2 / heightw (xmax - xmin) / widthh (ymax - ymin) / height。以640x480为例上面的xmin100、xmax260对应(100260)/2/6400.28125宽度(260-100)/6400.25数值能对上。VOC与YOLO互转的关键就在这套归一化公式四舍五入保留5位小数是通用做法。2.3 双格式互转的三个边界点类别ID、归一化分母和截断框格式转换最容易出错的地方有三个。第一个是类别映射VOC的name是字符串YOLO的txt里是整数ID必须提前固定names [banlangen_granule]否则转换时类别ID乱序训练出来的模型检测结果全错。第二个是归一化分母必须用XML里size中记录的长宽如果标注时的基准尺寸和实际图片尺寸不一致转换后坐标会整体偏移检测框全部错位。第三个坑是截断框。板蓝根颗粒在图像边缘被截断的情况很常见xmin、ymax若超出图片边界转YOLO时会出现大于1或小于0的坐标值。YOLO训练时对这类边界框的处理方式各有差异稳妥做法是转换前把所有坐标裁剪到图片范围内。def clamp_xml_to_yolo(xml_path, img_w, img_h): # 读取XML并限制坐标边界 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)) # 过滤掉裁剪后面积过小的框 if (xmax - xmin) 5 or (ymax - ymin) 5: return None # 再按归一化公式输出YOLO格式 x_center ((xmin xmax) / 2) / img_w y_center ((ymin ymax) / 2) / img_h w (xmax - xmin) / img_w h (ymax - ymin) / img_h return f0 {x_center:.5f} {y_center:.5f} {w:.5f} {h:.5f}这段代码里的面积过滤阈值5像素不是随便定的小于5个像素的目标在常见下采样倍数下会直接丢失保留反而会增加无效标签。数据集的110张图如果标注粒度细一个框覆盖几颗粒子这类小框的比例不低清洗时要留意。3. 110张图的训练策略数据划分、增强与小样本模型选型3.1 划分不均衡等于白标train/val/test怎么切才不容易翻车110张图按7:2:1划分训练集77张、验证集22张、测试集11张。数字很小所以划分策略比大样本数据集严格得多。常见做法是按“场景分组”划分而不是随机打乱。板蓝根颗粒图片如果来自不同光照条件、不同背景白底、透明袋、棕色瓶随机划分容易把同一场景的图同时分进训练和验证验证集分数虚高。更稳妥的思路是# 按文件名排序后每10张取1张作为测试集剩下90张再按9:1分训练和验证 ls ./banlangen/images | sort all_images.txt awk NR % 10 0 all_images.txt test.txt comm -23 all_images.txt test.txt train_val.txt head -n 68 train_val.txt train.txt tail -n 9 train_val.txt val.txt注意这种划分方式依赖文件名本身没有语义偏向如果文件名本身就按场景/批次命名要重新设计分组策略。老手一般会先按文件名前缀归组再按组划分确保同批次的图不进两个集合。3.2 数据增强策略翻转、HSV扰动和马赛克怎么配比110张原始图训练目标检测模型不增强基本不可能增强配比也要按场景调。板蓝根颗粒色泽偏棕黄背景可能是白纸、药袋或柜台HSV扰动的作用非常明显。常见的训练配置如下augment: hsv_h: 0.015 # 色调扰动幅度 hsv_s: 0.7 # 饱和度扰动 hsv_v: 0.5 # 亮度扰动 fliplr: 0.5 # 水平翻转概率 mosaic: 0.5 # 马赛克增强概率小目标场景建议保持开启 mixup: 0.0 # 110张图不建议开mixup容易过拟合mosaic增强把4张图拼成1张对提升小目标检测效果明显因为拼接后图像分辨率不变目标相对尺度变小模型被动学习到更多尺度特征。但板蓝根颗粒场景的特殊性在于颗粒外观高度一致mosaic过度会破坏真实场景的分布一致性训练损失曲线容易震荡。3.3 模型选型小数据集不折腾大网络YOLOv8s是性价比上限110张图撑不起YOLOv8l或x这类大模型。参数规模越大对数据量的需求越高强行用大模型的结果是训练集上mAP 0.99、验证集上完全失准过拟合到了极致。我一般建议在这个数据规模下选择YOLOv8s或nano预训练权重用COCO上的版本做迁移学习起点backbone特征提取层的权重保留只微调head和少量主干层。YOLOv8n参数量约3.2MYOLOv8s约11.2M对110张图来说nano更稳。不要迷信“大模型效果更好”这句话检测任务的瓶颈在小数据集上永远是数据质量而不是模型容量。用s起步、看loss曲线和验证集mAP来确认是否需要换更大模型这才是正路。4. 用YOLOv8跑通板蓝根颗粒检测从写配置到出检测框的完整命令4.1 数据配置文件path、train、val、nc、names一个都不能错训练前要新建一个data.yaml这是模型与数据集的接口。路径建议写相对路径避免换机器后反复改配置。# data.yaml path: ./banlangen # 数据集根目录 train: images/train # 训练图片目录相对path val: images/val # 验证图片目录 nc: 1 # 类别数只有一个类别板蓝根颗粒 names: 0: banlangen_granule容易踩的细节train和val指向的是包含图片文件的目录不是txt划分文件列表。YOLOv8会按目录扫描图片并从同名labels目录如labels/train自动寻找对应标注。所以图片目录和标签目录必须保持同名且图片目录放在images/下、标签目录放在labels/下目录结构不能随意改。4.2 训练命令与超参数epochs、batch、imgsz的搭配逻辑yolo train modelyolov8n.pt databanlangen_data.yaml epochs150 batch16 imgsz640 device0 project./runs namebanlangen_exp参数说明从实际效果出发。epochs我通常先给150110张小数据集在30个epoch左右loss明显下降后面进入缓慢收敛阶段150轮足够看到完整趋势且不会花太多时间。batch大小取决于显存16是多数消费级显卡的安全值显存不够降到8。imgsz用640与预训练权重一致不要随便改成1280分辨率越大显存占用指数上涨小目标检出率提升有限但训练时间翻倍。学习率参数没有写在命令里用YOLOv8默认值即可。只有一种情况需要手动调低——训练开始几条epoch后loss剧烈震荡此时把lr0从默认的0.01降到0.005或0.002能稳定训练曲线。130张以下的小数据集学习率宁低勿高这个习惯能省不少返工时间。4.3 推理验证用训练好的权重跑测试集并输出可视化结果训练结束后模型默认保存在runs/banlangen_exp/weights/best.pt。拿测试集图片跑推理并可视化是判断模型是否真的能用的第一关yolo predict modelruns/banlangen_exp/weights/best.pt source./banlangen/images/test saveTrue conf0.25conf0.25表示置信度阈值只显示大于25%的检测框。板蓝根颗粒小目标多置信度普遍低于大目标阈值设太高会出现大量漏检设太低则误检频发。真实使用时建议从0.1开始向上调找到误检和漏检的平衡点。saveTrue会把标注了检测框的结果图保存到runs/banlangen_exp/predict直接看图判断检测效果比看数值指标更直观。跑完一轮后回到训练日志里看results.png里面有训练损失、验证损失、mAP50和mAP50-95四条曲线。mAP50-95这个指标对小板蓝根颗粒非常严格——预测框和真实框的IoU要超过0.5才算一次正确检测颗粒重叠场景下很难达到高分。如果你只关心“能不能框到位置”mAP50更贴近实际业务如果做精细的颗粒计数才需要盯着mAP50-95。5. 板蓝根颗粒训练中的避坑与排查从解压到epoch结束的5个常见失误5.1 zip解压后路径多套一层训练报“No labels found”现象训练启动时报No labels found in .../images/train或者图片全部跳过看日志发现一张有效图都没加载。原因Windows下解压把zip里原有的根目录再嵌套了一层实际图片路径变成了banlangen/banlangen/images/train。YOLO按data.yaml里写的相对路径找文件层数对不上自然找不到。解决find . -type d看一下真实目录树确认images和labels的绝对路径后把data.yaml里的path改成./banlangen/banlangen或者直接mv把里层目录提到外层。经验做法是在解压完、写配置文件之前先跑一次ls把目录结构打印出来核对一遍这一步能节省后面所有路径相关的排查时间。5.2 类别ID映射错乱训练正常但检测结果张冠李戴现象训练日志正常loss正常下降mAP看起来也高但可视化检测结果里该圈板蓝根颗粒的位置框在了完全无关的物体上或者多个目标被并成一个框。原因用户在修改data.yaml的names顺序时和YOLO格式txt里已经写死的类别ID不一致。txt标注里的0如果你改成banlangen_granule对应ID 1模型学到的是另外一个语义空间但数值上训练又不会报错损失函数感知不到语义错位。解决从txt标签反查类别映射关系确认标注文件里出现过的ID集合和names列表下标一一对应。批量检查方法cut -d -f1 ./banlangen/labels/train/*.txt | sort -u输出结果就是训练集出现的类别ID最大值和nc减一的值做对比不一致就是映射错了。另一个习惯是训练前写一个一行脚本统计每个类别的实例数出现类别数为0或极大异常值都说明标签有问题。5.3 标签框越界或坐标乱序loss直接爆NaN现象训练启动后前几个epoch的loss值直接显示nan或者loss先正常下降中途突然跳成nan后不再恢复。原因标注坐标里出现负值、框宽高计算出来是负数或xmax xmin类型的乱序。YOLO格式的txt中中心点坐标和宽高都是归一化到0~1范围的值任何一个字段超出合法区间损失函数计算时将产生无效梯度最终传导成NaN。110张图里可能存在两三条手滑标错的框这类错框在打标工具里肉眼难以发现。解决写一个快速校验脚本扫全量标签import os bad_files [] label_dir ./banlangen/labels/train for f in os.listdir(label_dir): if not f.endswith(.txt): continue for line in open(os.path.join(label_dir, f)): parts line.strip().split() if len(parts) ! 5: bad_files.append((f, field_count_error)) continue vals list(map(float, parts[1:])) if any(v 0 or v 1 for v in vals): bad_files.append((f, out_of_range)) if vals[2] 0 or vals[3] 0: bad_files.append((f, zero_size)) if vals[2] 1 or vals[3] 1: bad_files.append((f, oversize)) print(bad_files)处理方式不是删图而是用之前提过的坐标裁剪和面积过滤逻辑把这些非法框过滤掉保留正常的标注。绝大多数情况下一张图里只有个别框有问题删除这些框不影响整体训练。5.4 密集堆叠场景下mAP虚高召回率实际惨不忍睹现象验证集mAP50达到0.9但把模型丢到真实的药房照片上测试许多板蓝根颗粒完全没有被检测出来漏检率远超训练集表现。原因训练集图片可能是规整的单一背景颗粒摆在干净的桌面或白纸上标注也相对完整。真实场景出现颗粒堆叠一个框内包含多粒颗粒模型输出与堆叠标注的匹配IoU低于阈值被判定为漏检。这是小而密集目标场景的通病不是模型参数的问题。解决板蓝根颗粒这类场景训练时把IoU阈值相关逻辑先放宽松使用conf0.1测试先看模型是否“框到了位置”。框到了但位置偏移继续调训练轮数或增强完全没反应才需要补充接近真实堆叠场景的图片。110张数据集的定位是基线验证训练集分布与真实场景的差异必须在评估阶段暴露出来否则部署后返工成本更高。5.5 过拟合训练loss低到0.05验证loss却居高不下现象训练集loss持续下降到接近0验证集loss在某个epoch后不降反升典型的分叉曲线。mAP表现则是训练集高、验证集低。原因110张图本身样本量少模型容量哪怕只有nano级别在足够多的epoch后也会背诵训练集特征而非泛化到验证集。epoch跑得太多、增强配比太弱或模型参数过多三者都会加速过拟合。解决一张图贴三个技巧。第一epochs降到100以内配合patience20早停策略验证集loss连续20轮不改善就自动停止避免无效训练浪费时间。第二增强强度拉高HSVV扰动幅度上调fliplr保持0.5mosaic开启。第三用YOLOv8n而不是s参数少一半以上过拟合压力小得多。如果以上都调完验证集仍然不收敛就别再折腾模型了问题的根源是图像数量需要补充数据。6. 从训练到判断“值不值得投入”置信度校准与数据质量评估技巧6.1 用混淆矩阵和置信度阈值画出真实能力边界训练完在runs/banlangen_exp/下会生成confusion_matrix.png这个图直接给你回答“这模型到底靠不靠谱”。横轴是真实类别纵轴是预测结果理想状态是主对角线上一团亮色。板蓝根颗粒只有一个类别重点看background那一格如果背景被误检为颗粒的比例太高说明模型没有学会区分颗粒和杂质、阴影需要调整增强参数或者检查标注框是否把背景包进去。置信度阈值对单一类别检测的影响远大于多类别情况。用val模式跑一次批量验证输出所有预测框的置信度分布yolo val modelruns/banlangen_exp/weights/best.pt databanlangen_data.yaml conf0.05出来的结果文件里记录了每个预测框的置信度从中选一个让误检和漏检大致平衡的阈值作为部署值。对小目标密集场景常见操作是把阈值压到0.15~0.2之间而不是默认的0.25这个参数直接决定实际使用体验。6.2 拉出全部标注框统计分布找出数据集的歪斜角落110张图全部过目检查标注质量时间成本可控。更快的方式是画每个标注框的面积分布和长宽比分布。板蓝根颗粒是近似圆形或椭圆形的独立小目标长宽比应该在0.7~1.3之间集中分布如果出现大量长宽比大于2的框多半是标注时框住了整排颗粒或包装袋上的文字这类框要处理掉。面积分布更直接如果大多数框的面积小于整图面积的1%模型在特征提取阶段容易将它们当噪声忽略。这时把imgsz从640提到960或1280小目标在特征图上的像素占比变大检测率会明显改善。换个角度说如果数据类型以极小目标为主110张图的数据量就不够了因为极小目标训练的有效样本数比图片张数还少——一张图里5个目标实际只有550个学习样本模型容易见过就忘。6.3 迭代习惯先跑通弱基线和加分项的正向清单一个很少被提及但很有用的习惯是训练一个“弱基线”——用原始图、最小增强、默认超参数跑30个epoch记录mAP值。这个数字就是你的地板之后再上增强、调分辨率、改模型结构所有改动的效果都对照这个地板来看。没有对比就没有方向你只知道改了配置但不知道是变好还是变坏。小数据集上的每次改动都可能被随机因素淹没用弱基线校准自己是最有效的管理预期方式。我做这类小样本检测任务的经验是头两个epoch如果loss没有下降趋势先停掉检查数据和配置确认正常后调到收敛至少要动用2~3轮对比实验。先接受110张图的性能上限再判断是否扩充数据不要指望算法调参能创造数据。判断依据很简单——如果增强、归一化、阈值调整都做完了验证集mAP50还达不到业务要求的及格线那就该去找更多板蓝根颗粒的实拍图。希望这份从解压到评估的完整路径能帮到你至少别再在格式转换和路径问题上耗掉一个周末。本文还有配套的精品资源点击获取
返回列表