首发于《有三AI》
【技术综述】万字长文详解Faster RCNN源代码mp.weixin.qq.comFaster R-CNN将分成四部分介绍。总共有Faster R-CNN概述,py-faster-rcnn框架解读,网络分析,和训练与测试四部分内容。第四篇将介绍网络分析,和训练与测试。
3. 网络分析
下面我们开始一个任务,就来个猫脸检测吧,使用VGG CNN 1024网络,看一下网络结构图,然后我们按模块解析一下。
3.1 input
layer {
name: 'input-data'
type: 'Python'
top: 'data'
top: 'im_info'
top: 'gt_boxes'
python_param {
module: 'roi_data_layer.layer'
layer: 'RoIDataLayer'
param_str: "'num_classes': 2"
}
}
这里要改的,就是num_classes,因为我们只有一个猫脸,前景类别数目等于1。
3.2 rpn
layer {
name: "rpn_conv/3x3"
type: "Convolution"
bottom: "conv5"
top: "rpn/output"
param { lr_mult: 1.0 }
param { lr_mult: 2.0 }
convolution_param {
num_output: 256
kernel_size: 3 pad: 1 stride: 1
weight_filler { type: "gaussian" std: 0.01 }
bias_filler { type: "constant" value: 0 }
}
}
layer {
name: "rpn_relu/3x3"
type: "ReLU"
bottom: "rpn/output"
top: "rpn/output"
}
layer {
name: "rpn_cls_score"
type: "Convolution"
bottom: "rpn/output"
top: "rpn_cls_score"
param { lr_mult: 1.0 }
param { lr_mult: 2.0 }
convolution_param {
num_output: 18 # 2(bg/fg) * 9(anchors)
kernel_size: 1 pad: 0 stride: 1
weight_filler { type: "gaussian" std: 0.01 }
bias_filler { type: "constant" value: 0 }
}
}
layer {
name: "rpn_bbox_pred"
type: "Convolution"
bottom: "rpn/output"
top: "rpn_bbox_pred"
param { lr_mult: 1.0 }
param { lr_mult: 2.0 }
convolution_param {
num_output: 36 # 4 * 9(anchors)
kernel_size: 1 pad: 0 stride: 1
weight_filler { type: "gaussian" std: 0.01 }
bias_filler { type: "constant" value: 0 }
}
}
具体的网络拓扑结构图如下:
从上图可以看出,rpn网络的输入来自于conv5卷积层的输出,后面接了rpn_conv/3x3层,输出通道数为256,stride=1。
rpn_conv/3x3层产生了两个分支,一个是rpn_cls_score,一个是rpn_bbox_pred,分别是分类和回归框的特征。
rpn_cls_score输出为18个通道,这是9个anchors的前背景概率,它一边和gt_boxes,im_info,data一起作为AnchorTargetLayer层的输入,产生分类的真值rpn_labels,回归的真值rpn_bbox_targets。另一边则经过rpn_cls_score_reshape进行reshape,然后与rpn_labels一起产生分类损失。
rpn_bbox_ppred输出为36个通道,就是9个anchors的回归预测结果,它与rpn_bbox_targets比较产生回归损失。rpn_cls_score_reshape重新reshape后得到rpn_cls_prob,rpn_cls_prob_shape,它与rpn_bbox_pred以及输入,共同得到了region prososal,就是候选的检测框。
在ProposalLayer层中配置了一个重要参数,就是feat_stride,这是前面的卷积层的feat_stride大小。ProposalLayer层完成的功能就是根据RPN的输出结果,提取出所需的目标框,而目标框是在原始的图像空间,所以这里需要预先计算出feat_stride的大小。ProposalLayer层的输出与data层一起获得最终的proposal roi,这将作为roi pooling层的输入。
3.3 roi pooing
前面得到了proposal roi之后,就可以进行roi pooling层,配置如下:
layer {
name: "roi_pool5"
type: "ROIPooling"
bottom: "conv5"
bottom: "rois"
top: "pool5"
roi_pooling_param {
pooled_w: 6
pooled_h: 6
spatial_scale: 0.0625 # 1/16
}
}
可以看到,它配置了几个参数,最终spatial_scale对应的就是前面的feat_stride,等于1/16,用于从图像空间的roi到特征空间roi的投影。
而pooled_w,pooled_h则是最终要pooling的特征图的大小,这里配置为6*6,从13*13的输入下采样而来。
4. 训练与测试
写到这里我们就简略一些。要做的就是三步,为了简单,保持使用pascal接口,步骤如下。
(1)准备voc格式的数据,可以找开源数据集或者使用labelme等工具集标注,然后配置好路径。替换掉pacvoc的ImageSets/Main目录下面的文件list,以及JPEGS和Annotations目录下的文件。
(2)然后到libdatasetspascal_voc.py中更改self._classes中的类别,由于我们这里是二分类的检测,所以将多余的类别删除,只保留背景,添加face类别。
(3)使用experements/tools下面的脚本训练吧。
遇到了坑,就直接跳和爬吧!
感受一下大小脸,大姿态,遮挡,误检,漏检。
路漫漫其修远兮.......
更多详细内容关注微信公众号:有三AI
龙鹏:【技术综述】万字长文详解Faster RCNN源代码(一)zhuanlan.zhihu.com