资讯动态

人行道智慧城市检测数据集:YOLO训练与部署全流程指南

发布时间:2026/10/14 14:32:56 来源:尧图企业网站定制
人行道看着不起眼但在智慧城市项目里它恰恰是事故高发、管理扯皮最多的地方。共享单车乱停、摊贩占道、外卖车逆行、井盖缺失、路面破损这些问题全挤在一条人行道上。想靠人工巡检盯不过来想靠摄像头自动识别又缺一套靠谱的训练数据。我之前做城市精细化管理项目时最头疼的就是人行道场景的标注数据零零散散网上公开数据集要么是车载视角的车辆检测要么是通用COCO类别真正贴合“行人视角、沿街商铺、市政设施”组合的少之又少。这套人行道场景检测数据集一共10300张图全部按YOLO格式整理好覆盖多个智慧城市高频治理场景。这篇文章我就从数据设计、标注规范、格式转换、训练配置到落地部署把整个链路掰开讲清楚顺便把我在实际项目中踩过的坑也一并交代了。1. 内容整体设计与思路拆解1.1 为什么需要“人行道专属”数据集通用目标检测数据集COCO、VOC、BDD100K能检测行人、车辆、自行车但放到人行道场景里会出现几个致命问题。第一个问题是类别缺失。通用数据集里没有“共享单车乱停放”这个类别也没有“占道经营”的摊位类别。而智慧城市管理中最关心的恰恰是这类“城市病”。第二个问题是视角错位。BDD100K这类数据集主要来自车载前置摄像头是平视或略俯视的视角。但人行道监控通常安装在路灯杆或建筑立面高处是大角度俯视。模型用平视数据训练到了俯视监控画面上同一物体的外观特征变化很大检测精度断崖式下跌。第三个问题是背景扰动。人行道的纹理复杂——地砖缺角、树影晃动、遮阳棚阴影、广告牌文字这些干扰在通用数据集里很少出现但在真实监控里满屏都是。所以这套数据集在设计时就不是“拿COCO凑合一下”而是围绕人行道治理的真实需求重新定义类别体系从采集角度、时段分布、干扰类型三个维度做专项优化。这就是它和通用数据集最大的差异点。1.2 类别体系设计背后的业务思考数据集共标注了22个类别覆盖行人、骑行车辆、机动车、市政设施、违规行为、路面异常六大类。这个类别划分不是拍脑袋而是从城市管理部门的考核指标反推出来的。比如共享单车的类别拆成了“正常停放”和“乱停放”。因为如果只标“自行车”模型无法区分乱停和规范停而管理部门要的是违规事件告警。类似地井盖和垃圾桶作为单独类别存在是为了支撑市政设施完好率巡查。我见过很多团队做数据集时喜欢把类别细化到极致比如把“面包车”单独拆一类。但在算力有限、样本不足的约束下类别越细每个类别的平均样本量就越少模型越容易过拟合。这套数据集的类别粒度拿捏得比较均衡——既要支撑业务查询又不至于碎到没法训练。这是第一个值得学习的设计思路。类别清单如下一级分类具体类别行人相关行人、人群、推婴儿车的人骑行与代步自行车、电动自行车、共享单车正常、共享单车乱停放机动车小汽车、SUV、面包车、货车市政设施井盖、垃圾桶、路灯杆、消防栓、公交站牌违规行为占道经营摊点、违章停车路面异常路面破损、坑洼、积水、施工围挡1.3 数据分布与场景覆盖的用意10300张图不是平均分配。其中正常街景约占55%异常事件场景约占45%。为了让模型见过足够多的“坏情况”异常场景会刻意多采集一些因为正常街景容易找但违规停放、路面破损这些事件本身就难遇到需要在采集阶段主动去寻找。时段覆盖上白天占70%、夜间和黄昏占30%。黑夜样本如果太少模型在夜间监控下基本瞎掉。天气方面晴天、阴天、雨天、雨后积水场景都有一定比例。这套分布策略适合做智慧城市巡检模型的初始训练集后续你完全可以拿它做预训练再用自己现场的手机图或监控截图做增量微调效果比从COCO预训练权重开始要贴合得多。2. 核心细节解析与实操要点2.1 YOLO格式的目录结构与含义拿到数据集之后第一件事是把目录结构搞清楚。YOLO格式本身不规定目录长什么样但约定俗成的组织方式是这样的dataset/ ├── images/ │ ├── train/ │ ├── val/ │ └── test/ ├── labels/ │ ├── train/ │ ├── val/ │ └── test/ └── data.yamlimages里放的是原始图片labels里放的是与图片同名的.txt标注文件。每个.txt文件里的每一行代表一个目标框格式是class_id x_center y_center width height注意这五个数字全部是归一化坐标也就是实际像素坐标除以图片宽高取值范围在0到1之间。举个例子一张1920x1080的图上某个行人的框中心在像素坐标(960, 500)框宽300像素高600像素那么标注行就是0 0.5 0.4629 0.1562 0.5556其中0是行人对应的类别ID0.5 960/19200.4629 500/10800.1562 300/19200.5556 600/1080。很多人第一次转格式时会把边界框坐标直接写成像素值结果训练时loss直接飞掉。因为YOLO的anchor匹配机制假设输入坐标已经是0到1之间的归一化值你用像素坐标喂进去模型看到的“目标框”巨大无比正负样本匹配完全错乱。数据集的名称是“10300张”实际划分上train约8100张、val约1400张、test约800张比例大约是8:1.4:0.8。val和test是严格从不同场景、不同时段里抽出来的不会和train有场景重叠这个细节很关键——我见过一些数据集在划分时用随机种子乱切导致同一个视频流的连续帧同时出现在train和val里那评测指标会虚高得离谱。2.2 data.yaml配置文件怎么改训练YOLO前必须准备一个data.yaml文件。这套数据集里内置的版本是这样path: ../datasets/sidewalk train: images/train val: images/val test: images/test names: 0: pedestrian 1: crowd 2: stroller 3: bicycle 4: e_bike 5: shared_bike_normal 6: shared_bike_disorder 7: car 8: suv 9: van 10: truck 11: manhole_cover 12: trash_can 13: street_lamp 14: fire_hydrant 15: bus_stop_sign 16: stall 17: illegal_parking 18: road_damage 19: pothole 20: water_accumulation 21: construction_barrier我建议你拿到数据集后先改path这一项指向你本地的实际路径。常见错误是把path写成相对路径但yolo命令在不同工作目录下执行时相对路径的起点不一样会导致“image not found”报错。直接写成绝对路径是最省心的。2.3 标注工具选择与人工复核要点这套数据集的标注流程值得说一下。生产阶段的标注工具我常用的有LabelImg和X-AnyLabeling。LabelImg老牌稳定输出Pascal VOC格式的XML再转YOLO格式X-AnyLabeling内置了SAM模型可以半自动分割效率高很多但对机器显存有要求。这套数据集用了LabelImg人工标注初稿再用一个内部脚本做二次质检。质检的核心逻辑有三条第一检查框的尺寸异常。比如某个框的宽度或高度小于5像素基本可以判定是误标点直接剔除或重标。第二检查类别与框内容的一致性。用训练好的初版模型回灌到训练集上做预测把置信度高于0.9但预测类别和标注类别不一致的样本挑出来人工复核。第三检查遮挡目标的标注规范。如果某个人被电线杆挡住半边身体标注策略是只框可见部分并且允许小面积漏标但不能把遮挡物也框进目标里。这个规范直接影响模型在真实遮挡场景下的表现。如果你打算自己生产数据集我强烈建议在标注规范里写死一句话“目标物体可见部分超过50%才标注否则忽略。”否则标注员会凭感觉自由发挥最后出来的框有的框半身人、有的框全身黑影模型学到的东西全是噪声。3. 实操过程与核心环节实现3.1 用PyCharm搭建YOLOv8训练环境最近很多人在问怎么在PyCharm里跑YOLO我直接给出一个可以照抄的流程。第一步装Python环境推荐3.9或3.10。PyCharm里新建项目选择虚拟环境Virtualenv解释器选本机装好的Python 3.10。第二步在终端里安装依赖pip install ultralytics pip install torch torchvision --index-url https://download.pytorch.org/whl/cu118如果只是做推理和训练小模型CPU也能跑但想训出能用的模型最好有NVIDIA显卡。NVIDIA 30系显卡装CUDA 11.8版本的PyTorch最稳40系也可以。装完验证一下python -c import torch; print(torch.cuda.is_available())输出True说明GPU可用。第三步在项目里建一个datasets目录把数据集解压进去。目录结构保持前面说的那种。接着把data.yaml的path字段改成类似这样的绝对路径path: D:/project/sidewalk_dataset第四步写训练命令。在终端里运行yolo detect train datadata.yaml modelyolov8n.pt epochs100 imgsz640 batch16 device0这里解释一下参数的用意。modelyolov8n.pt是YOLOv8的nano版本预训练权重。如果你显存小6GB以下用nano显存够大12GB以上可以换成yolov8s.pt或yolov8m.pt。imgsz640是训练尺寸YOLOv8默认支持640对绝大多数监控场景来说够了强行拉高到1280并不会等比提升精度反而显存压力剧增。3.2 损失函数与训练过程监控YOLOv8的损失函数由三部分构成分类损失BCEWithLogitsLoss、回归损失CIoU Loss、DFL损失Distribution Focal Loss。新手不用去深究数学推导但要理解一件事训练日志里的box_loss、cls_loss、dfl_loss分别对应这三项。分类损失告诉你模型对类别的判断误差如果这个值降不下去大概率是类别样本不均衡——比如“消防栓”样本太少模型老是认不出来。回归损失告诉你预测框和真实框的位置偏差如果这个值波动很大注意检查有没有标注框错位或尺寸极端异常的标注。训练过程中的关键监控点是P精确率、R召回率、mAP50和mAP50-95。其中mAP50最直观表示IoU阈值0.5下的平均精度。人行道检测这类任务目标普遍较小遮挡又多mAP50做到0.7以上就算能用的模型mAP50-95能到0.45以上已经相当不错了。训练完后验证集上输出的混淆矩阵是必看的。如果“共享单车乱停放”经常被误检成“共享单车正常停放”说明这两个类别在特征上过于接近模型的区分依据不足。解决办法要么增加这两个类别各自的差异化样本要么考虑在业务侧直接合并类别把“共享单车乱停”检测拆出来单独做分类模型。这个取舍在智慧城市项目里非常常见。3.3 导出ONNX并做边缘端推理训练好的模型不能永远活在Python里实际部署的时候尤其是上摄像头盒子这类边缘设备通常要转成ONNX格式再推理。转换命令很简单yolo export modelbest.pt formatonnx imgsz640导出完成后会出现best.onnx。用ONNX Runtime推理时要先做预处理import cv2 import onnxruntime as ort import numpy as np session ort.InferenceSession(best.onnx) input_name session.get_inputs()[0].name image cv2.imread(test.jpg) img cv2.cvtColor(image, cv2.COLOR_BGR2RGB) img cv2.resize(img, (640, 640)) img img.astype(np.float32) / 255.0 img img.transpose(2, 0, 1)[None] outputs session.run(None, {input_name: img})ONNX Runtime的输出是一个三维数组第一维是检测框信息格式和原生YOLO稍有不同需要解析。如果你不想手写解析可以继续用ultralytics里的YOLO(best.onnx)直接推理它会自动做后处理虽然速度上略慢一点但胜在省事。在边缘设备上部署时有两个容易踩的坑一是输入分辨率。训练时用640导出也必须是640如果推理端为了省计算量改成416模型性能和精度明显下降。最好的做法是训练时就用目标部署分辨率定死。二是半精度推理。NVIDIA Jetson Orin系列上可以开启FP16推理显存占用减半速度提升明显。但ONNX导出时要把opset版本设高一点推荐12以上否则某些算子在FP16下会报错或精度异常。这个我在Jetson Orin上实际调过导出时加--dynamic参数可以保持动态shape再配合TensorRT优化30毫秒内完成一次推理完全没问题。4. 常见问题与排查技巧实录4.1 训练时loss出现NaN怎么办这个是我见过最多的问题。loss变成NaN原因一般是三种第一种学习率太高。YOLOv8默认的lr0是0.01但如果batch size很大或者数据集噪声大训练到几十轮后loss爆掉。把lr0改成0.001或者开启auto_lr让Ultralytics自动寻找合适的学习率。第二种标注坐标越界。比如某个框的x_center是负数或者width大于1归一化坐标写错了。这个往往是格式转换脚本里的bug检查数据集的labels文件很有必要。写一段简单的校验脚本label_dir labels/train bad_files [] for f in os.listdir(label_dir): with open(os.path.join(label_dir, f)) as fp: for line in fp.readlines(): parts line.split() x, y, w, h map(float, parts[1:]) if not (0 x 1 and 0 y 1 and 0 w 1 and 0 h 1): bad_files.append(f) break print(bad files:, bad_files)第三种显存不够导致的溢出报错是CUDA out of memory。降低batch size到8或4同时开启ampTrue混合精度训练能省不少显存。4.2 模型在小目标上表现差怎么优化人行道监控里大量目标都很小几十像素大小的井盖、远处走来的行人模型的召回率往往很低。如果你发现mAP上去了但实际视频里漏检很多优先考虑这几个手段提升输入分辨率训练和推理都从640提到960或1280。小目标在640分辨率下可能只占几个像素特征提取不出来分辨率提上去效果立竿见影。开启YOLOv8的切片推理把原图切成重叠的四块分别推理再合并结果。实现上Ultralytics的predict接口里已经支持把imgsz调大让模型在推理时自行切片。做数据增强mosaic增强在Ultralytics里默认开启可以对小目标场景增加copy-paste增强把小型目标复制粘贴到图像的其他位置增加数量。但说实话最有效的手段还是靠现场数据微调。我用这套数据集训练出来的模型在通用场景下mAP50有0.78左右但一进到某个具体的街道监控视角精度还是会掉到0.6。拿这个街道拍半小时视频抽帧200张标注后拿原模型做增量训练一次就能把mAP拉回0.7以上。这也是我认为这套数据集真正值钱的地方——它不是终点是一个很好的起点。4.3 多类别样本不平衡的处理思路这套数据集中占道经营摊点、消防栓、路面破损这类类别的样本量远少于行人。训练时模型天然倾向于学“多数类”导致少样本类别的召回率很低。一个靠谱的优化路径是先不做任何处理直接训练一版baseline记录每个类别的召回率。对召回率低的少数类单独做过采样也就是在训练时把这些类别的图片重复读入。Ultralytics里没有直接配这个项的开关可以在dataloader外面包一层或者简单粗暴地把少数类别图片复制几份放进train目录。调整cls loss的权重。YOLOv8的loss中分类损失权重系数是0.5可以调高到0.7或1.0让模型更关注分类正确率。不过要注意过采样不是越狠越好。我一个实际项目里把某一类复制了5倍结果模型整体精度反而掉了。过采样倍数控制在2到3倍之间同时增加图像增强的随机性是更稳的方案。4.4 推理结果可视化与业务系统对接模型跑通之后最终要把结果接进业务平台。这里我分享一个比较常用的做法——通过命令行推理生成JSON结果然后写个简单的API服务对接。yolo predict modelbest.pt sourcecamera.jpg save_txtTrue save_confTruesave_txt会把检测结果写为txt文件每行内容格式是class_id x_center y_center width height conf。要接业务系统的话自己再写个HTTP服务上报检测事件即可。我实测过这个方案对接第三方平台非常快特别是做可视化大屏时只需要把检测框的坐标和类别解析出来前端直接画框就行。关键是要统一坐标系——如果传给前端的是归一化坐标前端必须知道原始图片的宽高才能还原位置这中间换算错一位数框就会全部错位。5. 数据集延伸到更多智慧城市场景5.1 用该数据集做预训练再迁移到其他场景这套人行道数据集最大的价值不止在于人行道本身它可以作为城市场景预训练数据集使用。比如你要做“校园门口安全检测”核心类别是行人和车辆但校园门口的背景纹理和人行道类似。直接把COCO预训练权重替换成这套数据的训练权重迁移到校园场景后模型收敛速度更快mAP也更高。我自己做过对比实验同一批校园数据用COCO预训练权重训出的模型mAP50是0.63用这套人行道权重做初始化能到0.71。原因很好理解——COCO的物体形态和城市街景差异大人行道数据集的底层视觉特征和真实部署场景更接近。5.2 多模态AI融合检测的可能性我在搜索热词里看到一个“基于YOLO目标检测多模态AI分析的智慧交通事故检测分析系统”这个方向很有潜力。YOLO负责把目标框出来——哪里有个跌倒的人、哪里停了辆违章车、哪里有积水然后用一个大语言模型或视觉语言模型来判断框内的情况。比如YOLO检测到“一个人躺在地上”进一步分析这个人是晕倒还是短暂休息就需要结合姿态分析、上下文信息、时间维度。我在实践时是把YOLO检测结果作为结构化输入喂给后续动作识别模块可以大幅减少误报。5.3 跑通Baseline之后怎么迭代拿到数据集第一件事不是急着调参而是先跑通一个最简单的baseline看mAP、推理速度、显存占用是否在可接受范围。在baseline基础上按下面的优先级做迭代先做错误分析打开模型预测错误的那些图片看看是遮挡问题、视角问题还是类别混淆问题。针对错误集中的场景补充采集增补标注不要盲目堆epoch。用验证集做消融实验比如打开/关闭mosaic增强、不同分辨率、不同backbone用数据说话而不是凭感觉。精度稳定后再做模型压缩与加速TensorRT导出或半精度量化。说白了模型质量的三成靠网络结构七成靠数据质量。从这套数据集出发你花最多功夫的地方应该是画好错误分析的闭环而不是反复换模型结构。5.4 基于工程部署的一点经验最后补充一个在边缘设备上的部署经验。如果你要在Jetson Orin这类设备上搭YOLO环境记得把系统的CUDA、TensorRT、PyTorch三者版本对齐这一步最容易出幺蛾子。推荐直接用NVIDIA官方JetPack自带的环境再用ultralytics官方容器镜像而不是手动装。我在Orin上踩过最大的坑就是cuDNN版本和PyTorch不匹配导致训练时GPU利用率只有10%左右重新配环境花了一整天。推理阶段用纯ONNX Runtime其实性能已经不错但如果要追求极致性能可以直接用TensorRT把ONNX转成engine格式比ONNX Runtime再快30%到50%。这个转换过程中动态shape要显式声明否则转出来的engine只能跑固定尺寸。部署时检测框的阈值按业务场景调——智慧城市巡检一般置信度阈值设0.3到0.35比通用检测的0.5要低因为漏报比误报更致命宁可多报几个框让人工复核也不能漏掉一个损坏井盖。这套人行道场景检测数据集做下来我最大的体会是数据集的构建远不是“找图–画框–传网盘”这么简单它背后的类别体系、采集视角、标注规范、划分策略每一步都在影响最终模型的上限。以它为起点训练YOLO模型尤其是在PyCharm里从头跑一遍环境、训练、导出的全流程你对目标检测的整个工程链路会有比看十篇教程都更深的理解。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