反卷积的计算与加速

  • 介绍
  • 插值补零法
  • 交错相加法
  • 小卷积核法


介绍

反卷积(标准叫法为转置卷积),是卷积的一种逆运算(注意:是卷积的逆运算,不是卷积的逆过程),属于上采样的一种,在计算机视觉的深度学习领域中被广泛用作超分辨率重建等。反卷积的详细推导过程可以看这篇。反卷积(Transposed Convolution)详细推导

本文将介绍三种反卷积计算方法(三种计算方法在数学上完全等价),并且简述每种方法的优劣。可以根据不同的加速平台选择不同的计算部署方法。
首先我们列举几个参数如下,
反卷积pytorch 反卷积计算过程_ide
其中反卷积pytorch 反卷积计算过程_人工智能_02,反卷积pytorch 反卷积计算过程_卷积_03分别是反卷积的kernel size和stride,反卷积pytorch 反卷积计算过程_卷积_03可以理解为feature map的放大倍数(在实际的超分网络中反卷积pytorch 反卷积计算过程_卷积_03常见为2,3,4,分别代表将feature map放大2倍,3倍,4倍)。

在本文介绍的每个方法下面用一个相同的例子来说明这些算法的等价性(golden数据采用TF的计算方式):
input(反卷积pytorch 反卷积计算过程_深度学习_06): 反卷积pytorch 反卷积计算过程_人工智能_07
kernel(反卷积pytorch 反卷积计算过程_深度学习_08): 反卷积pytorch 反卷积计算过程_反卷积pytorch_09
stride(反卷积pytorch 反卷积计算过程_反卷积pytorch_10),
output(反卷积pytorch 反卷积计算过程_ide_11): 反卷积pytorch 反卷积计算过程_卷积_12

插值补零法

此计算方法是目前最常见的计算反卷积的方法,核心思想就是在input feature map里的每个pixel之间插反卷积pytorch 反卷积计算过程_人工智能_13,将kernel在二维平面旋转180°,然后进行反卷积pytorch 反卷积计算过程_ide_14的常规卷积计算。其中反卷积pytorch 反卷积计算过程_人工智能_13的个数 反卷积pytorch 反卷积计算过程_反卷积pytorch_16反卷积pytorch 反卷积计算过程_卷积_03有关,具体数学关系为:
反卷积pytorch 反卷积计算过程_人工智能_18
此时反卷积的输入输出尺寸关系为:
反卷积pytorch 反卷积计算过程_卷积_19
实际用tensorflow或者其他框架进行反卷积计算时,必须指定输出图像的大小 反卷积pytorch 反卷积计算过程_ide_20,参考崔权:关于tf中的conv2d_transpose的用法,tensorflow反卷积层中也没有 反卷积pytorch 反卷积计算过程_ide_21这个参数( 注:TF中的padding只有’SAME’和’VALID’两种模式),我个人理解实际计算中的反卷积pytorch 反卷积计算过程_ide_21应该是由反卷积pytorch 反卷积计算过程_深度学习_23反推出来的。

让我们来看下面两张采用插值补零法的反卷积计算动图:

反卷积pytorch 反卷积计算过程_ide_24


上图中 反卷积pytorch 反卷积计算过程_人工智能_25,因此可以推算出该反卷积在top、bottom、left、right都补了1个反卷积pytorch 反卷积计算过程_人工智能_13

反卷积pytorch 反卷积计算过程_人工智能_27


上图中 反卷积pytorch 反卷积计算过程_人工智能_28,因此可以推算出该反卷积在top、left补了1个反卷积pytorch 反卷积计算过程_人工智能_13,而在bottom、right补了2个反卷积pytorch 反卷积计算过程_人工智能_13注:TF的计算规则是优先在top、left补2个反卷积pytorch 反卷积计算过程_人工智能_13,在bottom、right补1个反卷积pytorch 反卷积计算过程_人工智能_13)。

回到我们的例子,我们采用插值补零法计算反卷积的过程如下,

输入input插值补零(根据TF的计算规则): 反卷积pytorch 反卷积计算过程_ide_33

deconv kernel旋转180°: 反卷积pytorch 反卷积计算过程_深度学习_34

最后正向卷积得: 反卷积pytorch 反卷积计算过程_卷积_12
可以看出和TF golden结果一致。

优点:将反卷积转化成常规卷积,可以用专用的卷积加速器(NPU、DPU等各种xPU)进行加速计算。
缺点:需要在每个pixel间插0,那么从外部存储器(DDR)读取数据就会不连续,容易形成带宽bound;计算中也有很多冗余计算(乘0累加),实际计算效率(computation efficiency)也很低。

