一、model配置文件->roi_head
目标检测的ROI head是指在区域提议网络(Region Proposal Network,RPN)生成的候选区域中,对候选区域进行分类和边界框回归的神经网络模块。它的作用是通过对提议的区域进行再次筛选,将候选区域中的目标物体进行准确地分类和位置定位,从而完成目标检测的整个流程。
model = dict(
roi_head=dict(
type='StandardRoIHead',
bbox_roi_extractor=dict(
type='SingleRoIExtractor', # RoIExtractor类型
roi_layer=dict(type='RoIAlign', output_size=7, sampling_ratio=0),
# ROI具体参数: RoI 层的类别为RoIAlign,特征图的输出大小为7, sampling_ratio提取 RoI 特征时的采样率。0 表示自适应比率
out_channels=256, # 输出通道数
featmap_strides=[4, 8, 16, 32]), # 特征图的步长
bbox_head=dict(
type='Shared2FCBBoxHead', #bbox head 的类别
in_channels=256, # bbox head 的输入通道。
fc_out_channels=1024, # FC 层的输出特征通道
roi_feat_size=7, # 候选区域(Region of Interest)特征的大小
num_classes=80, # 分类的类别数量
bbox_coder=dict( # 第二阶段使用的框编码器
type='DeltaXYWHBBoxCoder',
target_means=[0., 0., 0., 0.], # 用于编码和解码框的均值
target_stds=[0.1, 0.1, 0.2, 0.2]), # 编码和解码的标准差。因为框更准确,所以值更小,常规设置时 [0.1, 0.1, 0.2, 0.2]。
reg_class_agnostic=False, #回归是否与类别无关
loss_cls=dict( # 分类分支的损失函数配置
type='CrossEntropyLoss', # 分类分支的损失类型,我们也支持 FocalLoss 等
use_sigmoid=False, # 是否使用 sigmoid
loss_weight=1.0), # 分类分支的损失权重
loss_bbox=dict( # 回归分支的损失函数配置
type='L1Loss', # 损失类型,我们还支持许多 IoU Losses 和 Smooth L1-loss 等
loss_weight=1.0)), # 回归分支的损失权重
二、roi_head详解
ROI head通常由两个子网络组成:分类子网络和回归子网络。分类子网络用于对候选区域中的物体进行分类,回归子网络则用于对物体位置进行精细调整。
目标检测的ROI head的原理是通过对每个候选区域进行卷积神经网络(CNN)特征提取,并输入到分类子网络和回归子网络中进行分类和边界框回归的操作。一般情况下,候选区域的大小是不同的,因此需要使用ROI Pooling或ROI Align等技术将候选区域缩放到特定大小,以便输入到CNN中进行特征提取。
Pooling:RoI Pooling 直接从feature map 里截取各个兴趣区域(Region of Interest, RoI)的feature, 并换为为相同大小的feature输出。RoI Pooling的作用本质上是为了将不同尺寸的RoI特征转换为相同的特征图输出,保证特征图展开后具有相同的大小尺寸,能够与下层的全连接层连接,分别执行线性分类(linear classifier)和边框回归(bounding box regressor)。
RoI Pooling = crop feature + resize feature
ROI Align:在候选区域边界的像素上采取了更加精细的划分和插值操作,以充分利用和保留边界上的信息。
RPN 层输出每张图片最多 nms_post 个候选框,故 R-CNN 输入 shape 为 (batch, nms_post, 4),4 表示 RoI 坐标。
利用 RoI 重映射规则,将 nms_post 个候选框映射到 FPN 输出的不同特征图上,提取对应的特征图,然后利用插值思想将其变成指定的固定大小输出,输出 shape 为 (batch, nms_post, 256, roi_feat_size, roi_feat_size),其中 256 是 FPN 层输出特征图通道大小,roi_feat_size 一般取 7。上述步骤即为 RoIAlign 或者 RoIPool 计算过程。
将 (batch, nms_post, 256, roi_feat_size, roi_feat_size) 数据拉伸为 (batchnms_post, 256roi_feat_sizeroi_feat_size),转化为 FC 可以支持的格式, 然后应用两次共享卷积,输出 shape 为 (batchnms_post, 1024)。
将 (batchnms_post, 1024) 分成分类和回归分支,分类分支输出 (batchnms_post, num_class+1), 回归分支输出 (batchnms_post, 4num_class)。
下面是我自己的理解:正确性有待评估
(7, 7, 256)->(2, 2, 256)->(1024,1)->(num_class+1)
->num_class*4