Deconvolution(逆卷积)

目前网上关于Deconvolution的文章写的着实不知所云,这里详细整理一篇出来。不敢说“一文读懂deconv”,但是“一文入门deconv”的牛还是敢吹的。

Deconvolution一般和转置卷积(transposed conv)、微步卷积(fractionally strided conv)的叫法等价,其一些常见的用途包括:

  1. 在ZF-Net中用于对feature map做可视化:https://arxiv.org/abs/1311.2901
  2. 在FCN中用于生成等于原图shape的图像:https://arxiv.org/abs/1411.4038
  3. 无监督的autoencoder和deconvNet中用于解码器:https://docs.microsoft.com/en-us/cognitive-toolkit/Image-Auto-Encoder-Using-Deconvolution-And-Unpooling 、https://ftp.cs.nyu.edu/~fergus/papers/matt_cvpr10.pdf
  4. DSSD、GAN中的应用。
    … …

Deconvolution(逆卷积)_第1张图片Deconvolution(逆卷积)_第2张图片
由上面的用途可以看到,deconv最大的作用是对feature map进行升采样,和双线性插值(bilinear interpolation)类似。下面我们来研究一下deconv本身。顾名思义,Deconvolution(逆卷积、去卷积)似乎应该是卷积(conv)的逆过程,然而实际上除了shape层面之外,二者在数值上没有任何可逆关系。deconv仅仅是一个普通的卷积层,在神经网络中也是需要通过梯度下降去学习的。所以,对于每个deconv层,我们实际上也能用另外一个deconv层去做恢复。(突然有个发现——如果用conv+deconv进行穿插排列组合是不是也能创造出许多新的网络架构emmm)
PyTorch代码见:https://pytorch.org/docs/stable/nn.html?highlight=trans#torch.nn.ConvTranspose2d。

核心原理

关于deconv的恢复原理,最核心的一条其实就是 (k-1) \textbf{(k-1)} (k-1)扩展(padding),来重要的事情说三遍: (k-1) \textbf{(k-1)} (k-1)扩展 (k-1) \textbf{(k-1)} (k-1)扩展 (k-1) \textbf{(k-1)} (k-1)扩展。不明白?先背下来再往下看。

最基本的形式

我们首先看看最基本的卷积形式:对于 ( m × m ) (m\times m) (m×m)特征图 I I I,用 ( k × k ) (k\times k) (k×k)的核做卷积,则得到的特征图 O O O ( m − k + 1 ) × ( m − k + 1 ) (m-k+1)\times(m-k+1) (mk+1)×(mk+1)。如果我们对 O O O (k-1) \textbf{(k-1)} (k-1)扩展得到 O ′ O' O,再用等大的 k × k k\times k k×k核做卷积,则得到的特征图 I ′ I' I边长是: ( m − k + 1 ) + 2 ( k − 1 ) − k + 1 = m (m-k+1)+2(k-1)-k+1=m (mk+1)+2(k1)k+1=m。示意图:
Deconvolution(逆卷积)_第3张图片Deconvolution(逆卷积)_第4张图片

如果加入了stride呢?

然后我们来看看加入stride之后的deconv。同样,对于 ( m × m ) (m\times m) (m×m)特征图 I I I,用 ( k × k ) (k\times k) (k×k)的核做卷积,计stride为 s s s。则得到的特征图 O O O ( m − k s + 1 ) × ( m − k s + 1 ) (\dfrac{m-k}{s}+1)\times(\dfrac{m-k}{s}+1) (smk+1)×(smk+1)。同样,我们对 O O O (k-1) \textbf{(k-1)} (k-1)扩展,再用等大的 k × k k\times k k×k核做卷积。和上面不同的是,这次我们加入相同的stride,也就是对 O O O做膨胀得到 O ′ O' O(抱歉我想不到更合适的词了,见下面的示意图),卷积过程中卷积核不做跨步。 O ′ O' O的边长是 ( m − k s + 1 ) + 2 ( k − 1 ) + ( s − 1 ) ( m − k s + 1 − 1 ) (\dfrac{m-k}{s}+1)+2(k-1)+(s-1)(\dfrac{m-k}{s}+1-1) (smk+1)+2(k1)+(s1)(smk+11),化简得到 ( m + k − 1 ) (m+k-1) (m+k1)。则用等大的 ( k × k ) (k\times k) (k×k)核做卷积之后同样能恢复原来的shape m m m。当然了,此处令 s = 1 s=1 s=1则能推出前一段的特殊情况。

