天天看点

Faster Rcnn源码阅读之Roi_pooling 层

首先 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。

继续阅读