RoIAlign源码及示意图

/*
* 参数解释
* bottom_data 需要做RoIAlign的feature map
* spatial_scale feature map放缩的尺寸 vgg是1/16
* channels height width feature map的通道高和宽不用多说
* pooled_height pooled_width RoIAlign后的feature大小
* sampling_ratio RoIAlign时,每个bin内高和宽方向的采样率,论文中默认是2,即每个bin采样2*2=4个点
* bottom_rois rpn生成的物体坐标,以原图为参照的,所以用在feature上时需要spatial_scale这个参数
*/
template <typename T>
__global__ void RoIAlignForward(const int nthreads,const T* bottom_data,const T spatial_scale,const int channels,const int height,const int width,const int pooled_height,const int pooled_width,const int sampling_ratio,const T* bottom_rois,T* top_data) {CUDA_1D_KERNEL_LOOP(index, nthreads) {// (n, c, ph, pw) is an element in the pooled outputint pw = index % pooled_width;int ph = (index / pooled_width) % pooled_height;int c = (index / pooled_width / pooled_height) % channels;int n = index / pooled_width / pooled_height / channels;const T* offset_bottom_rois = bottom_rois + n * 5;int roi_batch_ind = offset_bottom_rois[0];// Do not using rounding; this implementation detail is criticalT roi_start_w = offset_bottom_rois[1] * spatial_scale;T roi_start_h = offset_bottom_rois[2] * spatial_scale;T roi_end_w = offset_bottom_rois[3] * spatial_scale;T roi_end_h = offset_bottom_rois[4] * spatial_scale;// T roi_start_w = round(offset_bottom_rois[1] * spatial_scale);// T roi_start_h = round(offset_bottom_rois[2] * spatial_scale);// T roi_end_w = round(offset_bottom_rois[3] * spatial_scale);// T roi_end_h = round(offset_bottom_rois[4] * spatial_scale);// Force malformed ROIs to be 1x1T roi_width = max(roi_end_w - roi_start_w, (T)1.);T roi_height = max(roi_end_h - roi_start_h, (T)1.);T bin_size_h = static_cast<T>(roi_height) / static_cast<T>(pooled_height);T bin_size_w = static_cast<T>(roi_width) / static_cast<T>(pooled_width);const T* offset_bottom_data =bottom_data + (roi_batch_ind * channels + c) * height * width;// We use roi_bin_grid to sample the grid and mimic integral// 采样率,论文中默认是2,如果没有设置则等于ceil(roi_height / pooled_height),大概约等于每个bin里有几个格子就采样几个点int roi_bin_grid_h = (sampling_ratio > 0)? sampling_ratio: ceil(roi_height / pooled_height); // e.g., = 2int roi_bin_grid_w =(sampling_ratio > 0) ? sampling_ratio : ceil(roi_width / pooled_width);// We do average (integral) pooling inside a binconst T count = roi_bin_grid_h * roi_bin_grid_w; // e.g. = 4T output_val = 0.;for (int iy = 0; iy < roi_bin_grid_h; iy++) // e.g., iy = 0, 1{// 在height方向采样const T y = roi_start_h + ph * bin_size_h +static_cast<T>(iy + .5f) * bin_size_h /static_cast<T>(roi_bin_grid_h); // e.g., 0.5, 1.5// 在width方向采样for (int ix = 0; ix < roi_bin_grid_w; ix++) {const T x = roi_start_w + pw * bin_size_w +static_cast<T>(ix + .5f) * bin_size_w /static_cast<T>(roi_bin_grid_w);// 被采样到的点由于坐标是浮点数,其对应位置的值需要双线性插值获取(最近的4个点得到)T val = bilinear_interpolate(offset_bottom_data, height, width, y, x, index);output_val += val;}}output_val /= count;top_data[index] = output_val;}
}} // namespace

双线性插值代码及示意图、公式

template <typename T>
__device__ T bilinear_interpolate(const T* bottom_data,const int height,const int width,T y,T x,const int index /* index for debug only*/) {// deal with cases that inverse elements are out of feature map boundaryif (y < -1.0 || y > height || x < -1.0 || x > width) {// emptyreturn 0;}if (y <= 0) {y = 0;}if (x <= 0) {x = 0;}int y_low = (int)y;int x_low = (int)x;int y_high;int x_high;if (y_low >= height - 1) {y_high = y_low = height - 1;y = (T)y_low;} else {y_high = y_low + 1;}if (x_low >= width - 1) {x_high = x_low = width - 1;x = (T)x_low;} else {x_high = x_low + 1;}T ly = y - y_low;T lx = x - x_low;T hy = 1. - ly, hx = 1. - lx;// do bilinear interpolation// 由最近的4个点插值得到,示意图更清楚T v1 = bottom_data[y_low * width + x_low];T v2 = bottom_data[y_low * width + x_high];T v3 = bottom_data[y_high * width + x_low];T v4 = bottom_data[y_high * width + x_high];// 对应下面公式hx:1-u hy:1-v lx:u ly:vT w1 = hy * hx, w2 = hy * lx, w3 = ly * hx, w4 = ly * lx;T val = (w1 * v1 + w2 * v2 + w3 * v3 + w4 * v4);return val;
}

