图解转置卷积原理[通俗易懂]

图解转置卷积原理[通俗易懂]声明:本文大部分搬运自【机器学习】详解转置卷积(TransposeConvolution)感谢博主花与人间事同,本人只是在博主原创文章上做补充以及添加一些自己的理解。1转置卷积的背景通常,对图像进行多次卷积运算后,特征图的尺寸会不断缩小。而对于某些特定任务(如图像分割和图像生成等),需将图像恢复到原尺寸再操作。这个将图像由小分辨率映射到大分辨率的尺寸恢复操作,称为上采样(Upsample),如下图所示:上采样方法有很多,详见【图像处理】详解最近邻插值、线性插值、双线性插值、双三次插值

大家好,又见面了,我是你们的朋友全栈君。

声明:本文大部分搬运自【机器学习】详解 转置卷积 (Transpose Convolution)
感谢博主花与人间事同,本人只是在博主原创文章上做补充以及添加一些自己的理解。

1 转置卷积的背景

通常,对图像进行多次卷积运算后,特征图的尺寸会不断缩小。而对于某些特定任务 (如图像分割和图像生成等),需将图像恢复到原尺寸再操作。这个将图像由小分辨率映射到大分辨率的尺寸恢复操作,称为上采样 (Upsample),如下图所示:

在这里插入图片描述

上采样方法有很多,详见【图像处理】详解 最近邻插值、线性插值、双线性插值、双三次插值。然而,这些上采样方法都是基于人们的先验经验来设计的,规则固定且不可学习,在很多场景中效果并不理想。因此,我们希望神经网络自己学习如何更好地插值,即接下来要介绍的转置卷积

2 转置卷积的应用

曾经,转置卷积也被称为反卷积(Deconvolution)。与传统的上采样方法相比,转置卷积的上采样方式并非预设的插值方法,而是同标准卷积一样,具有可学习的参数,可通过网络学习来获取最优的上采样方式
转置卷积在某些特定领域具有广泛应用,比如:

  • 在 DCGAN 中,生成器将随机值转变为一个全尺寸图片,此时需用到转置卷积。
  • 在语义分割中,会在编码器中用卷积层提取特征,然后在解码器中恢复原先尺寸,从而对原图中的每个像素分类。该过程同样需用转置卷积。经典方法有 FCN 和 U-net 。
  • CNN 可视化:通过转置卷积将 CNN 的特征图还原到像素空间,以观察特定特征图对哪些模式的图像敏感。

3 转置卷积的区别

标准卷积的运算操作其实是对卷积核中的元素与输入矩阵上对应位置的元素进行逐像素的乘积并求和。然后,卷积核在输入矩阵上以步长为单位进行滑动,直到遍历完输入矩阵的所有位置。
假设,输入是一个 4×4 矩阵,使用 3×3 的标准卷积进行计算,同时令 padding=0,stride=1。最终输出结果应是一个 2×2 矩阵,如图 2 所示:

在这里插入图片描述

在上例中,输入矩阵右上角 3×3 范围的值 (黄色 2 3 4) 会影响输出矩阵右上角的值 (黄色 27),这其实也对应了标准卷积中感受野的概念。所以,可以说 3×3 标准卷积核 建立了 输入矩阵中 9 个值输出矩阵中 1 个值 的映射关系。
当然,从信息论的角度上看,常规卷积操作是不可逆的,所以转置卷积并不是通过输出矩阵和卷积核计算原始输入矩阵,而是计算得到保持了相对位置关系的矩阵
也就是说转置卷积是卷积的一个逆向过程,可以恢复卷积前的输入尺寸,而不是恢复原始值

4 转置卷积的推导

定义一个 4×4 输入矩阵 input:

在这里插入图片描述

再定义一个 3×3 标准卷积核 kernel:

在这里插入图片描述

设步长 stride=1、填充 padding=0,可得 2×2 输出矩阵 output:

在这里插入图片描述

这里开始我们换一个表达方式,将输入矩阵 input 和输出矩阵 output 展开成 16×1 列向量 X4×1 列向量 Y,可分别表示为:

在这里插入图片描述

接着再用矩阵运算来描述标准卷积运算,设有 新卷积核矩阵 C

在这里插入图片描述

经卷积运算关系推导,可得 4×16 稀疏矩阵 C

在这里插入图片描述

以下用图 4 展示矩阵运算过程:

在这里插入图片描述

而转置卷积其实就是要对这个过程进行逆运算,即 通过 C 和 Y 得到 X

在这里插入图片描述

