首先 RoI pooling 层的代码位于model/roi_pooling 下
主要文件为: functions/roi_pool.py
roi_pools 的初始化:
1,pooled_height pool之后feature map的高
2,pooled_width pool之后feature map的宽
3,spatial_scale feature map 原图的大小比例
过程:
具体算法过程是在functions/roi_pooling.c(cup)/roi_pooling_cuda.c(gpn)中实现的
以下是前向传播的代码
将rois /spatial_scale,将rois的映射到feature map上,得到feature map上的bbox的坐标
//找到roi对应的图片在batch中的索引
int roi_batch_ind = rois_flat[index_roi + 0];
//得到roi在特征图上的位置
int roi_start_w = round(rois_flat[index_roi + 1] * spatial_scale);
int roi_start_h = round(rois_flat[index_roi + 2] * spatial_scale);
int roi_end_w = round(rois_flat[index_roi + 3] * spatial_scale);
int roi_end_h = round(rois_flat[index_roi + 4] * spatial_scale);
// CHECK_GE(roi_batch_ind, 0);
// CHECK_LT(roi_batch_ind, batch_size);
//得到roi在共享卷积层的高,宽
int roi_height = fmaxf(roi_end_h - roi_start_h + 1, 1);
int roi_width = fmaxf(roi_end_w - roi_start_w + 1, 1);
//这个roi在pooling的时候会被分成多少段
float bin_size_h = (float)(roi_height) / (float)(pooled_height);
float bin_size_w = (float)(roi_width) / (float)(pooled_width);
2 //找max,在该区域中循环每一个点的值,找到最大的点,作为该区域pooling后对应点的值。
if (data_flat[index_data + index] > output_flat[pool_index + c * output_area])
{
output_flat[pool_index + c * output_area] = data_flat[index_data + index];
}
看一下forward的输入
1,feature maps:共享卷积层穿过来的特征
2,rois: rpn层选出来的框
输出:固定大小 w*h的矩形框
前传的代码三个文件都差不多的。
下面看下反向传播
roi_pool.py 的反向传播,主要调用了roi_pooling_cuda中的反向传播
代码。
//遍历该点对于特征图上高的区域
for (int ph = phstart; ph < phend; ++ph) {
//遍历该点对于特征图上宽的区域
for (int pw = pwstart; pw < pwend; ++pw) {
if (offset_argmax_data[(c * pooled_height + ph) * pooled_width + pw] == index)
{
//找到点,累计剃度
gradient += offset_top_diff[(c * pooled_height + ph) * pooled_width + pw];
}
}
}
反向传播中
输入:grad_output剃度,在roi_pooling_cuda计算累加剃度用的。但是具体怎么传进来的,代表什么意思。需要看上一层的代码。
输出:累加剃度
ok,roi 层就完成了。将rois映射到feature map上,然后划分成固定大小
m * n的区域,每一个区域输出最大值,输出最后pool成固定的m*n的map。