深度学习基础篇 第二章: 转置卷积

news2024/11/13 10:29:42

参考教程:
https://arxiv.org/pdf/1603.07285.pdf


文章目录

  • 什么是转置卷积
  • 转置卷积的思想
    • 一维形式的理解
    • 二维形式的理解
    • 卷积和转置的关系
      • no pading, unit strides
      • padding, unit strides
      • no padding, non-unit stride
      • padding,non-unit stride
  • pytorch中的转置卷积

什么是转置卷积

在上一章我们说过,卷积有三种模式:full,valid,same。在full模式下,输出的特征图会比输入的特征图要大;valid模式下,输出的特征图会比输入的特征图要小;same模式下,输出的特征图会和输入的特征图大小保持一致。

full情况是很少见的,它要求卷积核的大小 k k k比输入的特征图大,通过使用大小为 k − 1 k-1 k1的padding扩充输入特征图,从而使得卷积的输出特征图大小变大。

在通常情况下,我们使用的都是valid或者same模式的卷积,并且搭配上stride=1或者stride=2,这就使得在卷积网络中逐层深入时,我们的特征图大小要么不变,要么折半,倾向于往越来越小的方向变化。

这就使得在某些要求特征图逐层变大的任务中,传统卷积就不是那么适用了。比如说语义分割任务,输出是像素级别的分割结果;或者超分辨率任务,输出图像大小至少为输入的两倍。我们当然可以用padding的方式把特征图变大,但是实际使用中效果并不好。

  1. 先padding再卷积。这个其实就是转置卷积在做的事情。
  2. 先卷积再padding。毫无疑问这种补全的结果对我们的任务来说是没有用的。

在这种情况下,就需要转置卷积的帮助。

转置卷积也是一种卷积操作,它实现的是我们常用的卷积的“反方向”的运算,即把一个卷积操作的输出结果还原回输入的形状,通常卷积实现的是下采样操作,转置卷积则是一种上采样方法。要注意的是这里只考虑“形状”。

如下图,输入是一个大小为4x4的特征图,使用大小为3x3的kernel进行卷积,得到大小为2x2的输出。它的转置过程,是用大小2x2的特征图做输入,得到大小4x4的输出,从结果上看,它类似于使用一个3x3的kernel在padding=(2,2,2,2)的2x2特征图上做卷积。
在这里插入图片描述

转置卷积有时候又称为反卷积,但是它本质上和反卷积还是有不同的。一方面在数学含义上反卷积是可以还原输入的值的,而转置卷积只还原形状;另一方面在深度学习中我们使用的转置卷积中的参数都是可学习的,非固定的,它的输出结果也是面向任务需求的。

转置卷积的思想

卷积操作可以形式化为一个矩阵乘法运算。

一维形式的理解

如下图,假设输入向量 x = [ a , b , c , d , e , f , g ] T x=[a,b,c,d,e,f,g]^T x=[a,b,c,d,e,f,g]T,卷积核为 K = [ x , y , z ] K=[x,y,z] K=[x,y,z],卷积的滑动步长为2。
在这里插入图片描述
直观来看,大小为3x7的卷积矩阵A和大小为7x1的输入向量x相乘,得到大小为3x1的输出向量y。即
y = A x y = Ax y=Ax
转置卷积则是将上式中的输入输出互换:
x = A T y x = A^Ty x=ATy
即使用大小为7x3的转置卷积矩阵 A T A^T AT和大小为3x1的输出向量y相乘,得到大小为7x1的输入向量x。
这样的计算只还原了输入输出的大小,但是其中的数值已经发生了变化,所以只是在形状上保持一致。

二维形式的理解

参考了https://zhuanlan.zhihu.com/p/115070523?from_voters_page=true里的例子。