Deconvolution(逆卷积)_第5张图片Deconvolution(逆卷积)_第6张图片

如果加入了padding呢?

好了,我们现在似乎已经对于deconv的可逆原理有了一定的了解。于是问题来了,加入pad之后呢?道理其实是一样的,我们只需要把上面的 m m m换成 m + 2 p m+2p m+2p即可。下面我们来算一下stride 1的情况:

对于 ( m × m ) (m\times m) (m×m)特征图 I I I,先pad p p p,用 ( k × k ) (k\times k) (k×k)的核做卷积,则得到的特征图 O O O ( m + 2 p − k + 1 ) × ( m + 2 p − k + 1 ) (m+2p-k+1)\times(m+2p-k+1) (m+2pk+1)×(m+2pk+1)。如果我们对 O O O p ′ p' p扩展得到 O ′ O' O,再用等大的 k × k k\times k k×k核做卷积,则得到的特征图 I ′ I' I边长是: ( m + 2 p − k + 1 ) + 2 p ′ − k + 1 = m (m+2p-k+1)+2p'-k+1=m (m+2pk+1)+2pk+1=m

所以有:
2 p − 2 k + 2 + 2 p ′ = 0 2p-2k+2+2p'=0 2p2k+2+2p=0
p ′ = k − 1 − p p'=k-1-p p=k1p
所以第一节的核心原理要更新一下——做扩展 p ′ = k − 1 − p p'=k-1-p p=k1p之后再卷积。如图:
Deconvolution(逆卷积)_第7张图片Deconvolution(逆卷积)_第8张图片

如果是最一般的形式,即既有padding,又有stride呢?

道理其实是一样的。这里大概列一个计算步骤,详细过程感兴趣的朋友可以自己推一遍。
特征图 I I I m × m m\times m m×m
做pad得到 I ′ I' I ( m + 2 p ) × ( m + 2 p ) (m+2p)\times (m+2p) (m+2p)×(m+2p)
卷积后得到特征图 O O O ( m + 2 p − k s + 1 ) × ( m + 2 p − k s + 1 ) (\dfrac{m+2p-k}{s}+1)\times(\dfrac{m+2p-k}{s}+1) (sm+2pk+1)×(sm+2pk+1)
做pad p ′ p' p得到 O ′ O' O ( m + 2 p − k s + 1 + 2 p ′ ) × ( m + 2 p − k s + 1 + 2 p ′ ) (\dfrac{m+2p-k}{s}+1+2p')\times(\dfrac{m+2p-k}{s}+1+2p') (sm+2pk+1+2p)×(sm+2pk+1+2p)
做stride s s s得到 O ′ ′ O'' O ( m + 2 p − k s + 1 + 2 p ′ + ( s − 1 ) ( m + 2 p − k s + 1 − 1 ) ) × ( m + 2 p − k s + 1 + 2 p ′ + ( s − 1 ) ( m + 2 p − k s + 1 − 1 ) ) (\dfrac{m+2p-k}{s}+1+2p'+(s-1)(\dfrac{m+2p-k}{s}+1-1))\times(\dfrac{m+2p-k}{s}+1+2p'+(s-1)(\dfrac{m+2p-k}{s}+1-1)) (sm+2pk+1+2p+(s1)(sm+2pk+11))×(sm+2pk+1+2p+(s1)(sm+2pk+11))
deconv之后得到的特征图 I ′ ′ I'' I边长是: O ′ ′ 的 边 长 − k + 1 O''的边长-k+1 Ok+1
I ′ ′ I'' I边长为 m m m。解得 p ′ = k − 1 − p p'=k-1-p p=k1p

To do

空洞卷积(dilated convolution)、从矩阵乘法的角度理解卷积和逆卷积。

ref:
https://github.com/vdumoulin/conv_arithmetic

你可能感兴趣的:(CV,deconvolution,逆卷积,转置卷积,微步卷积)