文章目录

  • 原理
  • pytorch cuda源码阅读(前向)

原理

具体可参考:

  1. 详解 ROI Align 的基本原理和实现细节。这篇文章为整体的原理理解,并不涉及算法的具体实现。简单看。
  2. 双线性插值算法的详细总结。这篇文章涉及到算法的细节。就x,y点值的计算需要理解。重点理解以下公式:

pytorch cuda源码阅读(前向)

这里将总体流程写出来,并在程序中的相应位置有相应注释。仔细树立一下,理解还是比较容易的。
总体流程:

    1. 求出pw,ph,c,n,为了后面从bottom_data进行索引
    1. 求roi中每个bin的height,width
    1. 确定每个roi的bin的采样点个数
    1. 对每个bin中的采样点(x,y)利用双线性插值得到f(x,y),最后取个平均,得到当前index的值
    • 双线性插值流程

        1. f(0,0),f(0,1)分别是x,y的向下取整,f(1,0),f(1,1)理论上分别f(0,0),f(0,1)+1
        1. 利用图片中的公式进行双线性插值求得f(x,y)

具体程序

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 boundary// 取x,y临近的4个点做双线性插值if (y < -1.0 || y > height || x < -1.0 || x > width) {//emptyreturn 0;}if (y <= 0) y = 0;if (x <= 0) x = 0;// 1. f(0,0),f(0,1)分别是x,y的向下取整,f(1,0),f(1,1)理论上分别f(0,0),f(0,1)+1int 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;}// 2. 利用图片中的公式进行双线性插值求得f(x,y)T ly = y - y_low;T lx = x - x_low;T hy = 1. - ly, hx = 1. - lx;// do bilinear interpolationT v1 = bottom_data[y_low * width + x_low];            // 提取4个点的值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];T w1 = hy * hx, w2 = hy * lx, w3 = ly * hx, w4 = ly * lx;T val = (w1 * v1 + w2 * v2 + w3 * v3 + w4 * v4);return val;
}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 output// 1. 求出pw,ph,c,n,为了后面从bottom_data进行索引int 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 critical// 2. 求roi中每个bin的height,widthT 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// 3. 确定每个roi的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. = 4// 4. 对每个bin中的采样点(x,y)利用双线性插值得到f(x,y),最后取个平均,得到当前index的值T output_val = 0.;for (int iy = 0; iy < roi_bin_grid_h; iy ++) // e.g., iy = 0, 1{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.5for (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);T val = bilinear_interpolate(offset_bottom_data, height, width, y, x, index);output_val += val;}}output_val /= count;top_data[index] = output_val;}
}