对于一个输入大小为3x3的输入和大小为2x2的卷积核。
X = [ x 11 x 12 x 13 x 21 x 22 x 23 x 31 x 32 x 33 ] W = [ w 11 w 12 w 21 w 22 ] \begin{align} &X = \begin{bmatrix}x_{11}&x_{12}&x_{13}\\ x_{21}&x_{22}&x_{23}\\ x_{31}&x_{32}&x_{33} \end{bmatrix}\\ & W = \begin{bmatrix}w_{11}&w_{12}\\ w_{21}&w_{22} \end{bmatrix} \end{align} X= x11x21x31x12x22x32x13x23x33 W=[w11w21w12w22]
我们用类似于一维形式的方法,也把卷积核表示成相应的稀疏矩阵C:
C = [ w 11 w 12 0 w 21 w 22 0 0 0 0 0 w 11 w 12 0 w 21 w 22 0 0 0 0 0 0 w 11 w 12 0 w 21 w 22 0 0 0 0 0 w 11 w 12 0 w 21 w 22 ] C = \begin{bmatrix}w_{11}&w_{12}&0&w_{21}&w_{22}&0&0&0&0\\ 0&w_{11}&w_{12}&0&w_{21}&w_{22}&0&0&0\\ 0&0&0&w_{11}&w_{12}&0&w_{21}&w_{22}&0\\ 0&0&0&0&w_{11}&w_{12}&0&w_{21}&w_{22} \end{bmatrix} C= w11000w12w11000w1200w210w110w22w21w12w110w220w1200w21000w22w21000w22
同时输入向量也进行展开变为:
x = [ x 11 x 12 x 13 x 21 x 22 x 23 x 31 x 32 x 33 ] x = \begin{bmatrix}x_{11}&x_{12}&x_{13}& x_{21}&x_{22}&x_{23}& x_{31}&x_{32}&x_{33}\end{bmatrix} x=[x11x12x13x21x22x23x31x32x33]
直观来看,大小为4x9的卷积矩阵C和大小为9x1的输入向量x相乘,得到大小为4x1的输出向量y。即
y = C x y = Cx y=Cx
转置卷积则是将上式中的输入输出互换:
x = C T y x = C^Ty x=CTy
即使用大小为9x4的转置卷积矩阵 C T C^T CT和大小为4x1的输出向量y相乘,得到大小为9x1的输入向量x。
这样的计算只还原了输入输出的大小,但是其中的数值已经发生了变化,所以只是在形状上保持一致。

卷积和转置的关系

去理解转置卷积在给定输入特征图 x x x 上的运算结果,我们可以去想象这个输入特征图本身是某个正向的卷积在某特定特征图上 x ′ x' x的结果,转置卷积就是为了复原这个特定特征图 x ′ x' x的形状。

重温一下特征图大小计算公式:
D o u t p u t = D i n p u t − D k e r n e l + 2 × P a d d i n g S t r i d e + 1 D_{output}=\frac{D_{input}-D_{kernel}+2\times Padding}{Stride}+1 Doutput=StrideDinputDkernel+2×Padding+1
先放一个别的地方偷来的计算总结,后面再详细计算:
在这里插入图片描述


no pading, unit strides

