ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

YOLO11夜间行人检测:5000张数据集与三平台训练全攻略

YOLO11夜间行人检测:5000张数据集与三平台训练全攻略 简介面向目标检测与夜间行人检测任务这份资料提供了一套包含5000张夜间低光真实场景图像的完整数据集方案覆盖夜间街景、道路行人以及不同程度遮挡、严重遮挡等常见监控场景并配齐VOC、COCO、YOLO三种主流标注格式可直接用于YOLO等算法训练。资料以PDF文档形式呈现共1个文件压缩包大小6.07MB内部除数据集基本情况外还说明了labelimg标注规范与百度网盘获取方式因原始图像数据体量较大实际图片与标签需通过网盘下载。目前已有611人学习浏览。除了数据集介绍文档还给出YOLO11一键训练脚本的使用说明支持GPU、CPU、MacM芯片多平台运行并附有博主实测的训练结果日志可作为调参与效果评估的参考。对监控场景夜间行人检测项目或想补充夜间数据集的算法开发者而言这份资料能减少数据整理与训练配置的重复工作快速进入模型验证阶段其中的场景划分与标注细节也能为自建夜间数据集提供参考。1. 夜间行人检测为什么总让模型“翻车”从数据集说起夜间行人目标检测一直是目标检测落地里最磨人的场景之一。白天跑得挺好的模型一换到夜间场景漏检率和误检率同时飙升——不是模型结构不够新而是训练数据的分布根本对不上。城市夜间光照低、色偏严重、行人轮廓与背景对比度差再加上车灯、路灯、广告牌造成的过曝和光晕行人目标在画面里往往是“半个人影”的状态。这时候如果手里只有白天数据YOLO11再强也白搭。这篇文章要讲的是一个能直接拿去用的完整方案一份5000张图的夜间行人数据集配套VOC/COCO/YOLO三种格式的标签外加一套支持GPU(GPUs)/CPU/Mac三平台跑的YOLO11一键训练脚本。拆开来看它实际解决的是三个问题夜间数据从哪来、标注格式怎么统一、不同硬件环境下怎么把训练跑起来。对刚接触YOLO训练自己的数据集的初学者以及被夜间场景搞到头大的算法工程师这套组合都能省下大量时间。下面按我的落地经验把这个方案里的数据规格、脚本逻辑和踩坑点一层层拆开讲清楚。2. 5000张夜间行人图数据规模、标注质量与三种格式的转换逻辑拿到一份数据集先别急着开训。5000张图这个量级放到深度学习里不算大但也不小关键是看它怎么分布的。夜间场景数据集的坑在于“看似数量够、实则多样性不足”如果5000张图全是从同一段视频里抽帧来的那模型学到的只是那条路的夜间样子换个路口就废了。所以拿到数据后第一步不是训练而是做数据体检。2.1 数据分布体检光照等级、场景多样性和目标尺度我一般会先写个脚本把所有图片按亮度分桶统计看看暗光、微光、强光干扰各占多少比例。夜间行人数据最理想的状态是三档均匀分布——天黑但路灯清晰、完全无光照靠车灯补光、以及画面里有强光源直射的复杂场景。如果某一档占比超过70%模型训练出来的效果就会偏向那个档位。import cv2 import numpy as np import glob img_paths glob.glob(night_pedestrian/images/*.jpg) buckets {dark: 0, mid: 0, bright: 0} for p in img_paths: img cv2.imread(p) gray cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) mean_brightness gray.mean() if mean_brightness 60: buckets[dark] 1 elif mean_brightness 110: buckets[mid] 1 else: buckets[bright] 1 total len(img_paths) for k, v in buckets.items(): print(f{k}: {v} ({v/total*100:.1f}%))这段代码用OpenCV把图像转灰度后算平均亮度按阈值分成三档。阈值60和110是我在夜间数据上常用的分界值具体可以根据数据实际情况微调。跑完如果发现某档占比超过70%训练前最好做数据清洗把重复场景的帧删掉一些或者做亮度增强来扩充弱势档位。目标尺度分布同样重要。夜间行人在画面里经常是小目标——离摄像头远、只占图像几个百分点。跑数据标注工具统计一下所有标注框的宽高比和面积分布如果小目标占比很高训练时记得把imgsz调大、并开启多尺度训练否则模型对小目标几乎免疫。2.2 VOC/COCO/YOLO三格式并存同一批标签的三种“方言”同一份数据三种标注格式本质上就是同一种标注信息的不同序列化方式。VOC格式是一个XML文件对应一张图用object节点框出行人位置坐标是左上角加右下角绝对值。COCO格式是单个JSON文件用bbox字段存[x, y, width, height]坐标也是绝对值。YOLO格式最简单一个txt文件对应一张图存的是归一化后的center_x center_y width height。这套数据集好看就好在三种格式全给齐了省掉了最烦人的转换环节。但要注意实际训练时我用YOLO格式跑YOLO11COCO格式用来做模型评估对比VOC格式基本是留作存档或迁移到其他框架时备用。三类标签文件与图片同名前缀对应配合一个classes.txt内容是person一类因为行人检测不考虑性别年龄细分统一归person即可。2.3 标签自检训练前必做的三件事拿到别人给的标签别直接开训。我每次都会先跑一遍自检脚本确认三件事标签文件是否有缺失或空文件、坐标是否越界、类别ID是否连续从0开始。YOLO训练里最容易翻车的就是类别ID不连续——比如标签里只有class 0和class 5数据加载器会把5当索引越界处理或直接静默丢弃样本。# 统计有图无标签和有标签无图的情况 for img in images/*.jpg; do base$(basename $img .jpg) if [ ! -f labels/$base.txt ]; then echo missing label: $base fi done # 检查空标签文件大小为0 find labels -name *.txt -size 0 | wc -l这类脚本简单粗暴但有效能筛掉数据包里最常见的损坏样本。坐标越界的检查用Python跑一遍更快读每个txt文件的四列数据凡是归一化后大于1或小于0的直接标红。夜间数据集里这类问题尤其多见因为标注时如果图像经过裁剪或缩放标注工具没跟着同步更新坐标就会越界。遇到这类文件我的做法是直接删掉对应图片而不是尝试修复——5000张图删掉十几张坏的影响可以忽略但带着脏数据训练会污染整个验证集指标。3. 硬件差异下的环境准备GPU(GPUs)/CPU/Mac三平台权衡YOLO11训练脚本号称三平台通吃但“能跑”和“跑得动”是两回事。我自己在三种环境都试过这里面最核心的变量是显存和算力。GPU(GPUs)版本自然是首选但CPU和Mac也有各自的适用场景——比如小规模调参、断点续跑前的人工检查、或者机器上没有独立显卡的开发机。脚本的处理逻辑不是“一套参数打天下”而是自动探测硬件类型然后给出一套合理的默认配置。3.1 GPU(GPUs)环境CUDA版本与显存预算GPU训练最烦的不是训练本身而是环境里CUDA、PyTorch、显卡驱动三者版本对不上。YOLO11官方代码基于PyTorch不同版本的PyTorch对应不同CUDA编译版本。我的建议是直接用PyTorch官方给的安装命令而不是用conda默认源。显存大小直接决定batch size——8GB显存跑YOLO11ssmall版本用batch size 16比较稳超过就报CUDA out of memory。查看GPU是否可用的最快方式是在Python里跑一行代码验证而不是直接开训。我就翻车过一次训练跑了一个epoch才想起来看GPU利用率结果发现是0%——模型在CPU上裸跑了几个小时因为PyTorch编译的是CPU版本。每次新建环境、每张新机器上我先验证一次再谈训练。import torch print(torch.cuda.is_available()) # True 才说明CUDA可用 print(torch.cuda.get_device_name(0)) # 显卡型号 print(torch.cuda.mem_get_info()) # (可用显存, 总显存)多卡GPU(GPUs)的配置更敏感。YOLO11官方训练命令支持device0,1,2,3指定多卡这时候batch size会按卡数自动翻倍。但注意学习率也要跟着调——卡数翻倍学习率一般也要同步放大1.5到2倍否则多卡训练收敛速度反而慢。这个细节在脚本里会处理好但自己手动搭环境的话容易漏。3.2 CPU与Mac环境模型的正确打开方式CPU能训练但要选对模型尺寸。YOLO11nnano版本在CPU上训练5000张图单epoch大概需要十几分钟到半小时勉强能接受。YOLO11s在CPU上就要以小时为单位等epoch了。所以脚本在CPU环境下的默认模型是YOLO11n训练epoch数也会调低这是“能不能跑完”和“能不能出结果”之间的取舍。Mac平台的逻辑不同——脚本优先用mps后端跑GPU加速。MPS是苹果的Metal Performance ShadersPyTorch从1.12开始原生支持。MPS在推理速度和训练速度上都远快于纯CPU但要注意两个坑一是某些算子MPS还没实现遇到会报not implemented这个只能换代码路径或者用CPU兼容模式二是MPS上的数值精度和CUDA有微小差异同一个模型在Mac上训练出的mAP可能会比GPU低零点几个点做对比实验时要注意这个偏差。3.3 环境自检脚本别等训练跑起来才发现跑错设备我在三个平台都吃过“环境表面装好了、一跑就废”的亏所以总结出一个固定动作搭完环境先跑一个5行以内的自检脚本确认设备类型、PyTorch版本、能用内存/显存三个信息都正常再开始正式训练。import platform, torch print(OS:, platform.system()) print(PyTorch:, torch.__version__) if torch.cuda.is_available(): print(Device: CUDA, torch.cuda.get_device_name(0)) elif torch.backends.mps.is_available(): print(Device: MPS) else: print(Device: CPU)这个脚本同时把三个平台都覆盖了。输出Device: CUDA说明走的是显卡加速Device: MPS说明走的是Mac的GPU加速输出Device: CPU就是纯CPU算力。三类环境下YOLO11的推理代码完全一样只有训练时的batch size和epoch数需要手动调整。4. YOLO11一键训练脚本拆解从命令行到训出第一个权重文件三端环境就绪后终于可以碰这个核心训练脚本了。一键训练脚本的价值不在于它有多少新功能而在于把参数、路径、环境探测逻辑封装成了一套稳定的默认配置。我的使用习惯是先跑默认参数确认整条链路通再逐项调参做正式实验。这里的关键认知是要搞清楚脚本哪些参数是硬编码、哪些可以覆写、覆写的优先级是什么。4.1 脚本的目录约定数据放哪儿、结果落哪儿脚本能一键跑起来的前提是目录结构符合约定。我的标准目录是按YOLO官方训练惯例来的数据集文件夹里放images和labels两个子目录各拆成train和val两份。训练时脚本会自动读数据集根目录下的data.yaml文件里面写了训练集、验证集路径和类别名。# data.yaml path: ./night_pedestrian_dataset train: images/train val: images/val names: 0: person这个文件是整个训练链路的入口配置。用相对路径而不是绝对路径这样数据集挪到任何机器上都不用改配置。names只需要一行因为这个数据集只检测行人类别如果你以后往数据里加车辆、自行车类别就在标签文件里加类别ID同时把这里补上对应名字。4.2 一键训练脚本全貌模型选择、设备探测、超参数传递训练脚本的核心逻辑按顺序拆开看并不复杂。第一步是确定设备——脚本读环境变量或命令行参数如果没指定就自动探测第二步是按设备类型设置默认超参数第三步是拼接训练命令交给YOLO11的train接口执行。# train.py 核心逻辑 import torch import sys model_name sys.argv[1] if len(sys.argv) 1 else yolo11n.pt data_yaml sys.argv[2] if len(sys.argv) 2 else ./night_pedestrian_dataset/data.yaml if torch.cuda.is_available(): device 0 # 使用第一块GPU batch 16 epochs 150 elif torch.backends.mps.is_available(): device mps # Mac GPU加速 batch 16 epochs 100 else: device cpu batch 8 epochs 50 # CPU阶段只做验证性训练 from ultralytics import YOLO model YOLO(model_name) results model.train( datadata_yaml, epochsepochs, batchbatch, devicedevice, imgsz640, patience20, # 验证集连续20轮不涨就早停 lr00.01, augmentTrue )代码本身不新鲜关键在设备分支的处理逻辑。GPU(GPUs)环境下epochs给到150是因为夜间行人检测收敛比白天慢——低对比度样本的损失下降曲线更平缓Mac的MPS后端虽然能加速但稳定性不如CUDA给100轮是折中CPU环境只给50轮跑出来结果仅供参考确认链路通了就换GPU训正式的。patience20是早停机制验证集mAP连续20轮不提升就自动停止。这在夜间数据上尤其有用——夜间训练经常出现训练集损失还在降、验证集指标已经停滞的情况早停能防止模型过拟合到夜间的光影噪声上。imgsz640是速度与精度比较均衡的输入分辨率如果算力富余可以调到960小目标检测会明显变好。4.3 命令行参数覆写不改代码调实验脚本支持命令行传参调试时不用反复改Python文件。比如在GPU(GPUs)机器上想加大输入分辨率试试效果直接追加参数即可。python train.py yolo11s.pt ./night_pedestrian_dataset/data.yaml --imgsz 960 --batch 8命令行参数可以随时追加指定更高精度的模型和更大的输入分辨率。这里yolo11s.pt是带预训练权重的模型文件名脚本第一次跑会自动从官方GitHub下载权重文件大概几十MB网络不稳定的环境下如果报超时错误手动下载后放到当前目录即可。训练过程的日志会实时打印每个epoch的box_loss、cls_loss和mAP50指标我一般盯着mAP50的走向判断模型有没有在正常收敛——夜间场景mAP50能从0.1慢慢爬到0.7左右就算合格。5. 夜间行人训练避坑指南光照干扰、小目标漏检与过拟合训练脚本跑通只是第一步真正决定模型能不能用的是坑里爬出来的经验。夜间行人检测和白天场景的踩坑点差异非常大。按数据、训练、评估三个阶段我整理了几个反复踩过的坑每一条都是先描述现象再给解决路径。5.1 夜间数据增强过度导致过拟合“假象”第一个坑是增强策略过猛。Ultralytics默认开启大量数据增强——随机翻转、HSV色域变化、缩放、平移、马赛克拼接。白天数据吃这套增强没问题夜间数据本身就对比度低、颜色信息少再叠加HSV色域扰动和Cutout遮挡训练出来的模型会陷入一种奇怪的境地训练集loss很低验证集loss震荡不降直观表现就是夜间场景一换角度就疯狂漏检。现象背后是增强把“夜间的低光照特征”过度破坏模型学到的是增强后的纹理碎片而不是行人本身的轮廓结构。解决路径是收数据增强项。我一般把hsv_h、hsv_s、hsv_v三个值全部调低到默认一半以下关掉mosaic和mixup只用flip-lr和轻微scale。夜间行人检测的核心约束是“人和背景的边界”而不是“颜色多样性”所以对颜色类增强要克制。具体参数hsv_h0.01、hsv_s0.3、hsv_v0.2、mosaic0.0、mixup0.0格外的flip-lr默认开启即可。5.2 小目标漏检imgsz和anchor的配合问题夜间行人的另一个高频翻车点是远处小目标漏检。现象是近距离行人框得很准距离超过15米就完全无感。原因有两层5000张数据集里的标注框服从长尾分布——小目标样本数量本来就少同时imgsz640相当于把原图缩放远处的行人缩成十几个像素特征图上的响应完全被噪声淹没。解决路径分两步走。input分辨率上调到960模型在特征图上保留的小目标信息会多一些代价是训练时间增加约30%。同时看数据里小目标占比如果小目标比例超过20%考虑用Ultralytics内置的SAHI切片推理——把大图切成小块分别检测再合并结果这个方案对小目标的提升非常明显。如果切块推理速度不满足也可以试试给标签里的目标按面积分层采样训练时让模型多看到小目标样本。5.3 跨场景泛化崩塌验证集要有“没见过的路”这是最容易被忽略、也是模型上线后最容易翻车的问题。现象是训练集和验证集的mAP都很漂亮但换到另一条没见过的夜间道路上测试mAP直接腰斩。原因是数据集里几条主要道路的图片占了大部分模型学到的是这几条道路的固定背景特征——把路面纹理、路灯位置当成了行人的共现特征。解决路径是重新划分数据集。不要用纯随机划分按“场景分组划分”——同一个视频片段或同一条道路的截图分到同一个集合确保训练集和验证集没有场景重叠。5000张图如果来自10个场景可以按8个场景训练、1个场景微调、1个场景作为最终测试来分。这种做法会让验证集指标比随机划分略低一点但真实反映模型在陌生环境下的水平上线时心里有底。5.4 夜间数据标注边界模糊标签不一致导致的mAP虚高或偏低夜间行人标注的主观性很强——背光环境下行人轮廓和背景融在一起不同标注员对“行人边界从哪到哪”的判断可能相差好几个像素。现象是训练时用A标注版本训练、验证时用B标注版本评估mAP莫名其妙偏低而且偏低幅度不稳定。原因就是不同批次的标签box边界标准不统一模型学到的框中心分布方差大。解决路径是统一标注规范后全量回归一遍。如果数据集的XML或JSON标签来自多人协作标注先抽100张图检查框的一致度计算两个标注之间的IoU低于0.7的框数超过5%就得整体重标。夜间数据集标注时我用的标准是行人的框从头顶到脚底不包含影子被遮挡时框出可见部分的完整包围盒多人紧挨着时每个行人独立一个框不允许一个框圈两个人。5.5 训练中断恢复断点续跑的坑与后悔药训练到一半机器重启、显存溢出、或手动CtrlC中断训练是家常便饭。YOLO11训练时每轮会自动保存last.pt到runs/train/exp/weights/目录。恢复训练的命令很简单python train.py yolo11n.pt ./night_pedestrian_dataset/data.yaml --resume runs/train/exp/weights/last.pt但要注意——恢复训练的精妙之处在epoch计数和学习率调度器会从断点继续走而不是从头开始。如果中断时学习率已经衰减到很低恢复训练后会继续低学习率跑完剩余epoch效果是正常的。唯一值得注意的是如果中断发生在训练前几轮学习率还在高位恢复训练后模型可能会重新震荡几轮这不是bug是调度器在追进度。另外从last.pt恢复和自己手动加载权重继续训练是两回事——前者保留优化器状态和调度器状态后者只加载了权重参数。我一般先看last.pt是否保留优化器状态再决定要不要手动续训。6. 训练后的验证与进阶mAP之外还要看什么训练脚本跑完会在runs/train/exp/weights/下生成best.pt和last.pt两个权重文件。best.pt是验证集mAP最高的那一轮权重last.pt是最后一轮的权重。通用经验是用best.pt做推理测试用last.pt做继续训练。这时别急着部署先跑一套完整的验证流程。6.1 自定义置信度阈值与NMS调好再上测试视频模型默认输出置信度阈值是0.25但夜间场景的误检率高我一般把阈值调到0.35到0.4之间来压低误报。调阈值最好基于验证集统计——画出置信度与mAP的曲线找到精确率和召回率交叉点附近的值。python predict.py --weights runs/train/exp/weights/best.pt --source test_video.mp4 --conf 0.35 --iou 0.45预测脚本不带--conf参数时默认阈值直接复用训练时的设置。加上参数后可以实时调。NMS的IoU阈值0.45是常见默认值行人间距大时建议调低到0.4行人密集场景可以适度上调。夜间行人经常三五个并排走NMS阈值调高了会把相邻两个行人框合并成一个调太低又会导致同一个行人输出多个框。这个参数建议在实际视频上反复试几轮与置信度阈值组合调整。6.2 夜间专属评估分层看mAP对夜间模型只报一个mAP数字没意义我习惯把验证集按光照强度分成三档——明亮、昏暗、极暗分别评估指标。运行方式是在验证集目录里建三个子目录各放对应图片然后分别跑评估。from ultralytics import YOLO model YOLO(runs/train/exp/weights/best.pt) for split in [bright, dim, dark]: metrics model.val(datafnight_pedestrian_dataset/{split}/data.yaml) print(f{split}: mAP50{metrics.box.map50:.3f})如果分布显示“明亮档mAP50有0.8、极暗档只有0.3”说明模型对低光照的适应力还不够处理办法是对极暗图片做数据增强或者用Gamma校正把暗部提亮再做推理。这一步很关键——像夜间行人这种应用场景最需要关心的永远不是平均指标而是最差那档的上限。6.3 模型导出与部署转成TorchScript或ONNX保留三端兼容性训练完的PyTorch权重文件不能直接拿到生产环境用先要导出为通用格式。常见做法是转成ONNX或TorchScript两者都能保留模型结构和权重在无Python环境或C部署时使用。导出命令很简单model.export(formatonnx, imgsz640) model.export(formattorchscript, imgsz640)导出的ONNX文件在GPU(GPUs)服务器和Mac端都能跑推理CPU环境用OpenCV的DNN模块也能加载。这里有一个经验导出ONNX时imgsz要和训练时的输入尺寸一致如果训练时用的960导出时却是640输出精度会掉一截。数据格式本身对精度影响不明显但设备端使用ONNX Runtime时建议顺手开一下动态形状支持方便跑不同分辨率的输入。6.4 一套完整验证流程跑通才算真正结束最后再拉通一遍整个验证流程。把训练脚本跑出来的best.pt、导出的ONNX、以及原始PyTorch权重三份文件都在测试视频上跑同一段推理对比输出结果。重点关注两个指标帧率和检测稳定性。GPU(GPUs)上ONNX推理一般能跑到实时帧率Mac的MPS后端差一点但也可以接受CPU环境只能跑离线批量检测不能指望实时。我自己的习惯是全部验证通过后把data.yaml、best.pt、ONNX文件一起归档并在README里记录训练时的关键超参数和验证集指标——三个月后回头看这份记录比代码更有价值。夜间行人检测做到这个程度模型已经具备基本的落地能力了但远没到终点。后续如果想继续提升方向有三个一是扩充数据量尤其侧重极暗场景和小目标占比二是用训练好的权重做伪标签从无标注夜间视频里筛出高质量帧加入训练集形成迭代闭环三是考虑轻量化部署用TensorRT或CoreML做推理加速。整个过程里我最大的收获是学会了不要轻易相信一键脚本的默认输出——每一次训练后都要自己打开验证集图片、亲自看失败案例调参才有依据。希望这些拆解过程对你有帮助少走几趟我走过的弯路。本文还有配套的精品资源点击获取
返回列表