什么是反卷积层?


187

我最近读了乔纳森·朗(Jonathan Long),埃文·谢尔哈默(Evan Shelhamer)和特雷弗·达雷尔(Trevor Darrell)撰写的用于语义分割全卷积网络。我不了解“反卷积层”的作用/作用方式。

相关部分是

3.3。向上采样是向后跨步的卷积

将粗略输出连接到密集像素的另一种方法是插值。例如,简单的双线性插值通过仅依赖于输入和输出像元的相对位置的线性映射从最近的四个输入计算每个输出。 从某种意义上讲,使用因子进行的上采样是具有1 / f的分数输入步幅的卷积。只要f是整数,向上采样的自然方法就是以输出步幅f向后进行卷积(有时称为反卷积) 。这样的操作很容易实现,因为它简单地反转了卷积的前进和后退。yij
f˚Fff
因此,通过从像素方向的损失进行反向传播,在网络中执行上采样以进行端到端学习。
注意,在这样的层中的去卷积滤波器不必是固定的(例如,固定为双线性上采样),而是可以学习的。一堆解卷积层和激活函数甚至可以学习非线性上采样。
在我们的实验中,我们发现网络内上采样对于学习密集预测是快速有效的。我们最好的分割架构使用这些层来学习上采样,以进行第4.2节中的精确预测。

我不认为我真的了解卷积层是如何训练的。

我想我了解的是,内核大小为卷积层学习大小为过滤器。卷积层的内核大小为,步幅为和过滤器的输出的尺寸为。但是,我不知道卷积层的学习是如何工作的。(如果有帮助,我知道简单的MLP如何通过梯度下降来学习)。ķ × ķ ķ 小号Ñ Ñkk×kksNnInput dims2n

因此,如果我对卷积层的理解是正确的,我不知道如何将其逆转。

有人可以帮我理解反卷积层吗?


3
该视频讲座介绍了解卷积/上采样:youtu.be/ByjaPdWXKJ4?
t=16m59s

6
希望对任何人有用,我制作了一个笔记本,探讨如何在TensorFlow(0.11)中使用卷积和转置卷积。也许有一些实际的例子和数据可能会有助于理解它们的工作原理。
AkiRoss

1
对我来说,这个页面给我一个更好的解释,也解释了去卷积和卷积转之间的区别:towardsdatascience.com/...
T.Antoni

因为没有参数,上采样不是更像是反向池而不是反向跨步卷积?
肯·菲林

注:名称“解卷积层”是一种误导,因为这层不执行反卷积
user76284

Answers:


209

反卷积层是一个非常不幸的名称,应该称为转置卷积层

视觉上,对于跨步为1且没有填充的转置卷积,我们只需将原始输入(蓝色条目)填充为零(白色条目)即可(图1)。

图1

在第二步和填充的情况下,转置的卷积看起来像这样(图2):

图2

你可以找到卷积码运算的多(大)的可视化在这里


16
只是为了确保我理解:“反卷积”与卷积几乎相同,但是您添加了一些填充吗?(围绕图像/当每个像素周围s> 1时)?
Martin Thoma

17
是的,反卷积层也执行卷积!这就是为什么转置卷积比名称更合适的原因,而反卷积实际上是一种误导。
David Dao

11
如果实际输入是零填充的,为什么在图1中说“不填充”?
Stas S

8
:顺便说一句:这就是所谓的现在换位卷积TensorFlow tensorflow.org/versions/r0.10/api_docs/python/...
马丁托马

9
感谢这个非常直观的答案,但是我对为什么第二个是“大步走第二”的情况感到困惑,当内核移动时,它的行为与第一个完全相同。
2013年

49

我认为,获得卷积背后真正基本水平直觉的一种方法是,在输入图像上滑动K个滤镜,您可以将其视为K个模具,并产生K个激活-每个激活都表示与特定模具的匹配程度。相反的操作是进行K次激活并将其扩展为卷积操作的原像。因此,对反向操作的直观解释大致是在给定模板(过滤器)和激活(每个模板的匹配程度)的情况下进行图像重建,因此,在基本的直观层次上,我们希望通过模板遮罩炸毁每个激活并将它们加起来

了解deconv的另一种方法是检查Caffe中的反卷积层实现,请参见以下相关代码位:

DeconvolutionLayer<Dtype>::Forward_gpu
ConvolutionLayer<Dtype>::Backward_gpu
CuDNNConvolutionLayer<Dtype>::Backward_gpu
BaseConvolutionLayer<Dtype>::backward_cpu_gemm

您可以看到,它在Caffe中的实现与常规正向卷积层的backprop完全一样(对我来说,在我比较cuDNN转换层中的backprop的实现与使用GEMM实现的ConvolutionLayer :: Backward_gpu之后,这一点更加明显)。因此,如果您完成反向传播以进行常规卷积的工作,您将了解在机械计算级别上会发生什么。该计算的工作方式与本简介第一段中描述的直觉相匹配。