在这里插入图片描述
假如 x ′ x' x是4x4大小的特征图,我们的标准卷积操作是使用一个大小3x3的卷积核,padding=0,stride=1,得到的结果 x x x是一个大小为2x2的特征图。
现在我们的转置卷积要求将 x x x复原为 x ′ x' x,我们在通过调整padding来实现这样的结果。
仍然使用大小为3x3的卷积核,stride=1,那么按照公式:
4 = 2 − 3 + 2 × P a d d i n g 1 + 1 4 = \frac{2-3+2\times Padding}{1}+1 4=123+2×Padding+1
代入后可以得到padding = 2。
更general的,我们列一个公式来算padding。
D o u t p u t = D i n p u t − D k e r n e l + 2 × P a d d i n g S t r i d e + 1 D i n p u t = D o u t p u t − D k e r n e l + 2 × P a d d i n g ′ S t r i d e + 1 \begin{align} &D_{output}=\frac{D_{input}-D_{kernel}+2\times Padding}{Stride}+1\\ &D_{input} = \frac{D_{output}-D_{kernel}+2\times Padding'}{Stride}+1\\ \end{align} Doutput=StrideDinputDkernel+2×Padding+1Dinput=StrideDoutputDkernel+2×Padding+1
将式子4代入3中,在stride=1的情况下,可以得到
P a d d i n g + 1 − D k e r n e l + P a d d i n g ′ = 0 Padding + 1 - D_{kernel} + Padding' = 0 Padding+1Dkernel+Padding=0
在padding=0的情况下,可得到:
P a d d i n g ′ = D k e r n e l − 1 Padding' = D_{kernel}-1 Padding=Dkernel1
再将这个结果代入式子4,可以得到:
D i n p u t = D o u t p u t − D k e r n e l + 2 × ( D k e r n e l − 1 ) + 1 = D o u t p u t + D k e r n e l − 1 D_{input} = D_{output} - D_{kernel} + 2\times(D_{kernel}-1) +1 = D_{output} + D_{kernel} - 1 Dinput=DoutputDkernel+2×(Dkernel1)+1=Doutput+Dkernel1


padding, unit strides

在这里插入图片描述
类似于no padding的情况,使用和上一节类似的公式,可以得到:
P a d d i n g ′ = D k e r n e l − 1 − P a d d i n g Padding' = D_{kernel}-1-Padding Padding=Dkernel1Padding
同样代入式子4,可以得到:
D i n p u t = D o u t p u t − D k e r n e l + 2 × ( D k e r n e l − 1 − P a d d i n g ) + 1 = D o u t p u t + D k e r n e l − 1 − 2 × P a d d i n g \begin{align} D_{input} &= D_{output} - D_{kernel} + 2\times(D_{kernel}-1-Padding) +1 \\ &= D_{output} + D_{kernel} - 1 - 2\times Padding \end{align} Dinput=DoutputDkernel+2×(Dkernel1Padding)+1=Doutput+Dkernel12×Padding


no padding, non-unit stride

在这里插入图片描述
上图表示一个stride!=1的情况,假如 x ′ x' x是5x5大小的特征图,我们的标准卷积操作是使用一个大小3x3的卷积核,padding=0,stride=2,得到的结果 x x x是一个大小为2x2的特征图。
现在我们的转置卷积要求将 x x x复原为 x ′ x' x。需要再 x x x的元素之间进行填充,再进行卷积。
在这里插入图片描述
和之前的no padding的情况一样,我们的kernel大小仍使用3x3,padding使用前面两节得到的计算结果padding = k-1,那么我们来计算一下在填充后的图像上使用的新的stride是多少。

对于当前的问题, x ′ x' x大小为5x5, x x x大小为2x2,在 x x x的元素间填充stride-1 = 2-1 = 1个0,使它变成大小为3x3的 n e w _ x new\_x new_x。kernel大小为3x3,padding大小为2。

5 = 3 − 3 + 2 × 2 S t r i d e + 1 5 = \frac{3-3+2\times 2}{Stride}+1 5=Stride33+2×2+1
求得stride = 1。

更general的,我们列一个公式来算stride。
D o u t p u t = D i n p u t − D k e r n e l + 2 × P a d d i n g S t r i d e + 1 D o u t p u t ′ = D o u t p u t + ( S t r i d e − 1 ) ∗ ( D o u t p u t − 1 ) D i n p u t = D o u t p u t ′ − D k e r n e l + 2 × P a d d i n g ′ S t r i d e + 1 P a d d i n g ′ = D k e r n e l − 1 \begin{align} &D_{output}=\frac{D_{input}-D_{kernel}+2\times Padding}{Stride}+1\\ &D_{output'} = D_{output} + (Stride-1)*(D_{output}-1)\\ &D_{input} = \frac{D_{output'}-D_{kernel}+2\times Padding'}{Stride}+1\\ &Padding' = D_{kernel} -1 \end{align} Doutput=StrideDinputDkernel+2×Padding+1Doutput=Doutput+(Stride1)(Doutput1)Dinput=StrideDoutputDkernel+2×Padding+1Padding=Dkernel1
公式联立后可得到:
S t r i d e × D o u t p u t − S t r i d e + D k e r n e l − 1 = S t r i d e × ( S t r i d e × D o u t p u t − S t r i d e + D k e r n e l − 1 − 2 × P a d d i n g ) Stride\times D_{output} - Stride +D_{kernel}-1 = Stride\times(Stride\times D_{output} - Stride+D_{kernel}-1 - 2\times Padding ) Stride×DoutputStride+Dkernel1=Stride×(Stride×DoutputStride+Dkernel12×Padding)
在Padding=0的情况下,可得 S t r i d e = 1 Stride=1 Stride=1


padding,non-unit stride

在这里插入图片描述
在padding不等于0的情况下,使用之前得到的公式。
P a d d i n g ′ = D k e r n e l − 1 − P a d d i n g Padding' = D_{kernel}-1-Padding Padding=Dkernel1Padding
用这个式子和公式7、8、9联立,可以得到。
S t r i d e × D o u t p u t − S t r i d e + D k e r n e l − 1 − 2 × P a d d i n g = S t r i d e × ( S t r i d e × D o u t p u t − S t r i d e + D k e r n e l − 1 − 2 × P a d d i n g ) Stride\times D_{output} - Stride +D_{kernel}-1 -2\times Padding= Stride\times(Stride\times D_{output} - Stride+D_{kernel}-1 - 2\times Padding ) Stride×DoutputStride+Dkernel12×Padding=Stride×(Stride×DoutputStride+Dkernel12×Padding)
可得 S t r i d e = 1 Stride=1 Stride=1

pytorch中的转置卷积

根据上面的卷积和转置卷积的关系,我们来理一下它的具体实现。

转置卷积本质上就是对一个输入数据进行补零/上采样的普通卷积操作。
在有无padding,有无stride的多种情况下,kernel的大小是保持不变的。

  • 对于padding:
    1. 卷积中padding=0,转置卷积的padding’=k-1。
    2. 卷积中padding不为0,转置卷积的padding‘=k-padding-1。
      归纳为 padding’ = k-padding-1
  • 对于stride:
    1. 卷积中stride=1,转置卷积的stride=1,特征图不需要补0。
    2. 卷积中stride>1,转置卷积的stride=1,特征图元素间需要按stride-1的个数补0。
      归纳为,stride永远=1,但是特征图需要按stride-1进行补0。

对于一个大小为k,步长为s,padding为p的普通卷积,求它对应的转置卷积可以按如下步骤:

  1. 在特征图相邻数据间进行填充,在水平和垂直方向上元素间填充s-1个0。
  2. 在特征图边界进行填充,在四个边界分为进行大小为填充k-p-1的填充。
  3. 在得到的特征图上进行大小为k,步长为1的普通卷积操作。

看一下pytorch中的转置卷积的实现。

https://pytorch.org/docs/stable/generated/torch.nn.ConvTranspose2d.html#torch.nn.ConvTranspose2d

CLASS torch.nn.ConvTranspose2d(in_channels, out_channels, kernel_size, stride=1, padding=0, output_padding=0, groups=1, bias=True, dilation=1, padding_mode='zeros', device=None, dtype=None)

转置卷积和普通的卷积都继承了pytorch中的类_ConvNd,它们的初始化也没有什么区别,传参的参数名也大同小异。

我们在看介绍的时候可以看到,输入和输出的shape之间的关系是这样的。
在这里插入图片描述

从这个图可以看出来,实际上的操作是,output在使用当前卷积核运算处理后,得到input。这里的padding和stride都是针对output->input这一过程的。
但是在实际中我们做的是input->output这个过程,所以我们用的padding和stride都和给定的参数并不一致。

可以理解成,我们模拟了一个预想的输出使用卷积变成现在的输入的过程,然后用这个卷积的配置作为我们转置卷积的输入参数,基于此设计一个转置卷积。

使用了一个别人给的例子:
在这里插入图片描述
在这个例子中,我们的输入特征图大小是2x2,传入转置卷积的参数中,kernel_size=3,stride=1,padding=0。输出的特征图大小是4x4。

也就是我们用4x4的特征图做输入,使用kernel_size=3, stride=1, padding=0的卷积核,可以得到大小为2x2的输出特征图。

按照之前章节的公式理解,我们的转置卷积实际上做的操作是:

  1. 给2x2特征图的元素间填充stride-1 = 1-1 = 0个0。得到2x2大小的特征图。
  2. 给2x2的特征图进行大小为kernel_size-p-1 = 3-0-1-2的padding。得到大小为6x6的特征图。
  3. 在6x6的特征图上使用大小为3x3的卷积核,进行步长=1的卷积运算,得到大小为4x4的输出。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/960056.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ububtu部署bind-dns 问题

启动(重启)命令如下: sudo systemctl restart bind9查看状态命令如下: sudo systemctl status bind9停止命令如下: sudo systemctl stop bind9#配置自己的域 要修改一下路径的文件(named.conf.local): 在这个文件named.conf.loca…

java从入门到起飞(六)——用Socket实现网络通信

文章目录 背景网络编程网络编程三要素 2.DatagramSocket之UDP通信程序2.1 UDP发送数据2.2UDP接收数据2.3 3. Socket之TCP通信程序3.1TCP发送数据3.2TCP接收数据 背景 网络编程 ● 计算机网络 是指将地理位置不同的具有独立功能的多台计算机及其外部设备,通过通信线…

开始MySQL之路——MySQL 函数(详细讲解)

MySQL 函数 在MySQL中,为了提高代码重用性和隐藏实现细节,MySQL提高了很多函数。函数可以理解为别人封装好的模块代码。 在MySQL中,函数非常多,主要可以分为以下大类: 聚合函数:这类函数就是用来做简单的…

[深度学习]1. 深度学习知识点汇总

本文记录了我在学习深度学习的过程中遇到过的不懂的知识点,为了方便翻阅,故将其发表于此,随时更新,供大家参考。 深度学习常见知识点 1. 测试精度和训练精度 在深度学习中,测试精度和训练精度是两个重要的指标&#…

408考研-数据结构算法-双链表

双向链表的存储方式 双向链表跟链表差不多,只是它每个结点都含有两个链——一个指向下一结点,另一个指向前一结点。此外,它还能直接访问第一个和最后一个结点。 单链表只能向后操作,不可以向前操作。为了向前、向后操作方便&…

表白墙程序

目录 一、页面代码部分 二、设计程序 二、实现 doPost​编辑 三、实现 doGet 四、前端代码部分 五、使用数据库存储数据 一、页面代码部分 在之前的一篇博客中&#xff0c;已经写过了表白墙的页面代码实现&#xff0c;这里就不再重复了 页面代码如下&#xff1a; <!…

【Vue2】 axios库

网络请求库-axios库 认识Axios库为什么选择Axios库安装Axios axios发送请求常见的配置选项简单请求可以给Axios设置公共的基础配置发送多个请求 axios创建实例为什么要创建axios的实例 axios的拦截器请求拦截器响应拦截器 axios请求封装 认识Axios库 为什么选择Axios库 在游览…

git学习笔记 | 版本管理 - 分支管理

文章目录 git学习笔记Git是什么仓库常见的命令commit 备注规范在文件下设置git忽略文件 .gitignore 版本管理git log | git reflog 查看提交日志/历史版本版本穿梭 git resetgit reset HEAD <file> git checkout -- fileName 丢弃工作区的修改git revertGit恢复之前版本的…

海格里斯HEGERLS高密度料箱式四向穿梭车存储系统有哪些显著优势?

近些年仓储货架向着自动化、智能化发展&#xff0c;因此市面上出现很多不同类型的智能自动化仓储货架。其中&#xff0c;最受企业青睐的便是四向穿梭车货架。四向穿梭车货架根据其载重不同可分为托盘式和料箱式两大类。这两种不同类型的四向穿梭车货架在结构形式和控制方式上基…

Ubuntu20.04下安装google输入法

Ubuntu20.04下安装google输入法 1、添加中文语言支持 打开 系统设置——区域和语言——管理已安装的语言——在“语言”tab下——点击“添加或删除语言” 弹出“已安装语言”窗口&#xff0c;勾选中文&#xff08;简体&#xff09;&#xff0c;点击应用 回到“语言支持”窗…

日本橙皮书数据库—《医疗用医药品质量情报集》

日本橙皮书是一份关于医疗用医药品质量情报的汇总报告&#xff0c;由日本厚生劳动省发布。它主要涵盖了药品的品质再评价信息&#xff0c;特别是针对特定历史阶段的产品&#xff0c;笔者总结信息如下&#xff1a; ①日本橙皮书数据库包含了一系列药品的详细信息&#xff0c;如…

一句话画出动漫效果

链接&#xff1a; AI Comic Factory - a Hugging Face Space by jbilcke-hfDiscover amazing ML apps made by the communityhttps://huggingface.co/spaces/jbilcke-hf/ai-comic-factory 选择类型&#xff1a; Japanese 输入提示词&#xff1a; beauty and school love st…

视频云存储/安防监控/视频AI智能分析网关V3:消防器材缺失检测功能详解

在我们的日常生活中&#xff0c;消防器材是必不可少的&#xff0c;无论是在学校、园区还是工厂里&#xff0c;都需要摆放消防器材&#xff0c;做好防范措施&#xff0c;降低安全隐患。但有时也需防备消防器材被人为挪动甚至破坏&#xff0c;在危急时刻无法发挥作用。TSINGSEE青…

【kubernetes】Argo Rollouts -- k8s下的自动化蓝绿部署

蓝绿(Blue-Green)部署简介 在现代软件开发和交付中,确保应用程序的平稳更新和发布对于用户体验和业务连续性至关重要。蓝绿部署是一种备受推崇的部署策略,它允许开发团队在不影响用户的情况下,将新版本的应用程序引入生产环境。 蓝绿部署的核心思想在于维护两个独立的环…

lv3 嵌入式开发-1linux介绍及环境配置

目录 1 UNIX、Linux和GNU简介 2 环境介绍 3 VMwareTools配置 4 vim配置&#xff1a; 1 UNIX、Linux和GNU简介 什么是UNIX? unix是一个强大的多用户、多任务操作系统&#xff0c;支持多种处理器架构 中文名 尤尼斯 外文名 UNIX 本质 操作系统 类型 分时操作系统 开…

数据结构入门 — 栈

本文属于数据结构专栏文章&#xff0c;适合数据结构入门者学习&#xff0c;涵盖数据结构基础的知识和内容体系&#xff0c;文章在介绍数据结构时会配合上动图演示&#xff0c;方便初学者在学习数据结构时理解和学习&#xff0c;了解数据结构系列专栏点击下方链接。 博客主页&am…

一百七十、Linux——Crontab定时任务调度Kettle脚本

一、目的 由于用海豚调度器调度从Kafka到HDFS的kettle任务时发现有点问题&#xff0c;如果不设置定时调度&#xff0c;这个kettle任务会一直跑&#xff0c;而如果设置定时调度&#xff0c;隔天后就会生成多个任务&#xff0c;而且每个任务都在跑&#xff0c;不会停下&#xff…

stable diffusion实践操作-提示词

本文专门开一节写提示词相关的内容&#xff0c;在看之前&#xff0c;可以同步关注&#xff1a; stable diffusion实践操作 正文 提示词是SD中非常重要&#xff0c;你生成的图片质量&#xff0c;基本就取决于提示词的好坏&#xff0c;提示词分为正向提示词和反向提示词。 模板…

激光切割机自动调焦技术详解加图解

激光切割机在切割不同材料的过程中&#xff0c;激光束的焦点必须根据要求位于材料的不同位置。 因此&#xff0c;在切割不同材料的物料时&#xff0c;需要调整激光切割机的焦点位置。在以前的生产激光切割机中&#xff0c;普遍采用手动调焦的方法进行调焦。现在&#xff0c;许多…