ROI Align原理及cuda源码阅读相关推荐

  1. 【Vue原理】Vue源码阅读总结大会 - 序

    [Vue原理]Vue源码阅读总结大会 - 序 阅读源码准备了什么 1.掌握 Vue 所有API 2.JavaScript 扎实基础 3.看完 JavaScript 设计模式 4.学会调试 Vue 源码 ...

  2. 【Vue原理】Vue源码阅读总结大会

    专注 Vue 源码分享,为了方便大家理解,分为了白话版和 源码版,白话版可以轻松理解工作原理和设计思想,源码版可以更清楚内部操作和 Vue的美,喜欢我就关注我的公众号,好吧兄弟,不会让你失望的 阅读源 ...

  3. 【Spring 源码阅读】Spring IoC、AOP 原理小总结

    Spring IoC.AOP 原理小总结 前言 版本约定 正文 Spring BeanFactory 容器初始化过程 IoC 的过程 bean 完整的创建流程如下 AOP 的过程 Annotation ...

  4. 以太坊源码阅读3——MPT原理

    以太坊源码阅读3--MPT原理 介绍 MPT(Merkel-Patricia Tree),翻译为梅克尔-帕特里夏树 MPT提供了一个基于密码学验证的底层数据结构,用来存储键值对( key-value) ...

  5. Dubbo注册协议原理以及源码阅读

    前言 继上次小编所讲RPC协议暴露服务并且远程调用之后,小编这次给大家带来注册中心协议整体流程原理以及源码精讲,Dubbo协议服务暴露与引用以及源码分析文章中,远程服务暴露可以只通过RPC协议即可,那 ...

  6. 【源码阅读计划】浅析 Java 线程池工作原理及核心源码

    [源码阅读计划]浅析 Java 线程池工作原理及核心源码 为什么要用线程池? 线程池的设计 线程池如何维护自身状态? 线程池如何管理任务? execute函数执行过程(分配) getTask 函数(获 ...

  7. FreeSWITCH 1.10 源码阅读(3)-sofia 模块原理及其呼入处理流程

    文章目录 1. 前言 2. 源码分析 2.1 sofia 模块的加载 2.2 呼入的处理流程 1. 前言 SIP(Session Initiation Protocol) 是应用层的信令控制协议,有许 ...

  8. React 表单源码阅读笔记

    1 概念 1.1 什么是表单 实际上广义上的表单并不是特别好界定,维基上讲表单是一系列带有空格的文档,用于输写或选择.更具体的,在网页中表单主要负责数据采集的功能,我们下文中所提到的表单都指后者.如下 ...

  9. Darknet源码阅读【吐血整理,持续更新中】

    github地址 https://github.com/BBuf/Darknet Darknet源码阅读 Darknet是一个较为轻型的完全基于C与CUDA的开源深度学习框架,其主要特点就是容易安装, ...

  10. 应用监控CAT之cat-client源码阅读(一)

    CAT 由大众点评开发的,基于 Java 的实时应用监控平台,包括实时应用监控,业务监控.对于及时发现线上问题非常有用.(不知道大家有没有在用) 应用自然是最初级的,用完之后,还想了解下其背后的原理, ...

最新文章

  1. Storm(一)集群搭建
  2. Android Architecture Components Part2:LiveData
  3. google 浏览器清除缓存
  4. 判断手机号码是否符合要求
  5. 锁屏快捷键_全面屏 iPhone 锁屏快捷键美化,让你的 iPhone 更特别
  6. c51 嵌入汇编语言,在C51中嵌入汇编
  7. php代码输出sql语句,教你在Laravel中轻松容易的输出完整的SQL语句
  8. 共青城市大力推进国家智慧城市试点建设
  9. R语言使用cor.test函数检验两个数值向量之间的相关性系数是否具有统计显著性、对相关性系数进行显著性检验、基于pearson相关性检验
  10. 2018-2019年计算机类会议截稿日期汇总(更新至20180914)
  11. pl330 dmac驱动分析1--数据结构
  12. SpringMvc框架及SSM框架整合
  13. 恋爱计时:只要时间在走,我们的爱就在继续
  14. java标准差代码实现
  15. KNOWN_HOSTS处理
  16. java游戏开发杂谈 - 实现游戏主菜单
  17. SAP标准功能重复制造计划编制表实现生产排产初步分析
  18. Win10图标变白纸了,恢复方法
  19. AudioPlayer-简易音频播放器
  20. 2021-12-12 WPF面试题 相对于Winform,WPF有什么优势?

热门文章

  1. 工业摄像头传感器尺寸与像元尺寸的关系
  2. php apache mpm,RHEL 7 Apache MPM 配置
  3. python中分号中没内容_被“嫌弃”的分号的一生:不要在Python中使用无用分号了...
  4. mac操作系统如何访问共享计算机,windows电脑怎么访问苹果电脑共享文件夹
  5. 路由器修改dns服务器,路由器DNS怎么设置如何修改路由器DNS服务器地址
  6. JAVA代码重复率多少达标_【案例】代码重复率太高不要怕,求真老师教你化险为夷!...
  7. 性别为什么不适合建立索引-值重复率高的字段不适合建索引
  8. 当代计算机网络技术带来的影响,浅析当代网络技术
  9. [视频基础]流媒体码流、分辨率、采样率、比特率、gop、qp、fps、cvbr概念理解
  10. OCR通用文字识别接口