但是,我不知道卷积层的学习是如何工作的。(如果有帮助,我知道简单的MLP如何通过梯度下降来学习)。

为了回答第一个问题中的另一个问题,MLP反向传播(完全连接的层)和卷积网络之间有两个主要区别:

1)权重的影响是局部的,因此首先要弄清楚如何对3x3滤波器进行反向传播,例如将3x3滤波器与输入图像的3x3小区域卷积在一起,映射到结果图像中的单个点。

2)为空间不变性共享卷积滤波器的权重。实际上,这意味着在前向通过中,将具有相同权重的相同3x3滤镜拖动到具有相同权重的整个图像中,以进行正向计算以产生输出图像(针对该特定滤镜)。这对反向传播意味着什么,就是在源图像中每个点的反向传播梯度在向前通过过程中拖动滤镜的整个范围内求和。注意,由于需要向后传播dLoss / dx,因此损耗wrt x,w和偏差也存在不同的梯度,而dLoss / dw是我们更新权重的方式。w和bias是计算DAG中的独立输入(没有先前的输入),因此无需对它们进行反向传播。

(my notation here assumes that convolution is y = x*w+b where '*' is the convolution operation)

7
我认为这是此问题的最佳答案。
kli_nlpr

8
我同意这是最好的答案。最重要的答案有漂亮的动画,但是直到我读完此答案,它们才看起来像是常规卷积并带有任意填充。哦,人们如何被眼神的糖果所左右。
Reii Nakano

1
同意,接受的答案没有解释任何问题。这样好多了。
BjornW

感谢您的出色解释。我目前无法弄清楚如何正确地进行反向传播。你能给我一个提示吗?
巴斯蒂安

33

逐步数学解释了转置卷积如何使用3x3滤波器和2步幅进行2x升采样:

在此处输入图片说明

用于验证数学的最简单的TensorFlow代码段:

import tensorflow as tf
import numpy as np

def test_conv2d_transpose():
    # input batch shape = (1, 2, 2, 1) -> (batch_size, height, width, channels) - 2x2x1 image in batch of 1
    x = tf.constant(np.array([[
        [[1], [2]], 
        [[3], [4]]
    ]]), tf.float32)

    # shape = (3, 3, 1, 1) -> (height, width, input_channels, output_channels) - 3x3x1 filter
    f = tf.constant(np.array([
        [[[1]], [[1]], [[1]]], 
        [[[1]], [[1]], [[1]]], 
        [[[1]], [[1]], [[1]]]
    ]), tf.float32)

    conv = tf.nn.conv2d_transpose(x, f, output_shape=(1, 4, 4, 1), strides=[1, 2, 2, 1], padding='SAME')

    with tf.Session() as session:
        result = session.run(conv)

    assert (np.array([[
        [[1.0], [1.0],  [3.0], [2.0]],
        [[1.0], [1.0],  [3.0], [2.0]],
        [[4.0], [4.0], [10.0], [6.0]],
        [[3.0], [3.0],  [7.0], [4.0]]]]) == result).all()

我认为您的计算是错误的。中间输出应为3+ 2 * 2 = 7,然后对于3x3内核,最终输出应为7-3 + 1 = 5x5
Alex

抱歉,@ Alex,但我不明白为什么中间输出是7。请详细说明一下吗?
andriys

2
@andriys在您显示的图像中,为什么最终结果被裁剪?
詹姆斯·邦德

28

斯坦福CS类CS231n安德烈·卡帕西(Andrej Karpathy)编写的CS231n用于视觉识别的卷积神经网络附带注释在解释卷积神经网络方面做得非常出色。

阅读本文应该使您大致了解:

  • 反卷积网络 Matthew D.Zeiler,Dilip Krishnan,Graham W.Taylor和Rob Fergus纽约大学Courant研究所计算机科学系

这些幻灯片非常适合反卷积网络。


29
是否可以在很短的段落中总结这些链接中任何一个的内容?这些链接可能对进一步研究很有用,但理想情况下,堆栈交换答案应具有足够的文本来解决基本问题,而无需离开现场。
尼尔·斯莱特

抱歉,这些页面的内容太大,无法在简短的段落中进行总结。
Azrael15年