交错相加法

此方法是名符其实的“反”卷积,让我们回想下二维卷积的计算方法,一个 反卷积pytorch 反卷积计算过程_反卷积pytorch_36 的卷积核在以 stride 的间隔距离滑过input feature map,每一次滑动做一次卷积核和滑窗pixel的乘累加计算,并且得到一个output feature map中的一个pixel,如下图所示:

反卷积pytorch 反卷积计算过程_卷积_37


反卷积的计算就是正向卷积计算的逆向操作,先放图:

反卷积pytorch 反卷积计算过程_人工智能_38


具体计算过程就是input feature map上的每一个pixel和 反卷积pytorch 反卷积计算过程_反卷积pytorch_36 的卷积核点乘得到一个反卷积pytorch 反卷积计算过程_反卷积pytorch_36的patch,然后相邻的patch以间隔 stride 错位相加,如上图所示。一般来说,这种计算方法还需要对边界进行裁剪以符合output feature map的大小 反卷积pytorch 反卷积计算过程_ide_20

我们还是以计算为例,input每个pixel和反卷积核点乘得到9个 反卷积pytorch 反卷积计算过程_ide_42 patch:
反卷积pytorch 反卷积计算过程_人工智能_43

反卷积pytorch 反卷积计算过程_反卷积pytorch_44

反卷积pytorch 反卷积计算过程_人工智能_45

相邻patch以 stride=2 错位相加得: 反卷积pytorch 反卷积计算过程_ide_46

对最右列和最底行进行裁剪得到最终结果: 反卷积pytorch 反卷积计算过程_卷积_12

可以看出和TF golden结果一致。

优点:没有任何的冗余计算,不需要对输入补0。
缺点:无法利用专用的卷积加速器进行加速,但是适合用CPU或GPU这种比较通用的处理器进行计算(注:caffe的反卷积采用的就是此计算方法)。

小卷积核法

此方法是本人最为欣赏的一个方法,该方法将每一个大小为 反卷积pytorch 反卷积计算过程_ide_48 的反卷积核先在二维方向旋转180°,然后再将每一个反卷积核拆成 反卷积pytorch 反卷积计算过程_反卷积pytorch_49 个小卷积核(注:此时我们可以认为 反卷积pytorch 反卷积计算过程_卷积_50 扩大了 反卷积pytorch 反卷积计算过程_反卷积pytorch_49 倍),然后用这些小卷积核对input feature map做 反卷积pytorch 反卷积计算过程_深度学习_52 的正向卷积,最后通过depth2space将反卷积pytorch 反卷积计算过程_卷积_50方向的pixel重排到二维平面上。具体过程如下图示:

反卷积pytorch 反卷积计算过程_反卷积pytorch_54


上图kernel=3,stride=2的反卷积,我们先将其分拆并重排成4个kernel=2,stride=1的正向卷积核,重排方案如下:

反卷积pytorch 反卷积计算过程_卷积_55


图中的0-8代表二维 反卷积pytorch 反卷积计算过程_ide_42接着用这些正向卷积核对input feature map做正向卷积,得到4个output feature map,再用depth2space将 c_o 方向的数据重排到二维平面上。如下图所示:

反卷积pytorch 反卷积计算过程_ide_57


反卷积核的重排可以离线完成,不占用计算时间也不占用带宽。

回到我们的例子,deconv kernel拆成4个kernel=2的小卷积核:
反卷积pytorch 反卷积计算过程_反卷积pytorch_58反卷积pytorch 反卷积计算过程_人工智能_59反卷积pytorch 反卷积计算过程_ide_60反卷积pytorch 反卷积计算过程_反卷积pytorch_61

对input的左列和上行进行1次padding: 反卷积pytorch 反卷积计算过程_ide_62

用每个小卷积核对上面padding过的input进行stride=1的正向卷积得:
反卷积pytorch 反卷积计算过程_人工智能_63 , 反卷积pytorch 反卷积计算过程_反卷积pytorch_64 , 反卷积pytorch 反卷积计算过程_ide_65 , 反卷积pytorch 反卷积计算过程_人工智能_07

以上结果可以看成是4个通道的feature map,最后进行depth2space得:
反卷积pytorch 反卷积计算过程_卷积_12

可以看出和TF golden结果一致。

优点:可以用专用的卷积加速器加速反卷积计算,没有带宽bound。

缺点:卷积核重排比较复杂,没有统一的方案,部分卷积加速器可能不支持depth2space。