ARTICLE DETAIL

资讯详情

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

Faster-RCNN交通目标检测实战:从训练到推理的完整工程指南

Faster-RCNN交通目标检测实战:从训练到推理的完整工程指南 简介本资源面向计算机视觉入门与进阶学习者提供一套基于Faster-RCNN的车辆、行人及交通信号目标检测完整项目适合课程设计、毕业设计或算法练手场景。压缩包共89个文件约3.61MB以30个Python源码文件与36个pyc编译文件为主另含12张jpg测试图片、项目报告pdf、说明文档md及类别配置json等覆盖从数据读取到模型推理的全流程。项目按backbone、network_files、train_utils等模块组织包含ResNet50FPN、MobileNetV2、VGG等特征提取网络以及RPN、ROI Head、混合精度训练、多GPU训练、mAP评估与预测脚本并配有详细注释。已有226人学习读者可据此掌握Faster-RCNN网络结构、自定义数据集读取、训练验证流程与结果可视化快速复现车辆行人及交通信号检测实验。1. 从一份能跑通的 Faster-RCNN 交通目标检测包说起红绿灯、行人和车辆这三类目标是自动驾驶感知和智慧交通项目里绕不开的基本盘。但真正动手时多数人卡住的地方不是网络结构本身而是数据标注格式对不上、预训练权重加载报错、训练到一半 loss 变 NaN、推理画框坐标偏移这些琐碎问题。这份基于 Faster-RCNN 的车辆行人及交通信号目标检测资源包把 Python 源码、Pascal VOC 格式数据集、训练好的权重、项目报告和逐行注释一起打包省掉了从零搭工程的时间。它适合两类人一是刚接触目标检测、想找一个结构完整、能直接跑通的工程练手二是已经用过 YOLO 系列、想对比两阶段检测器在交通场景下精度与速度差异的从业者。整个工程基于 PyTorch 1.6 以上版本用 ResNet50FPN 做骨干网络训练脚本、验证脚本、预测脚本、mAP 曲线绘制一应俱全拿到手就能复现完整流程。2. 工程结构与核心模块拆解backbone、RPN 和 ROI Head 怎么配合2.1 目录布局与各模块职责拿到压缩包解压后根目录下大致是这么几块backbone放特征提取网络network_files放 Faster-RCNN 主体结构train_utils放训练验证工具根目录下散落着my_dataset.py、transforms.py、split_data.py、train_res50_fpn.py、predict.py、validation.py、plot_curve.py等脚本。这个划分方式很清晰改网络去network_files换骨干去backbone调数据增强去transforms.py各管各的。network_files里几个文件值得单独说。rpn_function.py是区域建议网络负责在特征图上生成候选框roi_head.py是 ROI Head把候选框映射回特征图并做分类和回归faster_rcnn_framework.py把 backbone、RPN、ROI Head 串成完整模型transform.py处理图像和标注的同步变换det_utils.py放的是框编码解码、NMS 这些底层工具函数。boxes.py里实现了BoxCoder和Matcher前者负责锚框与真实框之间的偏移量编解码后者负责把候选框和真实标注做匹配是训练能否收敛的关键。backbone目录下提供了三种选择resnet50_fpn_model.py、mobilenetv2_model.py、vgg_model.py。默认训练脚本用的是 ResNet50FPN精度最高但显存占用也最大MobileNetV2 适合显存紧张或者想部署到边缘设备的场景VGG 是 Faster-RCNN 原论文用的骨干现在用得少了但作为对比基线仍有参考价值。feature_pyramid_network.py是 FPN 的实现把不同尺度的特征图融合后输出给 RPN 和 ROI Head对小目标检测提升明显——交通场景里的远处行人和小信号灯就吃这个红利。2.2 数据读取与增强链路my_dataset.py里定义了一个继承自torch.utils.data.Dataset的类核心逻辑是读 Pascal VOC 格式的 XML 标注解析出每个目标的类别和边界框坐标再配合transforms.py做同步增强。这里有个容易忽略的点图像增强必须对图像和标注框做同样的几何变换否则框就飘了。工程里用的是一个组合变换类把随机翻转、随机裁剪等操作封装在一起保证图像和框同步。# my_dataset.py 核心逻辑示意 class VOCDataSet(Dataset): def __init__(self, voc_root, transforms, train_setTrue): # 读取 ImageSets/Main/train.txt 或 val.txt # 解析 Annotations 下的 XML 文件 ... def __getitem__(self, idx): # 读图像 - 读标注 - 同步增强 - 转 tensor image Image.open(img_path).convert(RGB) boxes, labels self.parse_xml(xml_path) image, boxes, labels self.transforms(image, boxes, labels) return image, boxes, labelstransforms.py里实现了RandomHorizontalFlip、RandomResize等每个变换都同时接收 image、boxes、labels 三个参数返回变换后的三者。参数方面RandomResize里有个max_size控制短边缩放后的长边上限默认 1333显存不够就往下调但别低于 600否则小目标特征全丢了。2.3 训练脚本与多 GPU 支持train_res50_fpn.py是主训练脚本里面几个参数需要根据自己机器调整。--data-path指向数据集根目录--epochs默认 10 轮左右--batch-size在单卡 8G 显存下建议设 2 到 4--lr初始学习率 0.005 配合余弦退火。脚本里用了 PyTorch 1.6 之后才支持的混合精度训练torch.cuda.amp那套能省显存提速但前提是 PyTorch 版本必须 1.6.0 以上低于这个版本会直接报AttributeError。train_multi_GPU.py是多卡版本用DistributedDataParallel做数据并行。启动方式和单卡不同得用torch.distributed.launch或者torchrun# 单机 4 卡训练示例 python -m torch.distributed.launch --nproc_per_node4 --use_env train_multi_GPU.py \ --data-path ./data \ --epochs 20 \ --batch-size 4 \ --lr 0.01 \ --output-dir ./save_weights--nproc_per_node是每台机器的进程数一般等于 GPU 数量。--use_env让脚本从环境变量读 rank 信息不加这个参数在某些 PyTorch 版本下会报找不到LOCAL_RANK。多卡训练时batch-size指的是单卡 batch总 batch 是它乘以卡数学习率也要相应放大。3. 从零跑通训练与推理环境、数据、权重加载的完整操作链3.1 环境配置与依赖安装环境这块官方推荐 Python 3.6 到 3.8PyTorch 1.6.0 以上Ubuntu 或 CentOS不建议 Windows。Windows 下pycocotools装起来麻烦得用pycocotools-windows替代而且多卡训练支持也差。如果手头只有 Windows 机器建议用 WSL2 或者直接上云服务器。# 创建虚拟环境 conda create -n faster_rcnn python3.8 -y conda activate faster_rcnn # 安装 PyTorch 1.6根据 CUDA 版本选对应命令 pip install torch1.8.0 torchvision0.9.0 # 安装其他依赖 pip install -r requirements.txt # pycocotools 按平台选 # Linux: pip install pycocotools # Windows: pip install pycocotools-windowsrequirements.txt里除了 PyTorch 和 torchvision还有 numpy、pillow、matplotlib、tqdm 这些常规库。装完后建议跑一句python -c import torch; print(torch.cuda.is_available())确认 GPU 可用返回 False 的话后面训练会慢到怀疑人生。3.2 数据集准备与格式校验工程用的是 Pascal VOC 格式目录结构应该是data/ ├── VOC2012/ │ ├── JPEGImages/ # 所有 jpg 图片 │ ├── Annotations/ # 对应的 xml 标注 │ └── ImageSets/ │ └── Main/ │ ├── train.txt │ └── val.txtsplit_data.py用来划分训练集和验证集按比例把图片名写进 train.txt 和 val.txt。如果自己换数据集XML 里的类别名要和pascal_voc_classes.json里的对上这个 json 文件定义了类别名到数字标签的映射。交通场景下一般就是vehicle、person、traffic_light这几类改 json 的时候注意索引从 1 开始0 留给背景。注意XML 里如果有类别名拼写不一致比如traffic light和traffic_light混用训练时会被当成两个类mAP 直接腰斩。跑之前用脚本扫一遍所有 XML 的类别名统一成 json 里的写法。3.3 训练启动与权重加载训练命令不复杂关键是参数要对python train_res50_fpn.py \ --data-path ./data/VOC2012 \ --epochs 15 \ --batch-size 4 \ --lr 0.005 \ --output-dir ./save_weights \ --weights ./save_weights/resNetFpn-model-10.pth # 断点续训或加载预训练--weights参数可以加载之前保存的权重继续训练也可以加载在 COCO 上预训练的骨干权重做迁移学习。如果从零开始训练不传这个参数就行。训练过程中每轮结束会在output目录下写result_faster.txt记录 loss 和 mAPplot_curve.py读这个文件画曲线。record_mAP.txt是工程自带的训练记录里面能看到作者跑出来的 mAP 大概在什么水平。交通场景三类目标ResNet50FPN 在 VOC 格式数据上 mAP 通常能到 0.75 以上具体看数据质量和标注精度。3.4 推理与结果可视化predict.py是单张图片推理脚本加载权重后对testdata里的图片做检测并画框保存。核心流程是读图 → 预处理 → 模型前向 → 后处理NMS、置信度过滤→ 画框。# predict.py 核心推理逻辑 model.eval() with torch.no_grad(): images, _ model.transform(images, None) # 预处理 predictions model(images) # 前向 results model.postprocess(predictions, images.image_sizes) # 后处理 # 过滤低置信度画框 for box, label, score in zip(results[0][boxes], results[0][labels], results[0][scores]): if score 0.5: draw_box_utils.draw_box(img, box, label, score)draw_box_utils.py负责画框和类别标签支持中文标签需要额外配置字体。testdata目录下有 test1 到 test6 六张测试图以及对应的_result.jpg结果图可以直接对比推理效果。置信度阈值默认 0.5交通信号灯这种小目标可以降到 0.3 试试但误检会变多。4. 避坑与排查训练不收敛、显存爆炸、mAP 异常的常见原因4.1 loss 出现 NaN 或一直不下降现象训练几个 batch 后 loss 变成 NaN或者 loss 在 2.0 附近震荡不降。原因学习率设太大是最常见的Faster-RCNN 对学习率比 YOLO 敏感初始 lr 超过 0.01 很容易炸。另一个原因是数据标注里有宽高为 0 的框计算回归 loss 时除零。解决把初始学习率降到 0.005 甚至 0.001配合 warmup 策略。检查 XML 标注过滤掉宽高小于 2 像素的框。如果用了混合精度训练偶尔也会因为梯度下溢出 NaN把amp关掉试试。4.2 显存不足报 CUDA out of memory现象训练启动后报RuntimeError: CUDA out of memory或者跑几个 batch 后爆显存。原因batch-size太大、图像分辨率太高、ResNet50FPN 本身显存占用就不小。默认max_size1333在 8G 显存上单卡 batch 超过 4 基本会炸。解决先把batch-size降到 2再把transforms.py里的max_size从 1333 降到 800min_size从 800 降到 600。还不行就换 MobileNetV2 骨干显存占用能降一半左右精度损失大概 3 到 5 个点。4.3 mAP 异常低或某类目标检测不到现象训练完 mAP 只有 0.2 到 0.3或者某一类目标完全检测不出来。原因类别名和 json 映射对不上、验证集和训练集图片重叠、标注框坐标越界。还有一种情况是pascal_voc_classes.json里类别顺序和 XML 里不一致导致标签错位。解决用validation.py单独跑验证集看混淆矩阵哪类错得最多。检查split_data.py划分时有没有把同一张图同时分到训练和验证。标注框坐标不能超出图像宽高越界的框在增强时会出问题。4.4 多卡训练速度反而变慢现象用了train_multi_GPU.py四卡训练速度比单卡还慢。原因数据加载成了瓶颈num_workers设太小或者磁盘 IO 跟不上。另外DistributedDataParallel的find_unused_parameters如果设成 True 会拖慢速度。解决把num_workers从默认的 4 调到 8 或 16数据放在 SSD 上。检查模型里有没有定义但没参与前向的参数没有的话把find_unused_parameters设成 False。多卡训练时batch-size是单卡值总 batch 等于它乘以卡数学习率要按线性缩放规则相应调大。4.5 推理结果框偏移或重复框现象预测出来的框位置明显偏了或者同一个目标画了好几个重叠框。原因框偏移通常是预处理和后处理没对齐比如推理时用了 resize 但没记录缩放比例后处理时没把框映射回原图尺寸。重复框是 NMS 阈值设太高。解决检查predict.py里postprocess是否用了image_sizes做坐标还原。NMS 阈值默认 0.5重复框多就降到 0.3 到 0.4。另外注意transform.py里的标准化参数要和训练时一致均值方差对不上也会导致框偏移。5. 进阶技巧换骨干、调锚框、导出推理结果5.1 替换骨干网络做精度与速度权衡工程默认用 ResNet50FPN想换 MobileNetV2 的话改train_res50_fpn.py里的模型构建部分把 backbone 换成mobilenetv2_model.py里定义的网络。MobileNetV2 参数量只有 ResNet50 的三分之一左右推理速度快一倍以上适合部署到 Jetson 这类边缘设备。代价是 mAP 会降几个点尤其是小目标。# 换 MobileNetV2 骨干示意 from backbone.mobilenetv2_model import MobileNetV2 from network_files import FasterRCNN backbone MobileNetV2(weights_path./mobilenet_v2.pth).features backbone.out_channels 1280 # MobileNetV2 输出通道数 model FasterRCNN(backbone, num_classes4) # 3 类 背景out_channels必须和骨干输出通道对齐ResNet50 是 2048MobileNetV2 是 1280设错了会在 RPN 那层报维度不匹配。换完骨干后学习率可以适当调小因为预训练权重的特征分布不同。5.2 锚框尺寸调整适配交通场景Faster-RCNN 默认锚框尺寸是[32, 64, 128, 256, 512]长宽比[0.5, 1.0, 2.0]。交通场景里行人偏瘦高信号灯很小默认锚框不一定最优。如果数据里目标普遍偏小把最小锚框从 32 降到 16增加一档小尺度。如果行人检测效果差把长宽比加上 0.3 和 3.0 两档。# 在 faster_rcnn_framework.py 里调整锚框参数 anchor_sizes ((16,), (32,), (64,), (128,), (256,)) # 增加小尺度 aspect_ratios ((0.3, 0.5, 1.0, 2.0, 3.0),) * len(anchor_sizes) # 增加极端比例改完锚框后RPN 的回归目标分布会变建议重新从头训练而不是加载旧权重微调。锚框数量增加会拖慢 RPN 速度但召回率会提升具体加多少看验证集上的 mAP 变化。5.3 导出推理结果与 mAP 曲线分析训练完想分析模型在各类目标上的表现validation.py跑完会输出每类的 AP 和总 mAP。plot_curve.py读result_faster.txt画 loss 和 mAP 曲线能直观看到有没有过拟合。如果训练 loss 还在降但验证 mAP 已经平了说明该早停了。# 跑验证集看每类 AP python validation.py \ --data-path ./data/VOC2012 \ --weights ./save_weights/resNetFpn-model-15.pth # 画训练曲线 python plot_curve.py --txt-path ./output/result_faster.txt导出的检测结果可以存成 json 或 csv方便后续做误检分析。我一般会把置信度 0.3 到 0.5 之间的框单独拎出来看这批框往往是模型最纠结的调锚框或者加数据对它们影响最大。从那以后我每次训完模型都强制把验证集里漏检和误检的图各抽 20 张过一遍比只看 mAP 数字有用得多。希望帮到你。本文还有配套的精品资源点击获取
返回列表