Facebook,Kaiming He的PointRend我的阅读笔记

Point Rend笔记
模块的提出是为了解决Mask预测时候对于原图或 map上的像素的过采样和欠采样问题 。这个问题的核心在于,由于2d图像本身是以栅格化的形式保存图像,那么网络在预测Mask的时候,不可避免地会将所有像素都有同等地位地进行预测,而实际上我们更希望的是网络集中预测在物体边缘部分的地方,而物体内部则不需要过多地预测,那么前者就是欠采样,后者则是过采样 。
方法的思路借鉴于计算机图形学中理论,将图像分割任务当做是一个渲染问题,并提出了神经网络模块 。该模块能够通过迭代细分算法,自适应选取位置进行基于点分割预测 。这一模块可以应用在已有的实例分割和语义分割的模型上,从而增强预测Mask的精细度和降低,并能让分割输出更高的分辨率 。
原有问题创新点方法 渲染
计算机图形学中渲染是讲一个三维的模型显示到一个二维的均匀网格的像素图上 。虽然输出是均匀网格的数据,但是其背后的物理模型是连续表示的,通过一定的方法,可以计算出这个物体上的各种物理遮挡、属性表现出来的颜色、性状等 。
具体做法
将一个图像的分割任务的真实分割Mask,当做是某个连续模型(即渲染中的实际三维模型)的遮挡图(在这里是假设也是连续的),而输出的Mask则是渲染的以二维均匀网格表示的图形 。上述的连续模型就是网络中输出的 map,而 map的连续性可以通过插值的方式(文中使用二次线性插值)近似的到各个位置的值来近似 。在这里则使用一个小型的参数化函数进行得到的 map上(插值后得到的)逐像素的计算预测值,相当于渲染中对每个像素点值的物理或几何计算方法(如光线追踪).总体上,Mask在整个过程中如同渲染一样,从粗糙到精细的一个过程 。
根据上面思路,模块组成:
接下来将会详细叙述上面三个主要组成部分的工作方法 。
自适应选取点
【Facebook,Kaiming He的PointRend我的阅读笔记】的核心在于如何选取点,处于物体边缘的点,高频域的点需要重点关注 。
训练过程中的选取点:如果按照预测过程中的方式为训练point head选取点,其会导致引入了迭代环节,从而影响BP算法的实现,所以训练时选取的是非迭代方式的随机采样选取点 。这一随机取样遵循:偏向选取不确定的部分,同时在较为确定的部分有一定采样 。假设需要选取 N N N个点给point head进行训练 。具体步骤为:
Point-wise表示(提取特征)
选取点后,通过双线性插值方式从 map得到,其中 map可以是单张,也可以是多张,或FPN对应的位置,然后一起 。
但是,这样操作存在两个问题:
基于上述的考虑,可以从网络中加入粗糙的分割预测,如果通道传递的是不同类别的语义信息,那么粗糙分割预测则提供了全局性的上下信息 。这样的粗糙的分割预测可以由如轻量化的Mask RCNN网络得到 。
在的实现中,这一过程在////.py的point-函数中实现,使用的的是(除开加入粗糙的分割预测部分)torch.nn..(input, grid, mode=‘’, =‘zeros’, =None)函数,源码如下所示:
def point_sample(input, point_coords, **kwargs):"""A wrapper around :function:`torch.nn.functional.grid_sample` to support 3D point_coords tensors.Unlike :function:`torch.nn.functional.grid_sample` it assumes `point_coords` to lie inside[0, 1] x [0, 1] square.Args:input (Tensor): A tensor of shape (N, C, H, W) that contains features map on a H x W grid.point_coords (Tensor): A tensor of shape (N, P, 2) or (N, Hgrid, Wgrid, 2) that contains[0, 1] x [0, 1] normalized point coordinates.Returns:output (Tensor): A tensor of shape (N, C, P) or (N, C, Hgrid, Wgrid) that containsfeatures for points in `point_coords`. The features are obtained via bilinearinterplation from `input` the same way as :function:`torch.nn.functional.grid_sample`."""add_dim = Falseif point_coords.dim() == 3:add_dim = Truepoint_coords = point_coords.unsqueeze(2)output = F.grid_sample(input, 2.0 * point_coords - 1.0, **kwargs)#hereif add_dim:output = output.squeeze(3)return output
在文档中,torch.nn..(input, grid, mode=‘’, =‘zeros’, =None)的作用是根据给定的input的值,使用grid中提供的位置计算 。具体而言到4D的数据,有
输入
对于每一个输出位置 o u t p u t [ n , : , h , w ] [n,:,h,w] [n,:,h,w]由输入的二维向量 g r i d [ n , h , w ] grid[n,h,w] grid[n,h,w]决定 i n p u t input input的位于 ( x , y ) (x,y) (x,y)的像素,这个像素将会使用某种插值方式得到输出 o u t p u t [ n , : , h , w ] [n,:,h,w] [n,:,h,w],而插值方式取决于函数参数中的mode选项,默认为双线性插值方式 。
值得注意的是,g r i d grid grid中的需要采样像素的位置表示方式是使用 i n p u t input input中空间维度的归一化后得到的值,也就是说它 x , y x,y x,y的范围为 [ ? 1 , 1 ] [-1,1] [?1,1],例如如果 x = ? 1 , y = ? 1 x=-1,y=-1 x=?1,y=?1,那么这个采样点应该是 i n p u t input input的最左上角的像素 。假如超出了范围 [ ? 1 , 1 ] [-1,1] [?1,1]的话,由函数参数决定其值 。
但没有说明是怎么计算的方法,其实,这一操作是来自论文(, Max . from ) 。接下来叙说是如何进行计算的 。
提出了一种让各种神经网络结构得到处理空间变换的的能力的方法,而这种变换是可以根据每个样本设计,而且不需要增添任何标记,能够动态地将图片或 map变换,让有了这一空间变换模块的网络不仅能从图片中选取最相关区域,而且能将这些区域变换为能让后继网络更简单处理的输出 。效果如下图所示:
是一个可微的模块,用于在前馈时给 map作空间变换,而变换是根据特定输入而定的 。输入可以是单张或多张map,而输出为单张map 。可分为三部分,根据计算顺序分别为:
可以其中变换写作矩阵形式(具体查看论文),或者是下式
V i c = ∑ n H ∑ m W U n m c k ( x i s ? m ; Φ x ) k ( y i s ? n ; Φ y ) ? i ∈ [ 1 … H ′ W ′ ] ? c ∈ [ 1 … C ] V_{i}^{c}=\sum_{n}^{H} \sum_{m}^{W} U_{n m}^{c} k\left(x_{i}^{s}-m ; \Phi_{x}\right) k\left(y_{i}^{s}-n ; \Phi_{y}\right) \ i \in\left[1 \ldots H^{\prime} W^{\prime}\right] \ c \in[1 \ldots C] Vic?=n∑H?m∑W?Unmc?k(xis??m;Φx?)k(yis??n;Φy?)?i∈[1…H′W′]?c∈[1…C]
其中 Φ x \Phi_{x} Φx?和 Φ y \Phi_{y} Φy?为k ( . ) k(.) k(.)的参数,这个 k ( . ) k(.) k(.)定义了图形插值方式(如双线性插值方法),U n m c U_{n m}^{c} Unmc?为输入通道c位置 ( n , m ) (n,m) (n,m)的值,V i c V_{i}^{c} Vic?为输出通道c上序列号i的像素值 。下面的图可以比较直观地看出变换进行的操作,说明看原文的图注 。
回到中,可以看出,的第一步已经被自适应取点取代,而后续中步骤则由中的torch.nn..所计算,而中的参数mode则决定了 第三步中,在中也就是双线性插值 。最终产生了根据中自适应选点后变换的 map 。
Point head
得到了Point-wise表示的特征后,将其输入到简单的MLP(Multi-layer )中进行label预测 。MLP的权重是各个点都共享的 。在本文实现中使用的是和R-CNN相似的两层1024宽的隐藏层,预测每一类的输出 。
如果有理解错误,请多多包涵 。