参考:稀疏卷积 Sparse Convolution Net - 知乎 (zhihu.com)
原文链接:How does sparse convolution work? | by Zhiliang Zhou | Towards Data Science
最近在学习关于稀疏卷积的知识,对稀疏卷积的计算感到比较困惑,网上相关的讲解对我来说都不是很详细(也许是我太笨),于是想记录一下自己对于Rulebook计算的理解,万一某一天就又忘了o( ̄┰ ̄*)ゞ。
关于什么是稀疏卷积这里不在进行过多的介绍,网上相关的文章很多,这里主要解释一下稀疏矩阵的计算实现
输入
这里我们引用官方的例子,输入是一个通道为3,长宽为5*5的输入,其中只有p1,p2点是有效输入,其余点均为0,图中右下角给出了p1,p2的值(以为有三个输入通道因此值都为3维)。
接着我们定义两个3*3的卷积核表示输出通道为2。
输出
稀疏卷积有两种输出一种是regular output definition,就像普通卷积一样,只要核覆盖一个输入点就计算输出点。 另一种称为submanifold output definition。 只有当核中心覆盖输入站点时,才会计算卷积输出。
这张图是regular output definition只要卷积核范围内有有效数据就输出
这种为submanifold output,只有卷积核的中心位于有效点时才产生输出
(注意这两张图表示的都是输出所以大小才为3*3)
A1,A2的含义
我们发现在计算计算第一个红框时,卷积核包含了p1的数值于是在输出中对应的位置为A1,而第二个红框包含了p1与p2这两点的数值因此对应的输出为A1,A2(意思这一点的输出采用了p1,p2这两个点的数据)
随着卷积核的移动最后计算出输出跟哪几个点有关
计算实现
稀疏卷积通过Rulebook来实现计算
建立哈希表
注:图中右下角(1,0)、(2,0)箭头方向画错了。应该分别对应序号1、2。
对于这个表来说
代表输入点的序号,
代表其位置比如p1的位置为(2,1)序号为0(注意这里作者是按照图中x,y的顺序)
左图中间的3*3的矩阵表示与p1点有关的输出,右图为总的输出,我们把包含A1的部分提取出来就是左图,然后分别记录下这六个输出的位置就是左图最右边一列的值记为。对于p2点我们也进行同样的操作得到相应的输出位置的值(如下图所示)
再对所有的进行编序号得到
其中表示序号,
的值当作
的值但我们发现
的值有重复的所以最后
的值有8个刚好对应我们得到的总输出有8个有效输出
注:图中左下角的(1,0)、(2,0)箭头方向画错了,应该分别对应序号1、2。
建立RuleBook
RuleBook本质上来说就是一个表。记录了输入特征图中稀疏点(非零点)与卷积核操作后的输出点之间的映射关系
在解释这个图之前我们发现我们给kernel的每个点都编了一个位置,以中心点为原点。
1.从到GetOffset()
如下图所示, 5×5 的输入图像经过 3×3 的卷积核输出 3×3 的output。以output中(0,0)位置为例,该点的值是input左上角的 3×3 橙色窗口卷积得到,在这个橙色的窗口中只有右侧P1位置非零,其余位置均为零。那么这次卷积操作只需要通过这个位置的卷积权重和输入值计算得到。P1位置对应到卷积核中的位置就是(1,0)。我们把这个(1,0)放入GetOffset()结果中。
2.GetOffset到RuleBook
如图所示我们计算出核偏差后,按照一定的顺序编写Rulebook(),Rulebook里有四个属性分别为(i,j),count,v_in,v_out,(i,j)表示核偏移的位置,count表示相同核偏移的数量(?可能是吧我也不是很理解,可以理解为相同偏移量被分到同一个组中)v_in表示是第几个点的有效数据(为0是p1点,为1是p2点),v_out等于hash_out里的v_out(如下图所示)
稀疏卷积的GPU实现
以Rulebook第一行红色方框为例,首先通过(-1,-1)找到卷积核权重F0;其次,根据输入像素序号,查找输入哈希表找到对应的tensor向量(0.1,0.1,0.1);
然后,需要注意到的是下图中我们可以看到红色和蓝黑色的两个方框输出结果对应的序号都是5,意味着他们的输出结果在同一位置,是需要累加的。图中Output Sparse Tensor尺寸为 9×2 是因为9为输出热力图 3×3 ,2表示输出两通道。
最后,完成计算后再根据输出序号,找出行列坐标,放到输出tensor的对应位置。