在看fasterrcnn以及和maskrcnn的时候,发现自己对fasterrcnn的roi_pooling层的原理还是不是很明白,之前只是知道roi_pooling是将rpn输出的一个roi的区域映射成一个固定大小的map,再送入后面的分类层进行分类。最近看了下roi_pooling层的源码,顿悟了。
1、roi_pooling在proto中的定义
根据看caffe源码的原则,先看该成在caffe.proto文件中的定义:
// Message that stores parameters used by ROIPoolingLayer
message ROIPoolingParameter {
// Pad, kernel size, and stride are all given as a single value for equal
// dimensions in height and width or as Y, X pairs.
// 设置pool后的map的高度和宽度
optional uint32 pooled_h = 1 [default = 0]; // The pooled output height
optional uint32 pooled_w = 2 [default = 0]; // The pooled output width
// Multiplicative spatial scale factor to translate ROI coords from their
// input scale to the scale used when pooling
# 设置从原图到pool前的feature map的比例的大小
optional float spatial_scale = 3 [default = 1];
}
从这里可以看出,在网络定义文件中定义roi_pooling层需要设置3个参数,分别是pooled_h 、pooled_w 以及spatial_scale 的值。前2个值分别为pool后的map的宽度和高度,比如在fasterrcnn中即为6*6,后面这个值
spatial_scale 为从原图到pool前的feature map的比例的大小,因为rpn输出的roi的坐标是基于原图的,转换到feature map,是有一个比例的。
再来看看在fasterrcnn中,roi_pooling层的定义:
#========= RCNN ============
layer {
name: "roi_pool_conv5"
type: "ROIPooling"
bottom: "conv5"
bottom: "rois"
top: "roi_pool_conv5"
roi_pooling_param {
pooled_w: 6
pooled_h: 6
spatial_scale: 0.0625 # 1/16
}
}
相关的参数设置和caffe.proto中定义的一致。
2、roi_pooling源码
在这里,主要是关注其前向传播的函数。
namespace caffe {
// 从net定义文件中获取roi_pooling层的相关参数
template <typename Dtype>
void ROIPooli