文章目录
手把手教你完成Faster-RCNN训练
该项目是fork了B站大佬bubbliiiing的,为了学习双阶段目标检测,有一部分注释也是自己重写了。但尊重原著,有需要的可以看原代码链接。
该帖子github链接: https://github.com/luohaohaoluo/zeroDL/tree/main/demo/faster-rcnn,感兴趣的朋友可以自行下载训练。
1. 文件目录介绍
-- \faset-rcnn
-- \networks
-- \model_data
-- resnet50.py
-- rpn.py
-- frcnn.py
-- frcnn_training.py
-- classifier.py
-- \utils
-- anchors.py
-- utils_bbox.py
-- dataloader.py
-- utills.py
-- utils_map.py
-- utils_fit.py
-- callbacks.py
-- \dataset
-- VOC2007
-- Annotations
-- lmageSets
-- JPEGlmages
-- SegmentationClass
-- SegmentationObject
-- train.py
-- voc_annotation.py
-- get_map.py
-- predicet.py
-- summary.py
-- frcnn.py
- networks: 关于faster-rcnn网络的代码
- model_data: 存放模型权重,例如预训练模型、训练的faster-rcnn。
- resnet50.py: 作为faster-rcnn的backbone,用于特征提取
- rpn.py: RPN网络构建的代码
- classifier.py: 检测头的代码
- frcnn.py: faster-rcnn的整体框架代码
- frcnn_training.py: faster-rcnn训练需要的配置,例如优化器,学习率等
- utils:
- anchors: 基础先验框和每个网络拓展先验框的代码
- utils_bbox: 预测框与先验框融合以及解析的代码
- dataloader.py: 生成一个关于VOC2007的dataloader类,用于训练或验证。
- utilss: 存放一些常用的函数,如随机数种子设置,图像归一化等
- utils_map.py: 计算map的库
- utils_fit.py: 训练时,单个epoch的过程
- callbacks.py: 训练过程,记录数据
- dataset:存放了VOC2007数据集,其中:
- Annotations: ".xml"格式的文件,记录每张图片的大小、物体类别、边界框位置信息等
- lmageSets: 关于数据集划分成train、val、test的".txt"文件
- JPEGlmages: JPEG格式的图片
- SegmentationClass: 以类别为基准的分割图片,可做语义分割
- SegmentationObject: 以物体为基准的分割图片,可做实例分割
- train.py: 利用VOC2007训练faster-rcnn的训练框架
- voc_annotation.py: 将VOC数据集做注释处理,生成的".txt"文件,将带有图像路径,以及真实框和标签信息。
- get_map.py: 计算map
- predicet.py: 模型预测文件
- summary.py: 计算模型的网络结构,包括参数量,以及FLOPS等
- frcnn.py: 模型预测调用的库,主要是方面实现预测的4个功能
2. faster-rcnn网络框架整体介绍
- 步骤:
- 第一步:将整个图片输入到一个基础卷积网络,得到整张图的feature map;
- 第二步:将region proposal(ROI)映射到feature map当中;
- 第三步:ROI提取一个固定长度的特征向量,每个特征会输入到一系列全连接层,得到一个ROI特征向量(该步骤对每一个候选区域都会进行同样的操作);
- 其中一个是传统softmax层进行分类,输出类别有K个类别+“背景”类;
- 另一个是bounding box regressor。
2.1. backbone构建
这里选用的是resnet50的结构, 为了能够顺利加载resnet50网络权重,因此,严格按照pytorch官方给的命名结构来写。
其中注意的是残差块的大小,左图是resnet18/34的残差块,右图是resnet50/101/152的残差块,这里如果当模型需要进行高和宽的压缩的时候,一般右图会有downsample操作。
2.2. RPN构建
这里的RPN其实是建立在原图的基础上,在最后分割头的时候,会根据比例缩放到feature map上,所以为什么就有了大约在600*600的网格点出来。 每个网格点,都会得到9个先验框,组成一共12996个先验框,根据NMS在训练过程中,筛选出600个先验框出来。
这里讲解的文件是rpn.py:
- 1.先在实例化的时候,就初始化9个基础先验框。
- 2.从forwad()开始看,首先是根据backbone的feature map,经过简单的卷积操作,得到两条分支,分别是rpn_locs和rpn_scores,用于记录预测框的位置和对应的得分。与此同时,根据得分,筛选出有物体的预测框出来做准备。值得提及的是根据后来的代码查阅,发现,其实rpn_locs的最后一维4个参数分别代表目标偏移框的( Δ x