
简介这份感冒药品分类检测数据集面向目标检测学习者与药品识别应用开发者提供VOC与YOLO双格式标注可直接用于训练感冒类药品的检测模型适合入门练手或作为药品零售场景识别的数据基础。压缩包共2000个文件包含960张jpg图片、960个VOC格式xml标注、960个YOLO格式txt标注及少量说明文件整体约44.17MB图片与标注一一对应无需额外转换即可接入主流检测框架。标注共4类涵盖999感冒灵、板蓝根、布洛芬及drugs总框数1365其中布洛芬657框、999感冒灵573框、板蓝根134框类别分布差异明显便于观察长尾样本对训练的影响。已有395人学习下载可作为药品检测任务的练手数据帮助读者快速跑通数据加载、格式转换与模型训练流程。1. 感冒药品分类检测数据集959 张 3 类别 VOCYOLO 格式到底能做什么手上有一批 959 张的感冒药品图片标了 3 个类别同时给了 VOC 和 YOLO 两套格式——这个数据集最直接的价值是让你跳过最耗时的「拍图 拉框」环节直接把精力放在模型训练和部署验证上。感冒药品分类检测属于典型的目标检测数据集落地场景药房货架、智能药盒、药品分拣线都需要模型先定位再分类。VOC 格式适合做数据审查和格式转换的中间态YOLO 格式则可以直接喂给 YOLOv5/v8/v11 系列训练。959 张不算大3 类别也不算复杂但正因为小它更适合用来跑通全流程、验证增强策略、对比不同 YOLO 版本的收敛差异。如果你正在找yolo 入门的练手数据或者想验证一个药品检测想法能不能落地这个体量的数据集刚好够用不会一上来就被算力卡住。2. VOC 与 YOLO 双格式拆解目录结构、标签差异与转换逻辑2.1 VOC 格式的目录约定与 XML 标签字段VOC 格式的核心是一个Annotations文件夹里面每张图对应一个同名 XML。XML 里真正影响训练的是size和object两块size里的width、height决定归一化基准object里的name是类别名bndbox的xmin/ymin/xmax/ymax是左上角和右下角绝对坐标。感冒药品这类数据有个特点药盒通常占画面比例较大但不同药品的包装尺寸差异明显如果拍摄时没有统一距离bndbox的宽高比会波动很大。常见做法是先用脚本统计一遍所有 XML 的宽高比分布把极端值挑出来人工复核避免把拍摄失误当成难样本。import os import xml.etree.ElementTree as ET from collections import Counter ann_dir Annotations ratio_list [] class_counter Counter() for xml_file in os.listdir(ann_dir): if not xml_file.endswith(.xml): continue tree ET.parse(os.path.join(ann_dir, xml_file)) root tree.getroot() for obj in root.findall(object): name obj.find(name).text class_counter[name] 1 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) w xmax - xmin h ymax - ymin if h 0: ratio_list.append(round(w / h, 2)) print(类别分布:, class_counter) print(宽高比范围:, min(ratio_list), ~, max(ratio_list))这段脚本做两件事统计 3 个类别的实例数量以及所有框的宽高比。类别分布直接决定后面要不要做重采样宽高比范围如果出现 0.1 以下或 10 以上的值基本可以判定是标注错误或极端遮挡需要单独处理。参数上只需要改ann_dir指向你的Annotations路径其他不用动。2.2 YOLO 格式的 txt 标签与归一化坐标YOLO 格式每张图对应一个.txt每行是class_id x_center y_center width height全部归一化到 0~1。和 VOC 最大的区别有两个一是没有类别名字段类别靠classes.txt或data.yaml里的names列表按索引对应二是坐标是中心点加宽高不是角点。感冒药品数据从 VOC 转 YOLO 时最容易翻车的地方是类别索引顺序——如果classes.txt里写的顺序和训练配置里的names不一致模型会把感冒灵学成阿莫西林而且 loss 还会正常下降属于典型的玄学问题。import os import xml.etree.ElementTree as ET classes [ganmaoling, amoxicillin, ibuprofen] # 必须与 data.yaml 的 names 顺序一致 ann_dir Annotations img_dir JPEGImages out_dir labels os.makedirs(out_dir, exist_okTrue) for xml_file in os.listdir(ann_dir): if not xml_file.endswith(.xml): continue tree ET.parse(os.path.join(ann_dir, xml_file)) root tree.getroot() size root.find(size) img_w float(size.find(width).text) img_h float(size.find(height).text) lines [] for obj in root.findall(object): name obj.find(name).text if name not in classes: continue cls_id classes.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) 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}) txt_name xml_file.replace(.xml, .txt) with open(os.path.join(out_dir, txt_name), w) as f: f.write(\n.join(lines))转换逻辑很直白读 XML 的绝对坐标除以图像宽高做归一化再换成中心点表示。classes列表的顺序就是最终类别索引必须和data.yaml里的names逐字一致。:.6f保留 6 位小数是 YOLO 官方脚本的习惯精度足够也不会让文件体积膨胀。转换完建议随机抽 5 张图用labelImg或labelme打开核对确认框的位置和类别都没错位。2.3 两套格式的取舍什么时候用 VOC什么时候用 YOLOVOC 的优势在于可读性和工具兼容性。labelImg默认存 VOC很多数据审查脚本也是按 XML 写的人工复核时 XML 的字段名比一串数字直观得多。YOLO 的优势在于训练链路短YOLOv5 之后的所有官方仓库都直接吃 txt不需要再转。我的习惯是原始标注保留 VOC 作为「母版」每次训练前用脚本生成一份 YOLO 副本这样即使转换脚本改错了母版还在不用重新标。959 张 3 类别的体量转换耗时在秒级没必要为了省这一步把 VOC 删掉。对比项VOCYOLO标签文件XMLTXT坐标表示角点绝对坐标中心点归一化坐标类别字段name 字符串class_id 整数索引常用工具labelImg、labelmeYOLO 官方训练脚本适合阶段标注、审查、存档训练、导出、部署3. 用这份数据集跑通 YOLO 训练环境、配置与首轮收敛判断3.1 环境准备与 data.yaml 的最小配置训练环境我一般用 Python 3.10 PyTorch 2.x Ultralytics 最新稳定版显卡 8G 显存起步959 张图 batch size 设 16 足够。目录结构按 YOLO 官方约定摆images/train、images/val、labels/train、labels/valdata.yaml放在数据集根目录。感冒药品 3 类别nc写 3names顺序和转换脚本里的classes完全一致。按 8:2 切分训练集约 767 张验证集约 192 张。如果某一类实例数明显偏少比如阿莫西林只有几十个框建议在切分时做分层抽样保证验证集里每类都有足够样本否则 mAP 曲线会抖得没法看。path: ./cold_medicine_dataset train: images/train val: images/val nc: 3 names: 0: ganmaoling 1: amoxicillin 2: ibuprofenpath是数据集根目录train和val是相对路径。nc必须等于names的长度多一个少一个都会在训练启动时报错。names的索引就是 txt 里的class_id顺序错了模型学到的就是错位映射。3.2 训练命令与关键参数怎么设首轮训练不建议一上来就改网络结构先用默认配置跑通确认数据链路没问题。命令用yolo detect train模型选yolov8n.pt或yolo11n.pt这种小模型959 张图用 nano 版本收敛快单卡几十分钟就能看到第一轮结果。yolo detect train \ data./cold_medicine_dataset/data.yaml \ modelyolov8n.pt \ epochs100 \ imgsz640 \ batch16 \ lr00.01 \ patience20 \ projectruns/cold_medicine \ nameexp1epochs100是上限patience20表示 20 轮验证指标不提升就早停避免过拟合。imgsz640是 YOLO 系列的默认输入尺寸药盒目标通常不会太小640 够用如果发现小目标漏检严重再考虑提到 960 或 1280但显存占用会明显上升。lr00.01是 SGD 的初始学习率用 AdamW 的话可以降到 0.001。batch16在 8G 显存上跑 640 分辨率基本安全如果 OOM 就降到 8 或 4。3.3 首轮结果怎么看mAP、混淆矩阵与 loss 曲线训练结束后重点看三个东西results.png里的 loss 曲线、confusion_matrix.png、以及val的 mAP50 和 mAP50-95。感冒药品 3 类别如果数据质量正常mAP50 首轮跑到 0.85 以上算合理低于 0.7 就要排查。loss 曲线看box_loss和cls_loss是否同步下降如果cls_loss降但box_loss不降通常是框的回归有问题可能是标注框太松或太紧。混淆矩阵里如果某一类大量被预测成背景说明该类样本太少或特征不明显需要补数据或做增强。验证集 mAP 波动大常见原因是验证集太小192 张里每类可能只有几十个实例统计噪声大可以适当增大验证集比例到 3:7。4. 小数据集训练避坑959 张 3 类别最容易踩的 5 个坑4.1 类别索引错位导致「学了个寂寞」现象训练 loss 正常下降mAP 也有数值但推理时类别全乱感冒灵被标成布洛芬。原因classes.txt或转换脚本里的类别顺序和data.yaml的names不一致模型学到的索引映射是错的。解决转换前先固定一份classes.txt转换脚本和data.yaml都从这份文件读不要手写两遍。训练前用yolo detect val跑一遍看混淆矩阵对角线是否集中如果分散就是索引问题。4.2 图片和标签文件名不匹配现象训练启动时报No labels found或大量图片被跳过。原因YOLO 按文件名找标签images/train/001.jpg必须对应labels/train/001.txt扩展名和主文件名都要一致。VOC 转 YOLO 时如果 XML 文件名和图片名不同就会断链。解决转换脚本里用图片文件名反查 XML而不是遍历 XML 直接生成 txt。转换后统计images和labels的文件数两者必须相等。4.3 验证集里某类样本为零现象mAP 曲线某一类始终为 0 或剧烈抖动。原因随机切分时某一类恰好全部分到训练集验证集没有该类实例。解决切分时按类别分层抽样保证每类在验证集里至少有 20 个实例。959 张 3 类别如果某类总数低于 100验证集比例可以提到 0.3。4.4 增强过度导致药盒特征被破坏现象训练 mAP 高但验证 mAP 低推理时对旋转和遮挡敏感。原因默认增强里mosaic、mixup、degrees对小数据集可能过强药盒上的文字和颜色是分类关键过度旋转和混合会把这些特征抹掉。解决首轮训练先关掉mixupdegrees降到 5 以内mosaic保留但把close_mosaic设到 10让最后 10 轮用干净数据收尾。4.5 图片尺寸不一致导致 letterbox 后目标过小现象训练正常但推理时小药盒漏检。原因原始图片分辨率差异大YOLO 的 letterbox 会统一缩放到imgsz如果原图很大缩放后药盒可能只有几十像素。解决训练前统计图片尺寸分布把长边超过 2000 的图片先缩到 1280 再训练或者直接把imgsz提到 960。推理时保持和训练一致的imgsz不要训练用 640 推理用 1280。5. 从 959 张到可用模型增强策略、导出与推理验证的实操技巧数据量小的时候增强策略比换模型更有效。我一般会先跑一版基线看混淆矩阵里哪两类容易混再针对性加增强。感冒药品里如果感冒灵和复方氨酚烷胺包装相似可以加hsv_h和hsv_s扰动让模型对颜色变化更鲁棒如果药盒经常被手遮挡可以加erasing随机擦除。但增强不是越多越好959 张的体量增强参数翻倍后等效样本量上去了但分布也会偏移验证集 mAP 可能先升后降需要盯着曲线调。导出环节如果目标是边缘设备部署优先导 ONNX 再转 TensorRT。YOLOv8/v11 导出命令很直接yolo export modelruns/cold_medicine/exp1/weights/best.pt formatonnx imgsz640 simplifyTruesimplifyTrue会做一层图优化去掉冗余算子ONNX 体积和推理耗时都会降。导出后一定要用onnxruntime跑一遍和 PyTorch 相同输入的对比确认输出差异在 1e-3 以内否则可能是某些算子不被支持转过去精度会掉。推理验证时除了看 mAP还要看单张耗时和显存占用。959 张训练出来的模型在 1080p 视频流上跑 640 分辨率单卡 T4 大概能撑十几路具体路数取决于后处理耗时和 batch 策略这个需要按你的实际流水线压测。最后说一个我自己的习惯每次训练完把data.yaml、转换脚本、训练命令、results.png和confusion_matrix.png一起归档到一个带日期的文件夹里。959 张的数据集不大但实验次数多了以后没有归档根本记不清哪版配置对应哪个结果。这个习惯帮我省过很多次「后悔药」——有一次线上模型类别错位就是靠归档里的classes.txt快速定位到是转换脚本改过顺序。希望帮到你。本文还有配套的精品资源点击获取