此时, C T C^T CT即为新的 16×4 稀疏矩阵。以下通过图 5 展示转置后的卷积矩阵运算。需要注意的是,用于转置卷积的权重矩阵 C T C^T CT 不一定来自于原卷积矩阵 C C C (通常不会如此恰巧),但其形状和原卷积矩阵 C C C 的转置相同

在这里插入图片描述

最后,将 16×1 的输出结果重新排序,即可通过 2×2 输入矩阵得到 4×4 输出矩阵。

5 转置卷积的输出

这里主要想说明的是,转置卷积其实也是一种卷积,转置卷积可以等价于标准卷积

5.1 stride = 1, padding=0

同样,使用上文中的 3×3 卷积核矩阵 C

在这里插入图片描述

输出矩阵 output 仍为:

在这里插入图片描述

将输出矩阵展开为 列向量 Y

在这里插入图片描述

带入到上文中的转置卷积计算公式,则转置卷积的计算结果为:

在这里插入图片描述

这其实等价于 先填充 padding=2 的输入矩阵 input

在这里插入图片描述

然后,将标准卷积核 kernel朝上翻转,再朝左翻转,得到转置标准卷积核 kernel
以一个 2×2 的标准卷积核为例,操作的图示如下,右下角是我们标准卷积核。标准卷积核内不同的颜色代表值不同。根据 1 ,我们先沿着水平红色的轴将卷积核向上翻转,再根据 2 ,沿着竖直红色的轴朝左翻转,得到转置标准卷积核。

在这里插入图片描述

根据上面的方法,同理我们可以得到 3×3 的转置标准卷积核 kernel

在这里插入图片描述

最后,在 填零的输入矩阵 input 上使用 经转置的标准卷积核 kernel 执行 标准卷积运算,如图 6 所示:

这里我们定义stride=1的普通卷积运算为标准卷积运算

在这里插入图片描述

更一般地,对于卷积核尺寸 kernel size = k,步长 stride = s = 1,填充 padding = p = 0 的转置卷积,其 等价的标准卷积 在原尺寸为 i ′ i’ i 的输入矩阵上进行运算,输出特征图的尺寸 o ′ o’ o 为:

在这里插入图片描述

至于为什么等于上面的关系式,下面会解释,这里我们先复习一下普通卷积的输入与输出尺寸的关系
k e r n e l = k , s t r i d e = s , p a d d i n g = p kernel=k,stride=s,padding=p kernel=k,stride=s,padding=p , 输入尺寸为 i i i , 输出尺寸为 o o o , 则有
o = ⌊ i − k + 2 p s ⌋ + 1 o=\lfloor \frac{i-k+2p}{s} \rfloor+1 o=sik+2p+1
后面我们在利用这个公式的时候,一般忽略公式中的向下取整,因为等价成标准卷积时有stride=1,不存在不整除的情况

即 kernel size = k,步长 stride = s = 1,填充 padding = p = 0 的转置卷积(注意这里的k、s、p都是针对转置卷积的)等价于这样的标准卷积:输入矩阵 input 在卷积运算前,需先进行 p a d d i n g ′ = k − 1 padding’ = k-1 padding=k1 的填充,得到尺寸 i ′ ′ = i ′ + 2 ( k − 1 ) i” = i’ + 2(k-1) i=i+2(k1)

因此,转置卷积输出尺寸可以由标准卷积输入输出尺寸公式推算出来,根据标准卷积输入输出尺寸计算公式可得 (等价的标准卷积的步长 s ′ = 1 s’ = 1 s=1,因为padding已经在 i ′ ′ i” i内进行了,所以下面公式的 p = 0 p=0 p=0):

在这里插入图片描述

到这里我们已经可以知道公式是怎么来的了,这里再简单总结一下,根据矩阵 C T y ′ C^Ty’ CTy ,转置卷积可以等价为标准卷积。我们需要根据转置卷积的参数k、s、p等先对输入进行填充,然后将转置卷积核进行两次翻转,最后做stride=1的标准卷积。因此我们可以根据标准卷积输入输出尺寸的公式计算出转置卷积的输入输出尺寸关系公式。

5.2 stride > 1, padding=0

在实际中,我们大多数时候会使用 stride>1 的转置卷积,从而获得较大的上采样倍率。

如下,令输入尺寸为 5 × 5 5×5 5×5,标准卷积核同上 k e r n e l s i z e = k = 3 kernel size = k = 3 kernelsize=k=3,步长 s t r i d e = s = 2 stride = s = 2 stride=s=2,填充 p a d d i n g = p = 0 padding = p = 0 padding=p=0,标准卷积运算后,输出矩阵尺寸为 2 × 2 2×2 2×2