f(i+u,j+v) = (1-u)(1-v)f(i,j)+ u(1-v)f(i+1,j) + (1-u)vf(i,j+1) + uvf(i+1,j+1)


引用:
caffe2/operators/roi_align_op.cu
mask rcnn解读
Deformable Convolutional Networks解读

RoIAlign源码解析相关推荐

  1. 谷歌BERT预训练源码解析(二):模型构建

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/weixin_39470744/arti ...

  2. 谷歌BERT预训练源码解析(三):训练过程

    目录 前言 源码解析 主函数 自定义模型 遮蔽词预测 下一句预测 规范化数据集 前言 本部分介绍BERT训练过程,BERT模型训练过程是在自己的TPU上进行的,这部分我没做过研究所以不做深入探讨.BE ...

  3. 谷歌BERT预训练源码解析(一):训练数据生成

    目录 预训练源码结构简介 输入输出 源码解析 参数 主函数 创建训练实例 下一句预测&实例生成 随机遮蔽 输出 结果一览 预训练源码结构简介 关于BERT,简单来说,它是一个基于Transfo ...

  4. Gin源码解析和例子——中间件(middleware)

    在<Gin源码解析和例子--路由>一文中,我们已经初识中间件.本文将继续探讨这个技术.(转载请指明出于breaksoftware的csdn博客) Gin的中间件,本质是一个匿名回调函数.这 ...

  5. Colly源码解析——结合例子分析底层实现

    通过<Colly源码解析--框架>分析,我们可以知道Colly执行的主要流程.本文将结合http://go-colly.org上的例子分析一些高级设置的底层实现.(转载请指明出于break ...

  6. libev源码解析——定时器监视器和组织形式

    我们先看下定时器监视器的数据结构.(转载请指明出于breaksoftware的csdn博客) /* invoked after a specific time, repeatable (based o ...

  7. libev源码解析——定时器原理

    本文将回答<libev源码解析--I/O模型>中抛出的两个问题.(转载请指明出于breaksoftware的csdn博客) 对于问题1:为什么backend_poll函数需要指定超时?我们 ...

  8. libev源码解析——I/O模型

    在<libev源码解析--总览>一文中,我们介绍过,libev是一个基于事件的循环库.本文将介绍其和事件及循环之间的关系.(转载请指明出于breaksoftware的csdn博客) 目前i ...

  9. libev源码解析——调度策略

    在<libev源码解析--监视器(watcher)结构和组织形式>中介绍过,监视器分为[2,-2]区间5个等级的优先级.等级为2的监视器最高优,然后依次递减.不区分监视器类型和关联的文件描 ...

最新文章

  1. Linux服务器生产环境中的文件删除与替换
  2. ES学习笔记之-AvgAggregation的实现过程分析
  3. 皮一皮:所以这也是大数据的一种?
  4. 学长毕业日记 :本科毕业论文写成博士论文的神操作20170326
  5. 微信公众开发api接口
  6. Vue.js入学教程
  7. 计算机第二道启动密码怎么设置,电脑一道密码怎么设置
  8. 命令行进入android设置,命令行编译生成APK
  9. Aspose.Cells基础使用方法整理
  10. my java note -------String 类的实例化
  11. “搏一搏,单车变摩托!”华为天才少年耗时四个月,将自行车强势升级为自动驾驶...
  12. java 友好变量单词_“友好”的英语单词是什么?
  13. jsp综合开发实例——夏日九宫格日记网
  14. HDDREG(硬盘坏道修复工具)v1.31绿色版
  15. 留学回国人员申办上海常住户口实施细则
  16. CentOS 7 VM虚拟机安装docker步骤
  17. Set集合和Collection集合
  18. 关于服务器忘记密码,如何清除。
  19. 【FFmpeg】做一个抖音/快手视频模板常用哪些功能
  20. 第6章gp_toolkit管理架构_gp_bloat_diag

热门文章

  1. 几个网赚网站--待验证
  2. jar包等概念的理解、yaml语法学习和多环境切换
  3. 列式存储的分布式数据库——HBase Shell与SQL实战操作(HBase Master高可用实现)
  4. Java中常见的50个错误、异常及规避技巧
  5. 玩魔兽世界的朋友必看,令人感动的MM(经典)
  6. 服务器系统突然爆满怎么解决,电脑内存突然爆满怎么办|电脑内存爆满的解决步骤...
  7. wps怎么导入access_mysql数据库中的表格数据如何导入wps中的excel,请问该怎么去做 | excel连接access数据库...
  8. 五一在家宅5天?前端开发工程师必读书单送给你!(文末大彩蛋!)
  9. android中画布大小设置,如何设置canvas大小?
  10. Airpods序列号怎么看 Airpods查看方法