新闻详情

新闻详情

首页 / 资讯中心 / 详情

1000张VOC吸烟检测数据集:YOLOv8小样本目标检测实战

发布时间:2026/9/28 17:20:54来源:尧图网络
1000张VOC吸烟检测数据集:YOLOv8小样本目标检测实战
简介这份资源是面向计算机视觉开发者与安防算法研究者的吸烟行为检测数据集覆盖室内、室外多种真实场景可用于训练和验证人员吸烟检测模型适合具备一定目标检测基础、希望快速搭建吸烟识别原型的读者。压缩包共约2000个文件包含1507个xml标注文件、486张jpg图像及7张png图像整体约861.69MB其中xml为VOC格式标签jpg与png为对应场景图片可直接接入YOLO、Faster R-CNN等常见检测框架进行训练。目前已有240人学习下载说明该数据集在吸烟检测方向具备一定参考价值。数据涵盖不同光照、角度与背景能帮助读者省去自行采集与标注的成本快速完成模型训练、精度评估与效果对比也可作为课程设计或算法验证的现成素材。1. 1000 张 VOC 吸烟检测数据集小样本目标检测的落地起点手上只有一千来张图能不能训出一个能用的吸烟检测模型这是我最近被问得最多的问题之一。答案是可以但前提是你得把数据集的脾气摸透。这份「1000 多张室内室外场景人员吸烟检测数据集voc 格式标签」正好卡在一个很微妙的位置它比玩具数据集大比工业级数据集小覆盖了室内和室外两类场景标注是经典的 VOC XML 格式。它解决的核心问题是——让你在没有几十万张标注图的情况下快速验证「吸烟行为检测」这条技术路线到底能不能跑通。适合谁适合做园区安全监控、加油站明火预警、公共场所行为分析的一线开发和算法同学也适合想拿一个真实二类检测任务练手 YOLO 全流程的人。别指望它直接上生产但它足够让你把从数据清洗到模型部署的整条链路走一遍而且走完你会对「小样本 真实场景」的坑有肌肉记忆。2. VOC 标签拆解与吸烟检测的选型逻辑2.1 为什么 VOC 格式在吸烟检测里依然是硬通货VOC 格式说白了就是每张图配一个同名 XML里面用object节点记录每个目标的类别和边界框坐标。它老但它通用。你拿到的这份数据集标签结构大概率长这样name里写的是smoke或者smokingbndbox里是xmin/ymin/xmax/ymax四个整数。为什么强调这个因为吸烟检测的目标尺度变化极大——远景里一个人叼烟烟头可能只占十几个像素近景里手部夹烟烟支能占上百像素。VOC 的绝对坐标在这种尺度跨度下反而比某些相对坐标格式更直观你排查标注错误时一眼就能看出框有没有跑偏。另一个现实原因是工具链。LabelImg、labelme 转 VOC、以及大量开源检测框架的 dataloader 默认就吃 VOC你不需要为了这份数据集去写新的解析器。常见做法是先用xml.etree.ElementTree把 XML 读一遍统计类别分布和框的宽高比这一步能帮你提前发现「烟头框普遍小于 20 像素」这种致命问题。2.2 室内外场景混采带来的三个隐性挑战这份数据集标称覆盖室内室外这听起来是优点实际用起来是双刃剑。室内场景常见的是办公室、走廊、卫生间光照稳定但背景杂乱烟头和白色墙面、纸巾容易混淆室外场景常见的是园区道路、门口、停车场光照剧烈变化逆光和阴影会让烟支的视觉特征极不稳定。混在一起训模型容易学到「背景捷径」——比如把某个室内墙角当成吸烟的强相关特征。我一般会先做场景分层统计按文件名前缀或者 EXIF 信息粗分室内外分别看两类的正样本数量和框的尺度分布。如果某一类场景的样本少于 200 张就要考虑在训练时对这类做重采样或者单独评估。别小看这一步很多翻车案例都是因为模型在室外召回率 0.8、室内只有 0.3而你在混合验证集上看到的是 0.6 的平均值误以为还行。2.3 从 VOC 到 YOLO 训练格式的转换脚本不管你最后用 YOLOv5、YOLOv8 还是别的框架第一步都是把 VOC 转成框架能吃的格式。下面这个脚本把 VOC XML 转成 YOLO 的 txt 格式同时生成训练集和验证集的划分文件。注意类别映射我写死了smoking - 0如果你的标签里类别名不统一先跑一遍统计再改。import os import glob import random import xml.etree.ElementTree as ET # 类别映射根据你数据集里实际的 name 字段调整 CLASS_MAP {smoking: 0, smoke: 0} def convert_bbox(size, box): VOC 绝对坐标转 YOLO 归一化中心坐标 dw, dh 1.0 / size[0], 1.0 / size[1] x (box[0] box[1]) / 2.0 y (box[2] box[3]) / 2.0 w box[1] - box[0] h box[3] - box[2] return x * dw, y * dh, w * dw, h * dh def parse_xml(xml_path): tree ET.parse(xml_path) root tree.getroot() size root.find(size) w int(size.find(width).text) h int(size.find(height).text) lines [] for obj in root.iter(object): name obj.find(name).text.strip() if name not in CLASS_MAP: continue cls_id CLASS_MAP[name] bnd obj.find(bndbox) box (float(bnd.find(xmin).text), float(bnd.find(xmax).text), float(bnd.find(ymin).text), float(bnd.find(ymax).text)) bb convert_bbox((w, h), box) lines.append(f{cls_id} { .join([f{v:.6f} for v in bb])}) return lines def main(xml_dir, out_dir, val_ratio0.2): os.makedirs(out_dir, exist_okTrue) xml_files glob.glob(os.path.join(xml_dir, *.xml)) random.seed(42) random.shuffle(xml_files) val_count int(len(xml_files) * val_ratio) val_files xml_files[:val_count] train_files xml_files[val_count:] for phase, files in [(train, train_files), (val, val_files)]: list_path os.path.join(out_dir, f{phase}.txt) with open(list_path, w) as f: for xml_path in files: lines parse_xml(xml_path) if not lines: continue # 跳过没有有效目标的图 img_path xml_path.replace(.xml, .jpg) f.write(img_path \n) label_path xml_path.replace(.xml, .txt) with open(label_path, w) as lf: lf.write(\n.join(lines)) print(ftrain: {len(train_files)}, val: {len(val_files)}) if __name__ __main__: main(./annotations, ./labels, val_ratio0.2)逻辑说明convert_bbox把 VOC 的左上右下坐标转成 YOLO 需要的归一化中心点加宽高。parse_xml里我加了一个if name not in CLASS_MAP: continue这是为了防止数据集里混入person之类的其他类别污染训练。main里用固定随机种子 42 保证划分可复现val_ratio0.2是 1000 张量级下的经验值验证集低于 150 张评估波动会很大。参数说明CLASS_MAP必须按你实际 XML 里的name字段改大小写敏感。val_ratio建议在 0.15 到 0.25 之间样本越少越要留足验证。如果你的图片是 png 格式把replace(.xml, .jpg)改成对应后缀。2.4 训练前的数据体检清单转换完别急着开训先跑一遍体检。我一般会检查四件事第一有没有宽或高小于 32 像素的图这种图在 YOLO 里会被 resize 到 640烟头直接糊成一片第二有没有框的宽高小于 8 像素的标注这种目标在特征图上基本消失建议直接过滤掉第三类别名有没有拼写不一致比如smoking和smoke混用第四室内外样本比例是否严重失衡。这四步用几十行 Python 就能跑完但能帮你省下几小时的无效训练。3. 用 YOLOv8 在 1000 张图上跑通吸烟检测3.1 环境搭建与最小可运行配置YOLOv8 对这份数据集来说是个稳妥选择它的 anchor-free 设计对小目标比 YOLOv5 友好一些而且ultralytics包的 API 足够简单。环境上我建议 Python 3.9 以上PyTorch 2.0 以上CUDA 11.8 或 12.1 都行。安装就一行pip install ultralytics8.1.0别装最新版小数据集上版本差异带来的玄学问题不值得你花时间排查。装完之后建一个smoking.yaml内容如下path: ./dataset train: labels/train.txt val: labels/val.txt nc: 1 names: [smoking]path指向你的数据集根目录train和val是上一步生成的 txt 列表路径。nc: 1表示只有吸烟一个类别。这个 yaml 放在项目根目录训练时直接引用。3.2 训练命令与关键参数怎么设最小训练命令长这样yolo detect train \ datasmoking.yaml \ modelyolov8n.pt \ epochs150 \ imgsz640 \ batch16 \ lr00.01 \ patience30 \ projectruns/smoking \ nameexp1逐条说参数。modelyolov8n.pt用 nano 版1000 张图用大模型必过拟合nano 的容量刚好。epochs150配合patience30意思是 30 轮验证指标不涨就早停小数据集上通常 80 到 120 轮就收敛了。imgsz640是默认值但如果你统计发现烟头框普遍小于 16 像素可以提到 960代价是显存翻倍、速度减半。batch16在 8G 显存上跑 640 分辨率没问题显存不够就降到 8。lr00.01是 SGD 的初始学习率如果你换成 AdamW改成 0.001。训练过程中重点看mAP50-95和recall。吸烟检测这种场景召回率比精确率重要——漏检一个吸烟的人可能意味着一次安全隐患误检一个大不了人工复核。如果训练到 50 轮 recall 还上不去 0.5先别调模型回去查标注质量。3.3 推理验证与阈值调整训完在验证集上跑推理yolo detect predict \ modelruns/smoking/exp1/weights/best.pt \ source./dataset/images/val \ conf0.25 \ iou0.5 \ save_txtTrue \ projectruns/smoking \ nameval_predconf0.25是置信度阈值默认 0.25 偏保守。吸烟检测里我一般会先降到 0.15 看召回能到多少再往上调找到精确率和召回率的平衡点。iou0.5是 NMS 的 IoU 阈值如果发现同一个人被框了两次降到 0.4。save_txtTrue会把预测结果存成 YOLO 格式的 txt方便你写脚本和真值对比逐图看漏检和误检。这里有个血泪经验别只看 mAP 数字。把预测结果可视化出来随机抽 20 张漏检的图和 20 张误检的图一张一张看。你会发现很多问题不是模型不行是标注本身就有问题——比如烟头被手挡住只标了一半或者远景里烟支根本没标。这些脏数据不清理调参调到天亮也没用。3.4 小样本下的数据增强策略1000 张图训检测数据增强是刚需但不能乱开。YOLOv8 默认开了 mosaic、mixup、HSV 抖动和随机翻转。我的建议是mosaic 保留它能把 4 张图拼成 1 张等效增加小目标出现的频率mixup 关掉它会把两张图线性混合吸烟这种细粒度特征混完就没了HSV 的hsv_v可以调到 0.5模拟室内外光照差异随机翻转保留但上下翻转要慎重人倒着抽烟的样本现实中不存在。如果你发现模型在室外逆光场景下召回特别差可以单独对室外样本做一次 gamma 校正增强把暗部提亮再混进训练集。这个操作相当于给模型补课比单纯加 epoch 有效。4. 吸烟检测落地时最容易翻车的五个坑4.1 坑一烟头框太小导致模型直接忽略现象训练 loss 正常下降但验证集 recall 始终在 0.3 以下可视化发现模型只框住了整张脸或手烟头完全没反应。原因YOLOv8 在 640 分辨率下P3 特征图的 stride 是 8一个 8 像素的烟头在特征图上只占 1 个格子卷积核根本提取不到有效特征。解决两条路。一是把imgsz提到 960 或 1280让烟头在特征图上占更多像素二是在转换标签时过滤掉宽高小于 10 像素的框承认这部分目标当前方案搞不定先保证能检出的部分做扎实。我一般先走第二条把基线跑稳再回头啃小目标。4.2 坑二室内外样本比例失衡导致场景偏科现象整体 mAP 看着还行但单独拿室外测试集一跑recall 掉 20 个点。原因室内样本占了七成以上模型在训练中见到的室外场景太少学到的特征偏向室内背景。解决先统计室内外比例如果低于 6:4对少的那一类做 oversampling——在生成 train.txt 时把室外样本路径重复写两到三遍。注意别重复验证集否则评估结果会虚高。另一个办法是冻结 backbone 前几层只训检测头减少模型对背景的过拟合。4.3 坑三VOC 标签里的坐标越界现象训练时偶尔报bbox out of range或者 loss 突然变成 nan。原因VOC 标注时手抖xmax超过了图片实际宽度或者xmin xmax。这种脏标注在人工标的数据集里很常见。解决在转换脚本里加一道校验xmin max(0, xmin)xmax min(w, xmax)并且如果xmax xmin或ymax ymin就直接丢弃这个框。别心疼一个越界框带来的 nan 能让你白跑一晚上。4.4 坑四把吸烟检测当成通用目标检测来调参现象照着 COCO 上的调参经验设lr00.02、weight_decay0.0005结果模型震荡不收敛。原因1000 张图和 COCO 的 12 万张图不是一个量级大学习率在小数据集上会让梯度更新过猛直接跳过最优解。解决小数据集上学习率砍半lr00.005到0.01之间试。weight_decay可以提到 0.001 增强正则化。另外把warmup_epochs从默认 3 提到 5让模型在前几轮慢慢适应数据分布。4.5 坑五验证集里混入了训练集图片现象验证指标高得离谱mAP50 到 0.95但一上真实场景就废。原因划分 train/val 时用了随机划分但数据集里存在同一场景的连拍图连拍图被分到了两边模型等于在验证集上看到了训练集的近邻。解决按场景或按视频片段划分而不是按单张图随机划分。如果文件名有场景编号按编号分组整组进 train 或整组进 val。没有编号就人工看一遍把明显是同一场景的图归到一起再分。这一步多花半小时能让你对模型真实能力有准确判断。5. 把 1000 张图榨干进阶技巧与效果验证数据集小就得在别的地方补。我常用的一个技巧是「预训练权重 分层冻结」。YOLOv8n 在 COCO 上预训练过backbone 已经学会了边缘、纹理这些通用特征。训练时先把 backbone 冻住只训 neck 和 head跑 30 轮让检测头适应吸烟任务然后解冻全部用更低的学习率lr00.001再跑 80 轮微调。这套流程比直接端到端训mAP50 通常能高 3 到 5 个点。另一个技巧是「难例挖掘」。第一轮训完用best.pt在训练集上跑推理把漏检和误检的图挑出来人工复核标注。如果确实是标错了就改如果标对了但模型没学会就把这些图复制一份在下一轮训练时提高采样权重。1000 张图里通常有 50 到 100 张是「硬骨头」把它们啃下来整体指标提升比加数据更明显。验证方法上别只信 mAP。我一般会做三件事第一按室内外分组算 recall看场景偏科有没有改善第二按目标框大小分组算 recall看小目标有没有被牺牲第三拿 20 张完全没参与训练的图自己手机拍的也行做一次盲测看模型在真实场景下的表现。这三步做完你对模型能不能用就有底了。最后说个我自己的习惯每次训完模型我都会把best.pt和对应的smoking.yaml、转换脚本、训练命令一起打包存档文件名带上日期和关键参数。小数据集实验迭代快没有后悔药只有存档能让你在两周后想起来「当时那个 0.72 的模型是怎么训的」时能一键复现。希望帮到你。本文还有配套的精品资源点击获取
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