在这里插入图片描述

此处,转换后的稀疏矩阵尺寸变为 25×4,由于矩阵太大这里不展开进行罗列。最终转置卷积的结果为:

在这里插入图片描述

此时,等价于 输入矩阵同时添加了 空洞填充,再由转置的标准卷积核进行运算,过程如图 7 所示:

在这里插入图片描述

更一般地,对于卷积核尺寸 k e r n e l s i z e = k kernel size = k kernelsize=k,步长 s t r i d e = s > 1 stride = s > 1 stride=s>1,填充 p a d d i n g = p = 0 padding = p = 0 padding=p=0 的转置卷积,其 等价的标准卷积 在原尺寸为 i ′ i’ i 的输入矩阵上进行运算,输出特征图的尺寸 o ′ o’ o 为:

在这里插入图片描述

即卷积核尺寸 k e r n e l s i z e = k kernel size = k kernelsize=k,步长 s t r i d e = s > 1 stride = s > 1 stride=s>1,填充 p a d d i n g = p = 0 padding = p = 0 padding=p=0 的转置卷积等价于这样的标准卷积:输入矩阵 input 在卷积运算前,需先进行 p a d d i n g ′ = k − 1 padding’ = k-1 padding=k1 的填充;然后,相邻元素间的空洞数为 s − 1 s-1 s1,共有 i ′ − 1 i’ – 1 i1 组空洞需插入;从而,实际尺寸为 i ′ ′ = i ′ + 2 ( k − 1 ) + ( i ′ − 1 ) × ( s − 1 ) = s × ( i ′ − 1 ) + 2 k − 1 i” = i’ + 2(k-1) + (i’ -1) \times (s-1) = s \times (i’ – 1) + 2k – 1 i=i+2(k1)+(i1)×(s1)=s×(i1)+2k1

因此,根据标准卷积输入输出尺寸计算公式得 (等价的标准卷积的步长 s ′ = 1 s’ = 1 s=1,因为padding已经在 i ′ ′ i” i内进行了,所以下面公式的 p = 0 p=0 p=0):

在这里插入图片描述

可见,通过控制步长 s t r i d e = s stride = s stride=s 的大小可以控制上采样的倍率

5.3 stride=s, padding=p

我们来讨论更一般的情况,这里我直接给出结论。
k e r n e l s i z e = k kernel size = k kernelsize=k,步长 s t r i d e = s stride = s stride=s,填充 p a d d i n g = p padding = p padding=p 的转置卷积,等价于这样的标准卷积:输入矩阵 input 在卷积运算前,需先进行 p a d d i n g ′ = k − p − 1 padding’ = k-p-1 padding=kp1 的填充;然后,相邻元素间的空洞数为 s − 1 s-1 s1,共有 i ′ − 1 i’ – 1 i1 组空洞需插入;从而,实际尺寸为 i ′ ′ = i ′ + 2 ( k − p − 1 ) + ( i ′ − 1 ) × ( s − 1 ) = s × ( i ′ − 1 ) + 2 k − 1 − 2 p i” = i’ + 2(k-p-1) + (i’ -1) \times (s-1) = s \times (i’ – 1) + 2k – 1 -2p i=i+2(kp1)+(i1)×(s1)=s×(i1)+2k12p
因此,根据标准卷积输入输出尺寸计算公式得 (等价的标准卷积的步长 s ′ = 1 s’ = 1 s=1,因为padding已经在 i ′ ′ i” i内进行了,所以下面公式的 p = 0 p=0 p=0):
o ′ = i ′ ′ − k + 2 p s ′ + 1 = s ( i ′ − 1 ) + 2 k − 1 − k + 1 − 2 p = s ( i ′ − 1 ) + k − 2 p o’=\frac{i”-k+2p}{s’}+1=s(i’-1)+2k-1-k+1-2p=s(i’-1)+k-2p o=sik+2p+1=s(i1)+2k1k+12p=s(i1)+k2p
再回忆下标准卷积输入输出尺寸的公式:
o = ⌊ i − k + 2 p s ⌋ + 1 o=\lfloor \frac{i-k+2p}{s} \rfloor+1 o=sik+2p+1
不考虑向下取整,我们根据输出 o o o反过来计算输入 i i i
i = s ( o − 1 ) + k − 2 p i=s(o-1)+k-2p i=s(o1)+k2p
有没有发现,我们最后就得到了一般情况下的转置卷积输入输出尺寸关系公式。