12
不需要标题的完整摘要,例如“反卷积神经网络类似于CNN,但经过训练后可以使用任何隐藏层中的特征来重建前一层(并通过跨层重复,最终输入可以从输出中重构出来。这使它可以在无监督的情况下进行训练,以便学习问题域中的通用高级功能-通常是图像处理”(请注意,我什至不确定那是否正确,因此无法编写自己的答案)。
尼尔·斯莱特

6
尽管链接很好,但是用您自己的话简要描述模型会更好。
SmallChess 2015年

11

刚刚从theaon网站上找到了有关该主题的精彩文章[1]:

对转置卷积的需求通常是由于希望使用与正常卷积相反的方向进行变换以将特征图投影到更高维度的空间而产生的。即,从4维空间映射到16维空间,同时保持卷积的连通性模式。

转置卷积(也称为分数跨步卷积)通过交换卷积的前进和后退路径来工作。一种表达方式是注意内核定义了卷积,但是它是直接卷积还是转置卷积取决于如何计算正向和反向遍历。

可以将转置卷积操作视为某些卷积相对于其输入的梯度,这通常是实践中如何实现转置卷积。

最后请注意,始终可以通过直接卷积实现转置卷积。缺点是它通常涉及将许多零列和零行添加到输入中,导致实现效率大大降低。

因此,简而言之,“转置卷积”是使用矩阵的数学运算(就像卷积一样),但是在您想要从卷积值返回到原始值(相反方向)的情况下,它比普通卷积运算更有效。这就是为什么在实现中优选在计算相反方向时进行卷积(即避免因填充输入而导致的稀疏矩阵导致许多不必要的0乘法)。

Image ---> convolution ---> Result

Result ---> transposed convolution ---> "originalish Image"

有时,您会沿卷积路径保存一些值,并在“返回”时重用该信息:

Result ---> transposed convolution ---> Image

这可能就是它被错误地称为“反卷积”的原因。但是,它确实与卷积的矩阵转置(C ^ T)有关,因此更合适的名称为“转置卷积”。

因此,在考虑计算成本时,这很有意义。如果不使用转置卷积,您将为亚马逊GPU付出更多。

在此处仔细阅读并观看动画:http : //deeplearning.net/software/theano_versions/dev/tutorial/conv_arithmetic.html#no-zero-padding-unit-strides-transposed

其他一些相关的读物:

滤波器的转置(或更普遍地,埃尔米特或共轭转置)就是匹配滤波器[3]。这是通过时间反转内核并采用所有值的共轭来发现的[2]。

我对此也不陌生,对于任何反馈或更正将不胜感激。

[1] http://deeplearning.net/software/theano_versions/dev/tutorial/conv_arithmetic.html

[2] http://deeplearning.net/software/theano_versions/dev/tutorial/conv_arithmetic.html#transposed-convolution-arithmetic

[3] https://zh.wikipedia.org/wiki/Matched_filter



1
我认为这是最好的答案!!!
kli_nlpr

10

我们可以使用PCA进行类比。

使用conv时,前向传递是从输入图像中提取主成分的系数,而后向传递(是更新输入)是使用系数(的斜率)来重建新的输入图像,以便新的输入图像具有PC系数,可以更好地匹配所需系数。

使用deconv时,前向通过和后向通过是相反的。正向遍历尝试根据PC系数重建图像,而后向遍历根据给定图像(的梯度)更新PC系数。

deconv正向传递完全按照这篇文章中给出的conv梯度计算:http ://andrew.gibiansky.com/blog/machine-learning/convolutional-neural-networks/

这就是为什么在deconv的caffe实现中(请参阅Andrei Pokrovsky的答案),deconv正向传递调用back_cpu_gemm(),而反向传递则调用forward_cpu_gemm()。


6

除了David Dao的回答:还可以反过来思考。除了关注哪个(低分辨率)输入像素用于生成单个输出像素外,您还可以关注哪个单个输入像素对输出像素的哪个区域起作用。

这是在此摘录出版物中完成的,包括一系列非常直观和交互式的可视化。朝这个方向思考的一个优势是,解释棋盘伪像变得容易。


5

从DSP角度看卷积

我有点迟了,但仍然想分享我的观点和见解。我的背景是理论物理学和数字信号处理。特别是,我几乎研究了小波和卷积;)

深度学习社区中人们谈论卷积的方式也让我感到困惑。在我看来,似乎缺少的是适当分离关注点。我将解释使用一些DSP工具进行的深度学习卷积。

免责声明

为了阐明要点,我的解释将有些麻烦,而且数学上并不严格。


定义

让我们先定义一些东西。我将讨论限于一维(扩展到更大的维度是直截了当的)无限的(因此我们不需要弄乱边界)序列。xn={xn}n=={,x1,x0,x1,}

两个序列和之间的纯(离散)卷积定义为ynxn

(yx)n=k=ynkxk

如果我们用矩阵向量运算的形式来编写,则看起来像这样(假设一个简单的内核和向量):q=(q0,q1,q2)x=(x0,x1,x2,x3)T

qx=(q1q000q2q1q000q2q1q000q2q1)(x0x1x2x3)

让我们分别介绍下采样和上采样运算符和。通过系数下采样将删除除第k个样本以外的所有样本:kN

kxn=xnk

