简介面向目标检测算法研究与智能交通应用开发这份资源提供了斑马线、行人、交通灯三类别的高质量图像数据集源码包。数据源自12554张国内城市道路与郊区行车记录仪实拍图像覆盖阴晴雨雾等多样光照共标注83546个实例其中行人59014个、交通灯13826个、斑马线10706个经YoLoV5 m6权重训练300轮后mAP0.5达0.956mAP0.5~0.95为0.7299适合YoLo系列模型快速迁移训练也可用于城市安全监控、交通流量分析等场景。压缩包共6个文件主要包含txt数据说明、Markdown文档、HTML预览页、LICENSE许可以及配置文件等整体仅9KB内容精简便于快速查阅与二次开发。目前已有53人学习查看对需要复现目标检测实验或扩充训练集的算法入门者与研究人员提供了可验证的标注数据和清晰的结构化说明能有效降低数据采集与标注成本。1. 斑马线行人交通灯数据集把路口感知的三个关键目标绑在一起做辅助驾驶感知的人都有过这种经历行人检测模型在普通路段跑得很好一进路口就漏检交通灯识别单独验证精度很高可放到带斑马线的真实场景里行人和灯同时出现时两个模型各自输出的结果在时间上对不上。斑马线行人交通灯数据集解决的就是这个脱节问题——它把斑马线、行人、交通灯三类目标放进同一批图像里统一标注训练一个能同时输出三类检测结果的模型而不是拼凑三套独立系统。这类数据集通常附带了完整的训练与推理源码适合做辅助驾驶感知、路口视频监控、车路协同算法验证的团队直接拿来做迁移训练。本文沿着从数据格式、源码跑通到调参避坑的完整路径展开说明白怎么做、参数怎么设以及哪些地方容易翻车。2. 数据组成与标注口径三类目标各自的标签规范2.1 三类目标的标注难点与常见口径斑马线行人交通灯数据集的核心价值不是图片数量而是标注口径。斑马线是一个区域性的面目标行人是一个会变形的框目标交通灯是一个带有状态属性的小目标三种目标用一套标准很难统一表达。标注口径上常见做法是采用三类别目标检测格式把交通灯的灯色红、黄、绿、灭作为附加属性处理。如果源码基于COCO JSON格式通常会有一个attributes字段存放灯色如果基于YOLO txt格式有的实现会把灯色拼到类别里比如traffic_light_red、traffic_light_green有的则保留单一traffic_light类别再额外给一个属性文件。两种方式没有绝对对错但要在一开始就定死否则后面训练和评估都会出问题。我一般会建议如果业务只关心“有没有灯”就用单一traffic_light类别如果业务要做红绿灯状态判断比如辅助驾驶需要知道当前能否通行就把灯色拆成多个类别。前者模型简单、数据利用率高后者需要额外保证各颜色样本均衡不然绿灯多红灯少训练出来的模型会偏好预测绿灯。斑马线的标注边界是最容易产生分歧的地方。有的标注人员习惯沿着白色条纹的外接矩形画框有的会把整个路口区域都框进去还有的只标包含条纹的最小矩形。数据集的源码里通常会在标注规则文档中写明“以斑马线白色条纹组的最外围为边界包含进入区域的虚拟延长线”。实际使用前先抽几十张图确认标注是否遵循统一规则这一步能省下后面大量返工时间。行人标注相对直观但要注意遮挡和截断。真实路口场景中行人之间互相遮挡、被车辆遮挡、人只露出半边身体的情况非常多。多数数据集的规则是可见部分超过整体面积的 30% 就标小于 30% 不标被车辆完全遮挡的瞬间不标。这个阈值直接决定了模型在密集路口的漏检率。如果发现训练后的模型对遮挡行人不敏感先回头查标注阈值是不是标得太严格。2.2 数据目录与标注文件从采集到划分的落地组织拿到带源码的斑马线行人交通灯数据集后第一步不是急着训练而是把目录结构理清楚。常见做法是采用如下数据组织方式crosswalk_dataset/ ├── images/ │ ├── train/ │ ├── val/ │ └── test/ ├── labels/ │ ├── train/ │ ├── val/ │ └── test/ ├── annotations/ │ ├── instances_train.json │ └── instances_val.json ├── data.yaml └── README.mdimages目录放原始图像labels目录放YOLO格式的txt标注annotations目录放COCO JSON格式标注data.yaml描述类别和路径。之前说过不要同时依赖两套标注做训练——源码里可能提供了格式转换脚本但每次转换都可能引入坐标归一化的精度误差尤其是小目标交通灯坐标转换时小数点后第四位的误差都会在图像上偏出好几个像素。数据划分是另一个容易被忽略的环节。如果图像来自连续视频抽帧直接把所有帧随机分成train和val很容易出现同一辆车、同一个人在相邻帧里同时出现在训练集和验证集的情况导致验证集指标虚高。更合理的划分是以“镜头片段”或“路口”为单位切分import os import random from collections import defaultdict # 读取所有图像按视频片段前缀分组 image_dir crosswalk_dataset/images/all groups defaultdict(list) for fname in os.listdir(image_dir): # 假设文件名格式: clip_id_frame_number.jpg clip_id fname.rsplit(_, 1)[0] groups[clip_id].append(fname) # 按片段划分保证同一片段的所有帧进同一个集合 clip_ids list(groups.keys()) random.shuffle(clip_ids) train_clips clip_ids[:int(len(clip_ids) * 0.7)] val_clips clip_ids[int(len(clip_ids) * 0.7):int(len(clip_ids) * 0.85)] test_clips clip_ids[int(len(clip_ids) * 0.85):] def split_to_dir(fnames, src_img, src_lbl, dst_img, dst_lbl): os.makedirs(dst_img, exist_okTrue) os.makedirs(dst_lbl, exist_okTrue) for fname in fnames: img os.path.join(src_img, fname) lbl os.path.join(src_lbl, fname.replace(.jpg, .txt)) if os.path.exists(lbl): os.rename(img, os.path.join(dst_img, fname)) os.rename(lbl, os.path.join(dst_lbl, fname.replace(.jpg, .txt))) split_to_dir([g for clip in train_clips for g in groups[clip]], images/all, labels/all, images/train, labels/train)这段脚本的关键是按文件名中的片段前缀做分组随机打乱的是片段而不是单帧。参数train_clips:val_clips:test_clips我这里用的是 7:1.5:1.5你可以按自己的数据量调整数据量大可以给验证集更多比例数据量小就要保证验证集每个类别至少有几十个实例否则指标波动会很大。划分完之后一定要做一次样本统计按类别数一数train和val里各有多少目标框。常见做法是写一个几行的统计脚本跑完打印出类似“crosswalk: 1200, pedestrian: 8500, traffic_light: 2300”这样的结果。如果发现val里某个类别样本太少后面训练出来的模型对该类别的AP曲线会像心电图一样剧烈抖动不是模型不行是验证样本不够。3. 源码快速跑通从数据集到第一次训练的最小命令3.1 源码结构里先看哪几个文件拿到源码包不要急着点训练先花十分钟把代码结构过一遍。一个成熟的斑马线行人交通灯数据集源码包通常包含如下几部分数据加载器、模型定义、训练循环、评测脚本、配置文件和推理可视化脚本。我一般会先看数据加载器因为数据集的坑大多藏在读数据的地方。数据加载器里最值得关注的是标注读取逻辑。如果源码同时支持COCO JSON和YOLO txt两种格式看默认启用哪个。常见的实现会通过data.yaml里的一个字段控制比如format: yolo或format: coco。这里有一个血泪教训不要认为两种格式表示的标注内容完全等价YOLO格式的坐标是归一化到 0~1 的COCO格式的坐标是像素绝对值两者混用会直接导致训练出来的模型框的位置整体偏移目标越小偏移越明显。模型定义部分不用全部看懂但要知道主干网络的类型和输入分辨率。源码里一般会在配置文件中写明img_size: 640或input_size: [640, 640]。这类路口场景的检测任务输入分辨率建议至少 640如果显卡允许可以上 1280。斑马线和行人属于中大目标交通灯属于小目标分辨率达不到这个水平交通灯类别基本就废了。训练循环部分主要看两处学习率调度策略和损失函数。多数源码默认带CosineAnnealing调度这个不用改损失函数如果是CIoU加上类别平衡权重直接可用。真正需要改的是源码里写死的类别数量新手最容易在这里翻车——源码默认是 80 类或 20 类加载自己的斑马线行人交通灯数据集前需要把配置改成 3 类同时改掉数据配置文件中类别名称列表。3.2 数据配置文件的改动点与启动命令以源码包自带的YOLO格式训练入口为例训练前需要改两个文件数据配置文件和一个可选的模型配置文件。数据配置文件的典型内容如下path: ./crosswalk_dataset train: images/train val: images/val test: images/test names: 0: crosswalk 1: pedestrian 2: traffic_light这里是直接用框架约定的相对路径path指数据集根目录train和val分别用训练集和验证集镜像目录的相对路径。names的索引必须和标注txt文件里每行开头的类别id对应。标注txt里0 0.5 0.5 0.2 0.1的行类别0就是斑马线这个对应关系不能乱。模型配置文件里一般只需要改nc字段nc: 3nc就是类别数量改成 3。如果数据集踏踏实实按 2.2 节的划分脚本整理过目录结构没有问题第一次启动训练的命令非常短python train.py --data crosswalk_dataset/data.yaml --weights base_model.pt --epochs 100 --batch 16 --imgsz 640 --device 0--data指向数据配置文件--weights是预训练权重--epochs 100是训练轮数--batch 16是批大小--imgsz 640是输入图像尺寸--device 0指定使用第一张显卡。第一次训练建议用--epochs 30快速跑通确认数据能正常加载、loss能下降再加到完整轮数不然配错了数据路径白白等几个小时。跑通后看日志里有没有输出每类别的AP指标。很多源码在验证阶段会打印crosswalk_ap,pedestrian_ap,traffic_light_ap三行。如果某行是0先不要怀疑训练问题大概率是该类别在val标签中压根没出现。常见的排查方法是用源码自带的inspect_labels.py脚本统计验证集标注而不是自己肉眼翻图片。训练时看到训练loss下降但验证loss不降要立刻停止回头检查是不是验证集合混入了训练帧或者数据增强配置过度。4. 训练参数与调优让三个类别各自收敛的配置思路4.1 基础训练参数与类别权重的设置斑马线行人交通灯数据集的训练调参不能把三个类别当成三个独立任务分别调因为你最终部署时是一个模型同时输出三类结果。一个常见的错误是只盯着整体mAP调参结果整体指标涨了交通灯的小目标AP反而掉了。基础参数设置上学习率一般保持源码默认即可比如lr00.01搭配Cosine调度。真正需要精心调的是输入分辨率和训练增强策略。斑马线是长条形大目标行人是不规则目标交通灯是小目标三者共存要求增强策略不能太激进。比如Mosaic增强会把四张图拼在一起小目标交通灯很可能被裁剪到只剩一点点边缘模型学不到有效特征。这类数据集源码里如果默认开了Mosaic运行到后半程训练时可以考虑关闭python train.py --data crosswalk_dataset/data.yaml --weights base_model.pt --epochs 100 --batch 16 --imgsz 640 --mosaic 0 --close_mosaic 10这里--mosaic 0表示关闭Mosaic增强--close_mosaic 10表示训练最后10个epoch提前关闭。实际经验是训练后三分之一阶段关闭Mosaic能让小目标AP明显回升。类别权重是另一个必要调整项。斑马线在图像里通常占据大面积目标框数量少但容易学习行人目标框数量多模型天然会偏向它交通灯目标框小、数量中等是最容易欠拟合的类别。常见做法是在数据配置文件中显式指定类别权重cls_weights: 0: 1.0 1: 0.8 2: 1.5类别权重的含义是给不同类别的损失乘上不同系数。crosswalk设1.0作为基准pedestrian降到0.8是因为它的样本量多降权避免模型过于关注行人而忽略其他类别traffic_light设1.5是给它更高的损失权重强迫模型关注小目标。这个值的调整原则是以多数类为基准少数类和难例类给更高权重。交通灯如果夜间样本特别少可以加到 2.0但不要超过 3.0太高会导致模型过拟合地偏向交通灯反而拉低行人AP。4.2 按检测难度分批迭代的调参顺序训练调参不推荐一次性把所有参数都改了那样翻车了根本不知道是哪个参数引起的。我的做法是把调参拆成两轮。第一轮只用基础参数训练100个epoch得到一组基线指标。这一步的目标不是追求最高精度而是验证数据标注质量、划分是否合理、模型能不能正常收敛。跑完后记录三类别的AP值和loss曲线形态。如果训练loss和验证loss同步下降且最后趋于平缓说明数据和代码没问题可以进入第二轮。第二轮才开始动增强和权重参数。重点关注训练过程中有没有出现过拟合信号验证loss在训练loss继续下降时反而上升这说明模型开始死记训练集特征。解决手段依次是调大数据增强强度但注意小目标问题、降低训练轮数、增加验证集样本。斑马线这类纹理特征明显的大目标很容易被模型当成背景纹理记忆下来如果一个模型在训练集上斑马线AP接近满分而验证集明显偏低就是典型的过拟合了。分批迭代的节奏建议以验证集指标回退为信号每次只改一个参数跑完对比上一轮变好就保留变差就回退。等三个类别的AP都稳定后最后再用测试集跑一次完整评估。测试集在整个调参过程中要完全不用否则它会变成第二个验证集最终指标会被调参过程污染。5. 斑马线行人交通灯数据集的常见问题与避坑清单5.1 标注口径不一致同一个目标两种标签现象训练出来的模型在验证集上斑马线AP很高但实际跑路口视频时斑马线框不住整条斑马线只框住了一组条纹而且框的位置忽左忽右。原因数据集中不同批次的标注人员对斑马线边界的理解不一致一部分人按条纹组最外侧画框另一部分人按路面施划区域整体画框。模型在两种标注之间摇摆学到的框既不完整也不稳定。解决训练前先做标注一致性检查。抽取10%的样本用标注可视化脚本把标签画到图上人眼确认看斑马线框的覆盖范围是否统一。如果发现两个版本的口径同时存在写一个后处理脚本把所有斑马线框统一放宽到覆盖整个条纹区域而不是重新标注那样成本太高。如果源码提供的是COCO JSON标注直接在JSON里修改坐标再转回YOLO格式会更快。5.2 夜间路口小目标行人漏检现象白天场景看起来一切正常一旦视频切到夜间能检测到斑马线和交通灯但行人漏检严重特别是穿深色衣服、站在斑马线边缘的行人框要么不出来要么置信度极低。原因夜间光照不足导致行人目标对比度低且数据集中夜间样本占比不够。多数公开的路口数据集白天帧占七成以上夜间帧本身少夜间行人更少。模型没有见过足够多的低照度行人特征自然学不会。解决先统计数据集中夜间帧的比例如果低于15%需要额外补充夜间拍摄数据。补充数据后做针对性增强随机降低图像亮度、加高斯噪声、模拟车灯过曝效果。调参上可以考虑把这部分夜间样本单独分成一个验证子集每次训练后单独跑夜间子集的AP而不是只看整体指标。如果源码里没有现成的夜间子集评估脚本花一个小时自己写一个简单的按文件名关键词过滤的脚本也值得。5.3 验证集与训练集同源导致的指标虚高现象训练结束后验证集mAP高达0.85模型部署到新的路口视频上效果却很差行人AP从0.8掉到0.4。原因数据划分时没有按视频片段切分同一辆车、同一个行人在相邻帧中既出现在训练集又出现在验证集。模型相当于已经“背过”验证集的内容新场景一到就暴露了泛化不足。解决严格按照2.2节的方式按片段划分数据。这是数据集使用中最容易埋雷的环节没有之一。源码包里如果自带了划分脚本先确认它是不是按时间序列分组如果只是随机划分务必改成按片段分组再重新划分。另一个补充手段是额外录制一段完全没有进入过训练流程的路口视频作为最终验证这段视频上的表现才是真正靠谱的交付指标。5.4 交通灯状态类别与颜色类别混用现象模型输出里交通灯同时出现traffic_light和traffic_light_red两种标签评估时这两种标签各自算一类导致交通灯的整体指标被拆碎AP看起来很低。原因数据集源码版本升级过程中标注格式从单一类别改成了分色类别但训练配置和评估脚本没有同步更新代码自动把两种格式的标签都读进去了。解决定好“源码采用的标注体系”为唯一基准另一套体系在数据预处理阶段就转换掉。如果源码默认是分色类别就去掉标注文件里所有不带颜色后缀的交通灯标签如果源码默认是单一类别就把分色标签全部合并成traffic_light。这一条属于源码使用中的典型环境问题建议每个项目开始前先跑一个label_inventory.py统计所有标签类别名的分布能第一时间发现这种混用。5.5 类不平衡导致行人压过交通灯现象训练初期行人loss降得很快交通灯loss几乎不动。训练到后期整体mAP看着还行但交通灯AP始终低于30%。原因行人目标数量远超交通灯且交通灯是典型的小目标网络浅层特征图上几乎没有它的位置信息深层特征图又把它和背景混在一起。模型把容量都花在了“好学的”行人上。解决除了4.1节提到的类别权重还要从数据层面做补充。一个有效做法是把包含交通灯的原图按需要裁切增强让小目标在图像中的占比相对变大。裁剪不是在训练时用随机裁剪而是在预处理阶段针对交通灯密集的区域生成一批裁切图把这些图加入训练集。这样做之后交通灯AP通常能提升5到10个点代价是训练时间变长、行人AP可能小幅下降整体收益是正的。6. 验证模型的一线技巧按场景拆指标而不是只看mAP斑马线行人交通灯数据集这个方向最终交付给业务方时对方不会只看一个整体mAP他们更关心的是“斑马线、行人、交通灯在哪些场景下会同时出问题”。所以我的验证习惯是每次训练结束跑完标准测试集后再额外做一次场景拆分验证。按类别拆分已经不够要按时间段和位置拆。常见做法是把测试集按“白天直行”“白天转弯”“夜间直行”“夜间转弯”四个子集拆开分别计算三类别AP。斑马线检出精度在四个子集里通常比较稳定行人AP在夜间直行会明显掉交通灯AP在白天转弯场景中会因为视角倾斜而下降。把这些数字列出来往后调参时优先级就清楚了先解决掉点最明显的组合场景。可视化验证比数值更有说服力。我一般会固定选取几个有代表性的路口视频片段包含行人遮挡、夜间过曝、交通灯被树枝遮挡等典型情况每次训练完成后用同一个推理脚本跑一遍把检测结果逐帧存成视频。这个固定片段不进入训练和调参流程只看不调它相当于模型交付前的“路测”。有一次我用整体AP 0.82的模型去跑固定片段结果发现三帧里出现一次行人框的置信度抖动连续帧之间同一行人被检测成不同类别ID这种问题靠整体指标永远看不出来只有逐帧看视频才发现。后来养成的习惯是每版模型都必须跑一次固定视频片段把检测框的中心点坐标导出成CSV检查相邻帧的坐标跳变幅度。交通灯的时序一致性也值得单独验证。如果一个红色的交通灯在连续多帧中一会儿被识别为红色一会儿被识别为绿色这在辅助驾驶场景中是致命的。我给这类数据集源码补的最后一个工具是一个简单的时序投票后处理统计同一位置交通灯在最近5帧中的识别结果取众数作为当前帧输出。这不算什么高级算法但实测可以减少约60%的灯色闪烁误报。这条路上最大的教训不是模型不够复杂而是数据集的口径和验证方式永远比模型结构更值得花时间。如果你拿到的斑马线行人交通灯数据集源码没有附带按片段划分的脚本那第一件事就是把它补上如果你发现验证集里混入了训练帧任何调参都只是在自欺欺人。希望这篇整理能帮你少走几趟这些弯路。本文还有配套的精品资源点击获取