简介:这是一份面向计算机视觉初学者与目标检测工程实践者的横幅检测数据集资源,围绕YOLO系列目标检测任务构建,可用于训练、微调与验证横幅类目标的识别模型,适合课程设计、毕业项目或算法练手场景。压缩包共1006个文件,约189.78MB,其中500张jpg图像构成主要样本,497个txt文件为对应的YOLO格式标注,另含2个yaml配置文件、2个pt权重文件及少量png与zip辅助内容,覆盖数据、配置到预训练模型的完整链路。资源内已附带基于YOLOv5训练好的模型权重,读者可直接加载推理或在此基础上继续迭代,省去从零标注与调参的时间成本。目前已有49人学习下载,体量适中、结构清晰,便于快速上手横幅检测这一细分任务,并对照标签格式理解YOLO数据组织方式。
1. 横幅检测数据集到底能解决什么:从 490 张图到可用的 yolov5 权重
做横幅检测这个需求,第一次听到的人多半会愣一下——横幅有什么好检测的?但真落到业务里,比如户外广告合规审核、街景招牌统计、赛事现场物料识别、内容平台违规横幅过滤,你会发现通用 COCO 预训练模型对「横幅」这个类别的召回率低得让人想砸键盘。原因不复杂:横幅在 COCO 里没有独立类别,形态又横跨条幅、展板、LED 屏、手持牌,长宽比极端、背景杂乱、透视变形严重,通用模型压根没为这种目标调过锚框。
这份资源就是冲着这个缺口来的:490 张标注好的横幅图像,配 YOLO 格式标签,外加一个已经训练完成的 yolov5 权重。对想快速验证横幅检测可行性、又不想从零标数据的人来说,它省掉的是最枯燥的那段——找图、框框、转格式、调通训练脚本。490 张不算大,但作为冷启动数据集,够你把整条链路跑通,也够你判断这个方向值不值得继续投人力扩标。适合两类人:一是要做横幅相关检测原型的产品/算法同学,二是想拿一个真实小数据集练手 yolov5 训练自己的数据集全流程的工程师。下面按「数据长什么样 → 怎么训 → 怎么用现成权重 → 坑在哪」的顺序拆开讲。
2. 数据集结构与 YOLO 标签格式:先看清 490 张图里装了什么
拿到一个数据集压缩包,我习惯先不急着解压训练,而是把目录结构和标签格式摸清楚。这一步花十分钟,能省掉后面几小时的报错排查。横幅检测这类目标有个特点:长宽比跨度极大,从接近 1:1 的方形展板到 10:1 的细长条幅都有,标签质量直接决定锚框聚类和训练稳定性。
2.1 目录组织与文件对应关系
解压后典型的结构是这样(不同打包方式可能略有差异,以实际为准):
banner_dataset/ ├── images/ │ ├── train/ # 训练集图像 │ └── val/ # 验证集图像 ├── labels/ │ ├── train/ # 对应训练集标签 │ └── val/ # 对应验证集标签 ├── data.yaml # 数据集配置文件 └── weights/ └── best.pt # yolov5 训练好的模型关键点是 images 和 labels 必须严格同名同层级对应。我见过太多人把images/train/001.jpg的标签写成labels/001.txt,训练时 yolov5 找不到标签会直接把它当负样本,loss 曲线看着在降,实际模型啥也没学到——这种「静默失败」是最坑的。
2.2 YOLO 标签格式逐字段拆解
YOLO 格式的标签是每张图一个.txt,每行一个目标,格式为:
<class_id> <x_center> <y_center> <width> <height>五个字段全部归一化到 0~1 之间。以一张 1920×1080 的横幅图为例,如果横幅框左上角在 (300, 400)、右下角在 (1500, 620):
# 计算归一化 YOLO 标签 img_w, img_h = 1920, 1080 x1, y1, x2, y2 = 300, 400, 1500, 620 x_center = (x1 + x2) / 2 / img_w # 0.46875 y_center = (y1 + y2) / 2 / img_h # 0.47222 width = (x2 - x1) / img_w # 0.625 height = (y2 - y1) / img_h # 0.20370 # 写入标签文件,class_id 从 0 开始 line = f"0 {x_center:.6f} {y_center:.6f} {width:.6f} {height:.6f}" print(line) # 输出: 0 0.468750 0.472222 0.625000 0.203704逻辑说明:x_center、y_center是框中心点坐标除以图像宽高,width、height是框的宽高除以图像宽高。这里最容易翻车的是坐标系——有人用左上角坐标直接归一化,有人忘了减 x1,结果标签全偏。参数上,class_id单类别横幅就是 0;如果数据集里区分了「条幅/展板/手持牌」多类,就要对照data.yaml里的names顺序确认,顺序错一位,模型学出来的类别就全乱套。
2.3 data.yaml 配置与类别定义
data.yaml是 yolov5 训练的入口配置,内容大致如下:
# 数据集路径配置 path: ./banner_dataset # 数据集根目录 train: images/train # 训练集相对路径 val: images/val # 验证集相对路径 # 类别定义 nc: 1 # 类别数量 names: ['banner'] # 类别名称,顺序必须与标签 class_id 对应nc和names必须和标签里的class_id严格对齐。单类别横幅nc: 1、names: ['banner']是最常见配置。如果你后续要扩类,比如加「横幅」和「竖幅」两类,标签里就得出现 0 和 1,names也要同步改成两项,否则训练时 yolov5 会报Label class X exceeds nc之类的错误。这一步没有玄学,就是对齐、对齐、再对齐。
3. 用这份数据集训练 yolov5:环境、命令与超参数怎么设
数据集看明白了,接下来是把它喂进 yolov5。这一章我按「环境准备 → 训练命令 → 超参数取舍 → 结果验证」的顺序走,命令都能直接抄,参数我会说清每个值为什么这么设。yolov5 的版本迭代比较快,下面以常见的 v6/v7 分支为准,不同版本参数名可能有细微差异,以你本地train.py --help为准。
3.1 环境准备与依赖安装
先确认 CUDA 和 PyTorch 版本匹配,这是新手翻车率最高的一步。显卡驱动、CUDA、PyTorch 三者版本不对应,torch.cuda.is_available()返回 False,训练直接掉到 CPU 上,490 张图也能跑到你怀疑人生。
# 1. 克隆 yolov5 仓库(以 v7.0 分支为例) git clone -b v7.0 https://github.com/ultralytics/yolov5.git cd yolov5 # 2. 创建虚拟环境,避免污染全局 conda create -n banner_yolo python=3.9 -y conda activate banner_yolo # 3. 安装依赖,requirements.txt 会自动拉取匹配的 torch pip install -r requirements.txt # 4. 验证 GPU 是否可用 python -c "import torch; print(torch.cuda.is_available(), torch.cuda.get_device_name(0))"逻辑说明:第 1 步指定分支是为了版本可控,别直接拉 main 然后被新特性坑。第 3 步requirements.txt里通常锁定了 torch 版本,但如果你本地 CUDA 是 11.8 而它默认装的是 cu121 的包,可能仍能跑但性能打折,稳妥做法是去 PyTorch 官网按你的 CUDA 版本单独装。第 4 步输出True和显卡型号才算过关,输出False就先别往下走,回去查驱动。
3.2 训练命令与关键参数
环境通了,训练命令本身不复杂,但参数怎么设决定了你是在浪费电还是在出活:
python train.py \ --img 640 \ --batch 16 \ --epochs 100 \ --data ./banner_dataset/data.yaml \ --weights yolov5s.pt \ --cfg models/yolov5s.yaml \ --hyp data/hyps/hyp.scratch-low.yaml \ --name banner_exp \ --cache逐参数说明:
--img 640:输入分辨率。横幅长宽比大,640 对细长条幅会压缩得厉害,如果小目标漏检多,可以试--img 960,代价是显存和速度。--batch 16:批大小。显存不够就降到 8 或 4,yolov5 会自动做梯度累积补偿,但太小会影响 BN 层统计。--epochs 100:490 张图属于小数据集,100 轮通常够收敛,配合早停(--patience 30)能防过拟合。--weights yolov5s.pt:从官方预训练权重起步,小数据集上迁移学习比从头训稳得多,这是血泪经验。--hyp hyp.scratch-low.yaml:小数据集建议用 low 增强配置,避免过强增强把本就少的样本「变没」。--cache:把图像缓存到内存,490 张图完全放得下,能明显加速每个 epoch。
3.3 超参数取舍与常见误用
小数据集训练最怕两件事:过拟合和欠拟合,而它们的表象都是「指标不好看」,得会区分。
学习率方面,hyp.scratch-low.yaml里lr0默认 0.01,490 张图我一般会降到 0.005 甚至 0.001,因为样本少、梯度噪声大,学习率太高 loss 会震荡不收敛。如果你看到 loss 曲线像心电图一样上下跳,先把lr0砍半。
锚框(anchor)方面,yolov5 默认锚框是基于 COCO 聚类的,横幅这种极端长宽比目标可能不匹配。常见做法是跑一次自动锚框:
python train.py --data ./banner_dataset/data.yaml --img 640 --batch 16 --epochs 10 --noautoanchor False--noautoanchor False会让 yolov5 在训练前用你的数据重新聚类锚框,横幅检测上这一步经常能带来几个点的 mAP 提升。注意聚类需要足够样本,490 张勉强够,如果只有几十张就别折腾了。
数据增强方面,hyp.scratch-low.yaml里mosaic默认 1.0,但横幅长宽比特殊,mosaic 拼接后可能产生不真实的组合。如果验证集 mAP 一直上不去而训练 loss 很低,试着把mosaic降到 0.5 看看。这些都是没有标准答案的调参,得靠你自己在验证集上试。
3.4 训练结果验证与指标解读
训练完在runs/train/banner_exp/下会生成一堆文件,重点看三个:
results.png:loss 和 mAP 曲线。训练 loss 降、验证 loss 也降,说明在学;训练 loss 降、验证 loss 升,过拟合,减 epoch 或加增强。confusion_matrix.png:混淆矩阵。单类别就看 TP/FP/FN,FP 多说明误检,FN 多说明漏检。weights/best.pt:验证集上表现最好的权重,这才是你要拿去推理的。
用验证集跑一次评估:
python val.py \ --data ./banner_dataset/data.yaml \ --weights runs/train/banner_exp/weights/best.pt \ --img 640 \ --conf 0.25 \ --iou 0.45--conf 0.25是置信度阈值,--iou 0.45是 NMS 的 IoU 阈值。横幅检测里如果相邻横幅挨得近,--iou调高到 0.5~0.6 能减少误抑制;如果误检多,--conf提到 0.4 试试。这些阈值没有万能值,得看你的业务对漏检和误检哪个更敏感。
4. 直接调用训练好的模型:推理、导出与部署前检查
不是每个人都有 GPU 从头训,这份资源里带了训练好的best.pt,对只想快速验证效果的人,直接推理是最短路径。但「能推理」和「推理结果可信」是两回事,这一章讲怎么把权重用起来,以及用之前该检查什么。
4.1 单图与批量推理
yolov5 的推理接口很统一,单图和批量都能走detect.py:
# 单张图推理 python detect.py \ --weights weights/best.pt \ --source ./test_banner.jpg \ --img 640 \ --conf 0.25 \ --save-txt \ --save-conf # 批量推理整个文件夹 python detect.py \ --weights weights/best.pt \ --source ./test_images/ \ --img 640 \ --conf 0.25 \ --project runs/detect \ --name banner_test--save-txt会把检测框按 YOLO 格式存成 txt,--save-conf额外保存置信度,方便你后续做阈值筛选。批量推理时--project和--name控制输出目录,别让结果散得到处都是。
4.2 Python 脚本内嵌调用
如果要把检测集成到自己的服务里,直接调 Python API 更灵活:
import torch from PIL import Image # 加载模型,指定设备 model = torch.hub.load('./yolov5', 'custom', path='weights/best.pt', source='local') model.conf = 0.25 # 置信度阈值 model.iou = 0.45 # NMS IoU 阈值 model.classes = [0] # 只保留 banner 类 # 推理 img = Image.open('test_banner.jpg') results = model(img) # 提取检测框 df = results.pandas().xyxy[0] for _, row in df.iterrows(): print(f"类别: {row['name']}, 置信度: {row['confidence']:.3f}, " f"框: ({row['xmin']:.0f},{row['ymin']:.0f},{row['xmax']:.0f},{row['ymax']:.0f})")逻辑说明:source='local'表示用本地克隆的 yolov5 仓库而不是联网拉取,离线环境必须加。model.conf、model.iou、model.classes是推理时的三个核心旋钮,classes=[0]在单类别时可有可无,多类别时能过滤掉不关心的类。results.pandas()返回 DataFrame,字段名直观,适合快速接业务逻辑。
4.3 模型导出与部署前检查
要在边缘设备或非 Python 环境部署,得先导出。yolov5 支持 ONNX、TensorRT、OpenVINO 等:
# 导出 ONNX,动态 batch 方便服务化 python export.py \ --weights weights/best.pt \ --include onnx \ --img 640 \ --batch 1 \ --dynamic # 导出 TensorRT(需要 GPU 和 tensorrt 环境) python export.py \ --weights weights/best.pt \ --include engine \ --img 640 \ --device 0 \ --half--dynamic让 ONNX 支持动态 batch 和动态输入尺寸,服务化时更灵活;--half用 FP16 精度,TensorRT 上能提速但可能掉一点点精度。导出后务必用同一张图对比原模型和导出模型的输出,确认框位置和置信度基本一致再上线——我见过导出后坐标全偏的,就是预处理没对齐。
部署前检查清单:输入尺寸是否和训练一致、归一化方式是否一致(yolov5 是 /255)、NMS 阈值是否和验证时一致、类别顺序是否和data.yaml一致。这四项任何一项不一致,结果都会「看起来能跑但就是不对」。
5. 避坑与排查:横幅检测训练里最容易翻车的五件事
这一章是我自己踩过和帮别人排查过的真实问题,按「现象 → 原因 → 解决」写。490 张图的小数据集,坑往往不在算法本身,而在数据和配置的细节里。
5.1 训练 loss 正常但 mAP 接近 0
现象:训练跑完,loss 曲线看着挺健康,但验证集 mAP 是 0 或者 0.001 这种离谱值。
原因:九成是标签路径或格式问题。要么labels目录和images没对应上,要么标签里的坐标没归一化(写成了像素值),要么class_id超出了nc范围。yolov5 对找不到标签的图会当负样本处理,所以 loss 照降,但模型学的是「全是背景」。
解决:先跑一遍官方自带的标签检查脚本,或者手动抽查几张图的标签。用python -c读一张标签,确认五个值都在 0~1 之间,class_id小于nc。再确认images/train/xxx.jpg对应的labels/train/xxx.txt存在。这一步别偷懒,我一般会写个三行脚本统计标签文件数和图像文件数是否相等。
5.2 显存溢出(CUDA out of memory)
现象:训练刚开始或跑几个 batch 后报RuntimeError: CUDA out of memory。
原因:--batch或--img设太大,或者--cache把图像全塞进显存(注意--cache默认是 RAM,但某些配置下会占显存)。横幅图如果分辨率很高,640 的输入也可能吃紧。
解决:先把--batch降到 8 或 4,再把--img从 640 降到 512 试。如果还爆,去掉--cache。另外确认没有其他进程占着显存,nvidia-smi看一眼。yolov5 的--batch支持-1自动模式,会按显存自动选,但自动值有时偏保守,手动调更可控。
5.3 验证集 mAP 远低于训练集表现
现象:训练集上检测框又准又全,验证集上漏检误检一堆。
原因:典型过拟合。490 张图对 yolov5s 来说偏少,模型把训练集「背」下来了。也可能是训练集和验证集分布不一致,比如验证集里全是某种特殊形态的横幅,训练集里没有。
解决:先加增强,hyp.scratch-low.yaml里把mosaic、scale、hsv_h/s/v适当调高;再减模型容量,从 yolov5s 换到 yolov5n;最后考虑早停,--patience 20让它在验证指标不升时自动停。如果验证集分布确实特殊,那得补数据,不是调参能救的。
5.4 推理时检测框位置偏移或尺寸不对
现象:用best.pt推理,框能出来但位置偏了,或者框比实际目标大一圈小一圈。
原因:推理时的输入尺寸、预处理和训练时不一致。最常见的是训练用 640,推理用了默认的 640 但图像 letterbox 填充方式不同,或者自己写预处理时忘了保持长宽比。
解决:统一用 yolov5 的detect.py或model(img)接口,它们内部会做一致的 letterbox。如果自己写预处理,务必复刻 yolov5 的letterbox函数:等比缩放 + 灰边填充 + 坐标还原。导出 ONNX 后坐标偏移,多半也是预处理没对齐,用同一张图对比原模型和 ONNX 输出即可定位。
5.5 长条横幅漏检严重
现象:方形展板检测得挺好,细长条幅(长宽比超过 8:1)大量漏检。
原因:默认锚框是基于 COCO 聚类的,没有覆盖极端长宽比;640 输入下细长条幅被压缩后特征几乎消失。
解决:跑自动锚框聚类(前面 3.3 提过),让锚框适配你的数据;把--img提到 960 或 1280,给细长目标更多像素;如果还不行,考虑切片推理(把大图切成重叠小块分别检测再合并),这是横幅检测里对付超长目标的常用手段。代价是推理变慢,得权衡。
6. 把 490 张用出 4900 张的效果:小数据集的进阶玩法
490 张图训一个能用的模型没问题,但要上线到真实业务,泛化能力往往不够。这一章讲几个我实际用过、能把小数据集价值放大的技巧,最后收在一个我自己的习惯上。
6.1 用已训权重做半自动标注
这是小数据集扩标最省力的路子。你手上已经有best.pt了,拿它去推理一批未标注的新图,把置信度高的检测框导出成 YOLO 标签,人工只做修正,比从零画框快好几倍。
# 对未标注图片批量推理,保存 YOLO 格式标签 python detect.py \ --weights weights/best.pt \ --source ./unlabeled_images/ \ --img 640 \ --conf 0.5 \ --save-txt \ --save-conf \ --project runs/pseudo_label \ --name round1--conf 0.5比正常推理高,是为了只保留高置信度框,减少人工修正量。导出的 txt 在runs/pseudo_label/round1/labels/下,直接拷进数据集就能用。注意伪标签一定有噪声,--conf设太低会把误检也标进去,反而污染数据。我一般会分两轮:第一轮 0.5 阈值扩一批,重训后再用新模型跑第二轮 0.6 阈值,逐步提纯。
6.2 数据增强的针对性配置
通用增强之外,横幅检测有几个针对性增强值得开:
| 增强项 | 参数 | 作用 | 注意 |
|---|---|---|---|
| mosaic | 0.5~1.0 | 拼接四图,增加背景多样性 | 太高会产生不真实组合 |
| mixup | 0.1~0.2 | 图像混合,抗过拟合 | 太高会让目标变模糊 |
| copy-paste | 需自定义 | 复制目标粘贴到其他图 | 对稀有形态横幅有效 |
| perspective | 0.0005 | 透视变换 | 模拟拍摄角度变化 |
| scale | 0.5 | 缩放 | 覆盖不同距离的横幅 |
copy-paste 是横幅检测里特别有效的一招:把训练集里的横幅框抠出来,随机粘贴到其他图的合理位置,能凭空造出大量样本。yolov5 原生不带这个,得自己写,但逻辑不复杂——读标签、抠图、随机位置粘贴、更新标签。代价是粘贴位置可能不自然,需要控制粘贴区域(比如只贴在天空、墙面等合理背景)。
6.3 用验证集反推数据缺口
训练完别只看 mAP 数字,把验证集上的漏检和误检样本挑出来看,能直接告诉你数据缺什么。我一般会跑一遍验证并保存预测结果,然后按置信度排序,看低置信度的 TP 和 FP 长什么样。
# 验证并保存预测结果到 json python val.py \ --data ./banner_dataset/data.yaml \ --weights runs/train/banner_exp/weights/best.pt \ --img 640 \ --conf 0.001 \ --iou 0.6 \ --save-json \ --project runs/val \ --name analysis--conf 0.001故意设极低,是为了把所有候选框都留下来分析,正常推理不会用这么低的值。拿到 json 后按类别和置信度分组,漏检多的形态就补对应数据,误检多的场景就加负样本。这个「看错误反推数据」的循环,比盲目加数据有效得多。
6.4 一个我坚持了很久的习惯
小数据集训练最怕的不是调参,是「不知道自己不知道」——模型在验证集上 0.9 的 mAP,上线后一塌糊涂,因为验证集和真实场景分布差太远。从那以后我每次拿到小数据集,都强制先做一件事:从真实业务场景里抽 20 张图,不放进训练也不放进验证,单独留作「上线前测试集」。训练全程不碰它,等模型定稿了拿它跑一遍,这个数字才是我敢不敢上线的依据。490 张图里抽 20 张出来做这件事,训练少一点数据,换来的是对模型真实能力的清醒认知,值。希望这个习惯也能帮到你。
本文还有配套的精品资源,点击获取