并且因数上采样是在样本之间交织零:kk1

kxn={xn/kn/kZ0otherwise

例如,我们有:k=3

3{,x0,x1,x2,x3,x4,x5,x6,}={,x0,x3,x6,}
3{,x0,x1,x2,}={x0,0,0,x1,0,0,x2,0,0,}

或根据矩阵运算(此处)编写:k=2

2x=(x0x2)=(10000010)(x0x1x2x3)

2x=(x00x10)=(10000100)(x0x1)

正如人们已经可以看到的,向下和上采样运算符相互调换,即。k=kT


深度学习卷积

让我们看一下深度学习中使用的典型卷积以及如何编写它们。给定一些内核和向量我们具有以下内容:qx

  • 跨度为的跨步卷积为,kk(qx)
  • 因子为的扩张卷积为,k(kq)x
  • 步长为的转置卷积为kq(kx)

让我们重新排列一下转置的卷积:

q(kx)=q(kTx)=(k(q)T)Tx

在这种表示法必须将其作为运算符来读取,即,它将与内核卷积的内容抽象化。或用矩阵运算编写(示例):(q)q

q(kx)=(q1q000q2q1q000q2q1q000q2q1)(10000100)(x0x1)=(q1q200q0q1q200q0q1q200q0q1)T(10000010)T(x0x1)=((10000010)(q1q200q0q1q200q0q1q200q0q1))T(x0x1)=(k(q)T)Tx

可以看到,是转置操作,即名称。

连接到最近的邻居上采样

在卷积网络中发现的另一种常见方法是使用某种内置形式的插值进行上采样。让我们通过简单的重复插值以因子2进行上采样。可以写成。如果我们还向其中添加一个可学习的内核,得到。卷积可以合并,例如对于,我们有2(11)xq2(11)qxq=(q0q1q2)

(11)q=(q0q0+q1q1+q2q2),

也就是说,我们可以用因子大小为2的重复上采样器和大小为3的内核的卷积替换为内核大小为4的转置卷积。此转置卷积具有相同的“插值能力”,但能够学习更好的匹配插值。


结论和最后评论

我希望我可以通过在基本操作中将它们分开来澄清一些在深度学习中发现的常见卷积。

我没有在这里盖池。但这只是非线性下采样器,也可以在此表示法内进行处理。


极好的答案。从数学/符号角度看通常可以使事情变得清晰。在这种情况下,“反卷积”一词与现有术语冲突时,我是否认为正确?
user76284

它并没有真正的冲突,只是没有意义。反卷积只是与上采样运算符的卷积。反卷积一词听起来像是某种形式的逆运算。在这里讨论逆仅在矩阵运算的上下文中才有意义。它与逆矩阵相乘,而不是卷积的逆运算(如除法与乘法)。
安德烈·伯格纳

对。根据正确的数学术语中,卷积产生了使得,而卷积得到的使得。后者与OP中所谓的“反卷积层”无关。幸好,我认为不赞成使用后者的名称,而采用了“上采样卷积”之类的方法。θ * X = ž ž θ * ž = Xzθx=zzθz=x
user76284

(最小范数)解卷积等效于由卷积矩阵(或者更确切地说,它的倒数乘以逆)。也就是说,如果,则。这可以为您的答案做一个很好的补充,因为它阐明了真正的反卷积实际上对应于什么。z = θ + xθz=xz=(θ)+x
user76284

简而言之,OP的所谓“反卷积层”实际上并没有进行反卷积。它正在做其他事情(您在答案中描述的内容)。
user76284

4

在遇到这篇博客文章之前,我很难理解本文中到底发生了什么:http : //warmspringwinds.github.io/tensorflow/tf-slim/2016/11/22/upsampling-and-image-segmentation与tensorflow和tf-slim /

这是我如何理解2倍上采样中发生情况的摘要:

纸上信息

简单的例子

  1. 想象以下输入图像:

输入图像

  1. 分数步法卷积的工作原理是在这些值之间插入factor-1 = 2-1 = 1个零,然后再假设stride = 1。因此,您收到以下6x6填充的图像

填充图像

  1. 双线性4x4滤镜看起来像这样。选择其值,以使使用的权重(=所有权重未与插入的零相乘)总和为1。它的三个唯一值分别为0.56、0.19和0.06。此外,按照惯例,滤波器的中心是第三行和第三列中的像素。

过滤

  1. 在填充的图像上应用4x4滤镜(使用padding ='same'和stride = 1)会产生以下6x6上采样图像:

放大图片

  1. 对每个通道分别执行这种上采样(请参阅https://github.com/shelhamer/fcn.berkeleyvision.org/blob/master/surgery.py的第59行)。最后,使用双线性插值和有关如何处理边界的约定,2x上采样实际上是非常简单的调整大小。我相信16倍或32倍的升采样的工作方式几乎相同。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.