PyTorch LSTM中文情感分析实战:预处理、模型与可解释性 2026/9/28 18:08:03

PyTorch LSTM中文情感分析实战:预处理、模型与可解释性

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →
为什么大型储能需要边缘 AI 协调控制器?RK3588+FPGA 高速采集方案 2026/9/28 18:07:56

为什么大型储能需要边缘 AI 协调控制器?RK3588+FPGA 高速采集方案

为什么大型储能需要边缘AI协调控制器?RK3588FPGA高速采集方案标签:# 储能协调控制器 #RK3588 #FPGA #边缘 AI #储能安全 #AIDC 数据中心储能 阅读对象:储能系统集成商、硬件研发工程师、BMS/EMS 开发、新能源方案选型前言随着大型集装箱储能、…

阅读更多 →
RKNN Toolkit V1.7.3模型转换深度解析:ONNX到RKNN的算子映射与量化校准 2026/9/28 18:07:56

RKNN Toolkit V1.7.3模型转换深度解析:ONNX到RKNN的算子映射与量化校准

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →
从“替代人的手”到“替代人的脑”:工业AI正在跨越哪道分水岭? 2026/9/28 18:07:56

从“替代人的手”到“替代人的脑”:工业AI正在跨越哪道分水岭?

一个工厂的“AI管家”,管的是什么?2026年9月,湖北某车间。生产线全速运转,却少见操作工的身影。AI系统全面接管生产流程后,这个百万吨级工厂年增效近2000万元。同月,容知日新发布“观星OS”设备智能运维操作…

阅读更多 →
ESP32锂电池电压监测:分压电路设计与ADC校准实战 2026/9/28 18:07:55

ESP32锂电池电压监测:分压电路设计与ADC校准实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →
STM32驱动0.96寸ST7735S TFT屏:从SPI接线到画点全流程 2026/9/28 18:07:49

STM32驱动0.96寸ST7735S TFT屏:从SPI接线到画点全流程

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