ROI Align原理及cuda源码阅读
文章目录
- 原理
- pytorch cuda源码阅读(前向)
原理
具体可参考:
- 详解 ROI Align 的基本原理和实现细节。这篇文章为整体的原理理解,并不涉及算法的具体实现。简单看。
- 双线性插值算法的详细总结。这篇文章涉及到算法的细节。就x,y点值的计算需要理解。重点理解以下公式:
pytorch cuda源码阅读(前向)
这里将总体流程写出来,并在程序中的相应位置有相应注释。仔细树立一下,理解还是比较容易的。
总体流程:
- 求出pw,ph,c,n,为了后面从bottom_data进行索引
- 求roi中每个bin的height,width
- 确定每个roi的bin的采样点个数
- 对每个bin中的采样点(x,y)利用双线性插值得到f(x,y),最后取个平均,得到当前index的值
- 双线性插值流程
- f(0,0),f(0,1)分别是x,y的向下取整,f(1,0),f(1,1)理论上分别f(0,0),f(0,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源码阅读相关推荐
- 【Vue原理】Vue源码阅读总结大会 - 序
[Vue原理]Vue源码阅读总结大会 - 序 阅读源码准备了什么 1.掌握 Vue 所有API 2.JavaScript 扎实基础 3.看完 JavaScript 设计模式 4.学会调试 Vue 源码 ...
- 【Vue原理】Vue源码阅读总结大会
专注 Vue 源码分享,为了方便大家理解,分为了白话版和 源码版,白话版可以轻松理解工作原理和设计思想,源码版可以更清楚内部操作和 Vue的美,喜欢我就关注我的公众号,好吧兄弟,不会让你失望的 阅读源 ...
- 【Spring 源码阅读】Spring IoC、AOP 原理小总结
Spring IoC.AOP 原理小总结 前言 版本约定 正文 Spring BeanFactory 容器初始化过程 IoC 的过程 bean 完整的创建流程如下 AOP 的过程 Annotation ...
- 以太坊源码阅读3——MPT原理
以太坊源码阅读3--MPT原理 介绍 MPT(Merkel-Patricia Tree),翻译为梅克尔-帕特里夏树 MPT提供了一个基于密码学验证的底层数据结构,用来存储键值对( key-value) ...
- Dubbo注册协议原理以及源码阅读
前言 继上次小编所讲RPC协议暴露服务并且远程调用之后,小编这次给大家带来注册中心协议整体流程原理以及源码精讲,Dubbo协议服务暴露与引用以及源码分析文章中,远程服务暴露可以只通过RPC协议即可,那 ...
- 【源码阅读计划】浅析 Java 线程池工作原理及核心源码
[源码阅读计划]浅析 Java 线程池工作原理及核心源码 为什么要用线程池? 线程池的设计 线程池如何维护自身状态? 线程池如何管理任务? execute函数执行过程(分配) getTask 函数(获 ...
- FreeSWITCH 1.10 源码阅读(3)-sofia 模块原理及其呼入处理流程
文章目录 1. 前言 2. 源码分析 2.1 sofia 模块的加载 2.2 呼入的处理流程 1. 前言 SIP(Session Initiation Protocol) 是应用层的信令控制协议,有许 ...
- React 表单源码阅读笔记
1 概念 1.1 什么是表单 实际上广义上的表单并不是特别好界定,维基上讲表单是一系列带有空格的文档,用于输写或选择.更具体的,在网页中表单主要负责数据采集的功能,我们下文中所提到的表单都指后者.如下 ...
- Darknet源码阅读【吐血整理,持续更新中】
github地址 https://github.com/BBuf/Darknet Darknet源码阅读 Darknet是一个较为轻型的完全基于C与CUDA的开源深度学习框架,其主要特点就是容易安装, ...
- 应用监控CAT之cat-client源码阅读(一)
CAT 由大众点评开发的,基于 Java 的实时应用监控平台,包括实时应用监控,业务监控.对于及时发现线上问题非常有用.(不知道大家有没有在用) 应用自然是最初级的,用完之后,还想了解下其背后的原理, ...
最新文章
- Storm(一)集群搭建
- Android Architecture Components Part2:LiveData
- google 浏览器清除缓存
- 判断手机号码是否符合要求
- 锁屏快捷键_全面屏 iPhone 锁屏快捷键美化,让你的 iPhone 更特别
- c51 嵌入汇编语言,在C51中嵌入汇编
- php代码输出sql语句,教你在Laravel中轻松容易的输出完整的SQL语句
- 共青城市大力推进国家智慧城市试点建设
- R语言使用cor.test函数检验两个数值向量之间的相关性系数是否具有统计显著性、对相关性系数进行显著性检验、基于pearson相关性检验
- 2018-2019年计算机类会议截稿日期汇总(更新至20180914)
- pl330 dmac驱动分析1--数据结构
- SpringMvc框架及SSM框架整合
- 恋爱计时:只要时间在走,我们的爱就在继续
- java标准差代码实现
- KNOWN_HOSTS处理
- java游戏开发杂谈 - 实现游戏主菜单
- SAP标准功能重复制造计划编制表实现生产排产初步分析
- Win10图标变白纸了,恢复方法
- AudioPlayer-简易音频播放器
- 2021-12-12 WPF面试题 相对于Winform,WPF有什么优势?
热门文章
- 工业摄像头传感器尺寸与像元尺寸的关系
- php apache mpm,RHEL 7 Apache MPM 配置
- python中分号中没内容_被“嫌弃”的分号的一生:不要在Python中使用无用分号了...
- mac操作系统如何访问共享计算机,windows电脑怎么访问苹果电脑共享文件夹
- 路由器修改dns服务器,路由器DNS怎么设置如何修改路由器DNS服务器地址
- JAVA代码重复率多少达标_【案例】代码重复率太高不要怕,求真老师教你化险为夷!...
- 性别为什么不适合建立索引-值重复率高的字段不适合建索引
- 当代计算机网络技术带来的影响,浅析当代网络技术
- [视频基础]流媒体码流、分辨率、采样率、比特率、gop、qp、fps、cvbr概念理解
- OCR通用文字识别接口