6 小结

  • 我们可以用转置卷积来上采样,而 转置卷积的权值是可学习的,所以无需一个预定义的插值方法。

  • 尽管它被称为转置卷积,但这并不意味着我们取某个已有的卷积矩阵并使用转置后的版本

  • 可以用卷积来模拟转置卷积。通过在输入矩阵的值间插入零值 (以及周围填零) 上采样输入矩阵,然后进行常规卷积就会产生与转置卷积相同的效果。你可能会发现一些文章用这种方式解释了转置卷积。但是,由于需要在常规卷积前对输入进行上采样,所以效率较低。

  • 注意:矩阵中的实际权值不一定来自原始卷积矩阵。重要的是权重的排布是由卷积矩阵的转置得来的。

  • 注意:转置卷积会导致生成图像中出现 网格/棋盘效应 (checkerboard artifacts),因此后续也存在许多针对该问题的改进工作。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/151931.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 计算机 修改 虚拟ip,电脑虚拟ip地址怎么弄?「建议收藏」

    计算机 修改 虚拟ip,电脑虚拟ip地址怎么弄?「建议收藏」原标题:电脑虚拟ip地址怎么弄?在需要建立局域网和连接多台计算机时。我将重新设置电脑的IP地址,这样电脑就可以连上网了。因此,如何设置电脑的IP地址呢?以下是根据电脑原来的IP地址设置IP地址的共享方法。设置步骤:1、首先,右击桌面上的网络邻居,并在打开的菜单中选择该属性。2、在打开的“网络连接”属性菜单中找到本地连接,单击“本地连接”,然后点击“查看此连接状态”,即可打开本地连接。单击“支持”标…

    2022年10月12日
    3
  • 如何成为年薪50W的运维架构师?

    如何成为年薪50W的运维架构师?linux云计算工程师三大核心职能平台架构组建负责服务的搭建日常运营保障保证运维工作正常运转出现问题解决性能、效率优化运维工作效率的优化,devops运维自动化提升系统的性能90%服务器都是LinuxLinux免费(windows是付费的,我们用的都是盗版)Linux平台稳定Linux开源过程开发工程师(开发,bug修复,码农)—>…

    2022年7月17日
    17
  • qmap的书写格式linux,QMap 键值存储「建议收藏」

    qmap的书写格式linux,QMap 键值存储「建议收藏」Qt中的QMap介绍与使用,在坛子里逛了一圈,发现在使用QMap中,出现过很多的问题,Map是一个很有用的数据结构。它以“键-值”的形式保存数据。在使用的时候,通过提供字符标示(键)即可得到想要的数据。这个“数据”即可以是一个字符串,也可以是任意对象,当然也包括自己定义的类对象。说明:map是以值传递的形式保存数据的。1.基本应用下面以“键-值”都是QString的例子说明QMap的基本使用方法…

    2022年5月7日
    77
  • 数据库概念结构设计_数据库设计阶段分为

    数据库概念结构设计_数据库设计阶段分为概念结构设计:将需求分析得到的用户需求抽象为信息结构(即概念模型)的过程。一、概念模型在需求分析阶段所得到的应用需求应该首先抽象为信息世界的结构,然后才能更改、更准确地用某一数据库管理系统实现这些需求。概念模型的主要特点:1.能真实、充分地反映现实世界,包括事物和事物之间的联系,能满足用户对数据的处理要求,是现实世界的一个真是模型。2.易于理解,可以用它和不熟悉…

    2022年10月12日
    3
  • 电子设计教程12:Buck降压电路

    电子设计教程12:Buck降压电路  我们仍然使用MC34063芯片,来设计一个DC-DC降压电路,实现直流12V转5V。Buck变换器  Buck变换器是开关电源基本拓扑结构的一种,Buck变换器又称为降压变换器,是一种对输入电压进行降压变换的直流斩波器,其输出电压低于输入电压。  Buck变换器与Boost变换器使用的器件完全一样,只不过连接方式不太一样。Buck电路是正激类型,在开关管导通的时候,能量可以传递到输出端。…

    2022年6月20日
    40
  • mysql json decode_json_decode详解

    mysql json decode_json_decode详解最近在为WBlog开发一个QQ登录功能的程序,在开OAuth2.0开发包中常遇到json_decode函数,久了忘得也差不多了,于是今天重新整理一下json_decode函数.json_decode是php5.2.0之后新增的一个PHP内置函数,其作用是对JSON格式的字符串进行编码.json_decode的语法规则:json_decode(string$json[,bool$ass…

    2022年7月17日
    17

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号