深入浅出理解转置卷积Conv2DTranspose

温故而知新,可以为师矣!

一、参考资料

论文:A guide to convolution arithmetic for deep learning
github源码:Convolution arithmetic
bilibili视频:转置卷积(transposed convolution)
转置卷积(Transposed Convolution)
【keras/Tensorflow/pytorch】Conv2D和Conv2DTranspose详解
怎样通俗易懂地解释反卷积?
抽丝剥茧,带你理解转置卷积(反卷积)

二、标准卷积(Conv2D)

在这里插入图片描述

1. Conv2D 计算公式

标准卷积计算公式有:
o = i + 2 p − k s + 1 i = size of input o = size of output p = p a d d i n g k = size of kernel s = s t r i d e s o=\frac{i+2p-k}s+1 \quad \begin{array}{l} \\i=\textit{size of input}\\o=\textit{size of output}\\p=padding\\k=\textit{size of kernel}\\s=strides\end{array} o=si+2pk+1i=size of inputo=size of outputp=paddingk=size of kernels=strides

以特征图的高度Height为例,经过卷积操作之后,输出特征图计算公式为:
H o u t = H i n + 2 p − k s + 1 ( 1 ) H_{out}=\frac{H_{in}+2p-k}s+1\quad(1) Hout=sHin+2pk+1(1)

2. Conv2D中的步长stride

2.1 当步长stride=1,p=0,k=3

在这里插入图片描述

输入特征图(蓝色): ( H i n , W i n ) = ( 4 , 4 ) (H_{in},W_{in})=(4,4) (Hin,Win)=(4,4)
标准卷积核: k e r n e l _ s i z e ( k ) = 3 , s t r i d e ( s ) = 1 , p a d d i n g = 0 kernel\_size(k)=3,stride(s)=1,padding=0 kernel_size(k)=3,stride(s)=1padding=0
输出特征图(绿色): ( H o u t , W o u t ) = ( 2 , 2 ) (H_{out},W_{out})=(2,2) (Hout,Wout)=(2,2)

代入 公式 ( 1 ) 公式(1) 公式(1)中,可得:
H o u t = H i n + 2 p − K S + 1 H o u t = 4 + 2 ∗ 0 − 3 1 + 1 = 2 H_{out}=\frac{H_{in}+2p-K}S+1\\ H_{out}=\frac{4+2*0-3}1+1=2 Hout=SHin+2pK+1Hout=14+203+1=2

2.2 当步长stride=2,p=1,k=3

在这里插入图片描述

输入特征图(蓝色): ( H i n , W i n ) = ( 5 , 5 ) (H_{in},W_{in})=(5,5) (Hin,Win)=(5,5)
标准卷积核: k e r n e l _ s i z e ( k ) = 3 , s t r i d e ( s ) = 2 , p a d d i n g = 1 kernel\_size(k)=3,stride(s)=2,padding=1 kernel_size(k)=3,stride(s)=2padding=1
输出特征图(绿色): ( H o u t , W o u t ) = ( 3 , 3 ) (H_{out},W_{out})=(3,3) (Hout,Wout)=(3,3)

代入 公式 ( 1 ) 公式(1) 公式(1)中,可得:
H o u t = H i n + 2 p − k s + 1 H o u t = 5 + 2 ∗ 1 − 3 2 + 1 = 3 H_{out}=\frac{H_{in}+2p-k}s+1\\ H_{out}=\frac{5+2*1-3}2+1=3 Hout=sHin+2pk+1Hout=25+213+1=3

三、转置卷积(Conv2DTranspose)

1. 引言

对于很多生成模型(如语义分割、自动编码器(Autoencoder)、GAN中的生成器等模型),我们通常希望进行与标准卷积相反的转换,即执行上采样。对于语义分割,首先用编码器提取特征图,然后用解码器恢复原始图像大小,这样来分类原始图像的每个像素。

实现上采样的传统方法是应用插值方案或人工创建规则。而神经网络等现代架构则倾向于让网络自动学习合适的变换,无需人类干预。为了做到这一点,我们可以使用转置卷积。

2. 对转置卷积名称的误解

转置卷积又叫反卷积、逆卷积。然而,转置卷积是目前最为正规和主流的名称,因为这个名称更加贴切的描述了Conv2DTranspose 的计算过程,而其他的名字容易造成误导。在主流的深度学习框架中,如TensorFlow,Pytorch,Keras中的函数名都是 conv_transpose。所以,学习转置卷积之前,我们一定要弄清楚标准名称,遇到他人说反卷积、逆卷积也要帮其纠正,让不正确的命名尽早的淹没在历史的长河中。

我们先说一下为什么人们很喜欢将转置卷积称为反卷积或逆卷积。首先举一个例子,将一个4x4的输入通过3x3的卷积核在进行普通卷积(无padding, stride=1),将得到一个2x2的输出。而转置卷积将一个2x2的输入通过同样3x3大小的卷积核将得到一个4x4的输出,看起来似乎是普通卷积的逆过程。就好像是加法的逆过程是减法,乘法的逆过程是除法一样,人们自然而然的认为这两个操作似乎是一个可逆的过程。转置卷积不是卷积的逆运算(一般卷积操作是不可逆的),转置卷积也是卷积。转置卷积并不是正向卷积的完全逆过程(逆运算),它不能完全恢复输入矩阵的数据,只能恢复输入矩阵的大小(shape)。所以,转置卷积的名字就由此而来,而并不是“反卷积”或者是“逆卷积”,不好的名称容易给人以误解。

有些地方,转置卷积又被称作 fractionally-strided convolution或者deconvolution,但 deconvolution 具有误导性,不建议使用。因此,本文将会使用 Conv2DTransposefractionally-strided convolutions 两个名字,分别对应代码版学术论文版

3. Conv2DTranspose的概念

转置卷积(Transposed Convolution)语义分割或者==对抗神经网络(GAN)==中比较常见,其主要作用是做上采样(UpSampling)。
在这里插入图片描述

4. Conv2DConv2DTranspose对比

转置卷积和标准卷积有很大的区别,直接卷积是用一个“小窗户”去看一个“大世界”,而转置卷积是用一个“大窗户”的一部分去看“小世界”。

标准卷积(大图变小图)中,输入(5,5),步长(2,2),输出(3,3)。

在这里插入图片描述

转置卷积操作中(小图变大图),输入(3,3)输出(5,5)。
在这里插入图片描述

5. Conv2DTranspose计算过程

转置卷积核大小为k,步长s,填充p,则转置卷积的计算步骤可以总结为三步:

  1. 第一步:计算新的输入特征图;
  2. 第二步:计算转置卷积核;
  3. 第三步:执行标准卷积操作。

5.1 第一步:计算新的输入特征图

对输入特征图 M M M 进行 插值(interpolation) 零元素,得到新的输入特征图 M ′ M^{\prime} M

以特征图的高度Height为例,输入特征图的Height高为 H i n H_{in} Hin ,中间有 ( H i n − 1 ) (H_{in}-1) (Hin1) 个空隙。
两个相邻位置中间的插值零元素的个数: s − 1 s-1 s1 s s s 表示步长。
Height方向上总共插值零元素的个数: ( H i n − 1 ) ∗ ( s − 1 ) (H_{in}-1) * (s-1) (Hin1)(s1)
新的输入特征图大小 H i n ′ = H i n + ( H i n − 1 ) ∗ ( s − 1 ) H_{in}^{\prime} = H_{in} + (H_{in}-1)*(s-1) Hin=Hin+(Hin1)(s1)

5.2 第二步:计算转置卷积核

对标准卷积核 K K K进行上下、左右翻转,得到转置卷积核 K ′ K^{\prime} K

已知:
标准卷积核大小: k k k,
标准卷积核stride: s s s,
标准卷积核padding: p p p

  1. 转置卷积核大小: k ′ = k k^{\prime}=k k=k
  2. 转置卷积核stride: s ′ = 1 s^{\prime}=1 s=1该值永远为1
  3. 转置卷积核padding: p ′ = k − p − 1 p^{\prime} = k-p-1 p=kp1该公式是如何产生的,下文有解释。
    在这里插入图片描述

5.3 第三步:执行标准卷积操作

转置卷积核新的输入特征图进行标准卷积操作,得到的结果就是转置卷积的结果。

根据标准卷积的计算公式可知:
H o u t = ( H i n ′ + 2 p ′ − k ′ ) s ′ + 1 ( 2 ) \mathrm{H_{out}}=\frac{(\mathrm{H_{in}^{\prime}}+2\mathrm{p^{\prime}}-k^{\prime})}{\mathrm{s^{\prime}}}+1\quad(2) Hout=s(Hin+2pk)+1(2)

H ′ = H i n + ( H i n − 1 ) ∗ ( s − 1 ) H^{\prime} = H_{in} + (H_{in}-1)*(s-1) H=Hin+(Hin1)(s1)
k ′ = k k^{\prime}=k k=k,
s ′ = 1 s^{\prime}=1 s=1,
p ′ = k − p − 1 p^{\prime} = k-p-1 p=kp1

将第一、二步中变换的结果代入上式,可得:
H o u t = ( H i n + H i n ∗ s − H − s + 1 ) + 2 ∗ ( k − p − 1 ) − k s ′ + 1 ( 3 ) \text{H}_{out}=\frac{(\text{H}_{in}+\text{H}_{in}*s-\text{H}-\text{s}+1)+2*(\text{k}-\text{p}-1)-\text{k}}{\text{s}'}+1\quad(3) Hout=s(Hin+HinsHs+1)+2(kp1)k+1(3)
化简,可得:
H o u t = ( H i n − 1 )*s + k − 2 p − 1 s ′ + 1 ( 4 ) \text{H}_{out}=\frac{(\text{H}_{in}-1\text{)*s}+\text{k}-2\text{p}-1}{\text{s}'}+1\quad(4) Hout=s(Hin1)*s+k2p1+1(4)
上式中,分母步长 s ′ = 1 s^{\prime}=1 s=1,则最终结果为:
H o u t = ( H i n − 1 ) ∗ s − 2 p + k ( 5.1 ) \mathrm{H}_{out}=(\mathrm{H}_{in}-1)*\text{s}-2\text{p}+\mathrm{k}\quad(5.1) Hout=(Hin1)s2p+k(5.1)

综上所述,可以求得特征图Height和Width两个方向上进行转置卷积计算的结果:
H o u t = ( H i n − 1 ) × s t r i d e [ 0 ] − 2 × p a d d i n g [ 0 ] + k e r n e l _ s i z e [ 0 ] W o u t = ( W i n − 1 ) × s t r i d e [ 1 ] − 2 × p a d d i n g [ 1 ] + k e r n e l _ s i z e [ 1 ] H_{out}=(H_{in}−1)×stride[0]−2×padding[0]+kernel\_size[0]\\ W_{out}=(W_{in}−1)×stride[1]−2×padding[1]+kernel\_size[1] Hout=(Hin1)×stride[0]2×padding[0]+kernel_size[0]Wout=(Win1)×stride[1]2×padding[1]+kernel_size[1]

5.4 Conv2DTranspose示例

在这里插入图片描述

输入特征图 M M M H i n = 3 H_{in}=3 Hin=3
标准卷积核 K K K k = 3 , s = 2 , p = 1 k=3,s=2, p=1 k=3,s=2,p=1
新的输入特征图 M ′ M^{\prime} M H i n ′ = 3 + ( 3 − 1 ) ∗ ( 2 − 1 ) = 3 + 2 = 5 H_{in}^{\prime}=3+(3−1)∗(2−1)=3+2=5 Hin=3+(31)(21)=3+2=5。注意加上padding之后才是7。
转置卷积核 K ′ K^{\prime} K k ′ = k , s ′ = 1 , p ′ = 3 − 1 − 1 = 1 k^{\prime}=k,s^{\prime}=1,p^{\prime}=3−1−1=1 k=k,s=1,p=311=1
转置卷积计算的最终结果: H o u t = ( 3 − 1 ) ∗ 2 − 2 ∗ 1 + 3 = 5 \mathrm{H_{out}}=(3-1)*2-2*1+3=5 Hout=(31)221+3=5

在这里插入图片描述

6. 证明 p ′ = k − p − 1 p^{\prime}=k-p-1 p=kp1

变换 公式 ( 5.1 ) 公式(5.1) 公式(5.1) 可得:
H i n = H o u t + 2 p − k s + 1 ( 5.2 ) H_{in}=\frac{H_{out}+2p-k}s+1\quad(5.2) Hin=sHout+2pk+1(5.2)

公式 ( 5.2 ) 公式(5.2) 公式(5.2) 公式 ( 1 ) 公式(1) 公式(1)可以看出, Conv2DConv2DTranspose 在输入和输出大小互为逆(inverses)

Note: torch.nn.ConvTranspose2d
The padding argument effectively adds dilation * (kernel_size - 1) - padding amount of zero padding to both sizes of the input. This is set so that when a Conv2d and a ConvTranspose2d are initialized with same parameters, they are inverses of each other in regard to the input and output shapes.

参数padding有效地将 d i l a t i o n ∗ ( k e r n e l _ s i z e − 1 ) − p a d d i n g dilation * (kernel\_size - 1) - padding dilation(kernel_size1)padding 零填充的填充量添加到两种大小的输入中。这样设置是为了当Conv2d和ConvTranspose2d用相同的参数初始化时,它们输入和输出的形状大小互为逆
简单理解,参数padding的作用是,使得 Conv2dConvTranspose2d 输入输出的形状大小互为逆

第二步中 p ′ = k − p − 1 p^{\prime} = k-p-1 p=kp1 计算公式是如何产生的呢?其实就是根据“ Conv2dConvTranspose2d 输入输出的形状大小互为逆” 的条件推导(反推)得来的。可以简单证明:

已知条件
H ′ = H i n + ( H i n − 1 ) ∗ ( s − 1 ) H^{\prime} = H_{in} + (H_{in}-1)*(s-1) H=Hin+(Hin1)(s1)
k ′ = k k^{\prime}=k k=k,
s ′ = 1 s^{\prime}=1 s=1,
p ′ p^{\prime} p未知待求。

将已知条件代入 公式 ( 2 ) 公式(2) 公式(2) 中,可得:
H o u t = ( H i n + H i n ∗ s − H − s + 1 ) + 2 ∗ p ′ − k s ′ + 1 \text{H}_{out}=\frac{(\text{H}_{in}+\text{H}_{in}*s-\text{H}-\text{s}+1)+2*p^{\prime}-\text{k}}{\text{s}'}+1 Hout=s(Hin+HinsHs+1)+2pk+1
化简,可得:
H o u t = ( H i n − 1 ) ∗ s + 2 ∗ p ′ − k + 2 ( 6 ) \mathrm{H}_{out}=(\mathrm{H}_{in}-1)*\text{s}+2*p^{\prime}-\mathrm{k}+2\quad(6) Hout=(Hin1)s+2pk+2(6)
根据“ Conv2dConvTranspose2d 输入输出的形状大小互为逆”,可得:
H i n = ( H o u t − 1 ) ∗ s + 2 ∗ p ′ − k + 2 ( 7 ) \mathrm{H}_{in}=(\mathrm{H}_{out}-1)*\text{s}+2*p^{\prime}-\mathrm{k}+2\quad(7) Hin=(Hout1)s+2pk+2(7)
变换公式可得:
H o u t = ( H i n − 2 ∗ p ′ + k − 2 ) s + 1 ( 8 ) \mathrm{H_{out}}=\frac{(\mathrm{H_{in}}-2*\mathrm{p^{\prime}}+\mathrm{k}-2)}{\mathrm{s}}+1\quad(8) Hout=s(Hin2p+k2)+1(8)
公式 ( 8 ) 公式(8) 公式(8) 公式 ( 1 ) 公式(1) 公式(1) 可得:
2 p − k = − 2 ∗ p ′ + k − 2 2p-k=-2*p^{\prime}+k-2 2pk=2p+k2
解得:
p ′ = k − p − 1 ( 9 ) p^{\prime}=k-p-1\quad(9) p=kp1(9)

证闭。

7. Conv2DTranspose中的步长stride

下图展示了转置卷积中不同s和p的情况:

在这里插入图片描述在这里插入图片描述在这里插入图片描述
s=1, p=0, k=3s=2, p=0, k=3s=2, p=1, k=3

7.1 当步长stride=1,p=0,k=3

在这里插入图片描述

输入特征图(蓝色): ( H i n , W i n ) = ( 2 , 2 ) (H_{in},W_{in})=(2,2) (Hin,Win)=(2,2)
标准卷积核: k e r n e l _ s i z e ( k ) = 3 , s t r i d e ( s ) = 1 , p a d d i n g ( p ) = 0 kernel\_size(k)=3,stride(s)=1, padding(p)=0 kernel_size(k)=3,stride(s)=1,padding(p)=0
新的输入特征图: H i n ′ = 2 + ( 2 − 1 ) ∗ ( 1 − 1 ) = 2 H_{in}^{\prime} =2+(2-1)*(1-1)=2 Hin=2+(21)(11)=2。如图上图所示,插值变换后得到的新的输入特征图为(2,2)。
转置卷积核: k e r n e l _ s i z e ( k ′ ) = 3 , s t r i d e ( s ′ ) = 1 , p a d d i n g ( p ′ ) = 3 − 0 − 1 = 2 kernel\_size(k^{\prime})=3,stride(s^{\prime})=1, padding(p^{\prime})=3-0-1=2 kernel_size(k)=3,stride(s)=1,padding(p)=301=2。如图上图所示,填充padding为2。
输出特征图(绿色): ( H o u t , W o u t ) = ( 4 , 4 ) (H_{out},W_{out})=(4,4) (Hout,Wout)=(4,4)

代入 公式 ( 5 ) 公式(5) 公式(5)中,可得:
H o u t = ( H i n − 1 ) ∗ s − 2 p + k H o u t = ( 2 − 1 ) ∗ 1 − 2 ∗ 0 + 3 = 4 \mathrm{H}_{out}=(\mathrm{H}_{in}-1)*\text{s}-2\text{p}+\mathrm{k}\\ \mathrm{H}_{out}=(2-1)*1-2*0+3=4 Hout=(Hin1)s2p+kHout=(21)120+3=4

7.2 当步长stride=2,p=0,k=3

在这里插入图片描述

输入特征图(蓝色): ( H i n , W i n ) = ( 2 , 2 ) (H_{in},W_{in})=(2,2) (Hin,Win)=(2,2)
卷积核: k = 3 , s t r i d e ( s ) = 2 , p a d d i n g = 0 k=3,stride(s)=2, padding=0 k=3,stride(s)=2,padding=0
新的输入特征图: H i n ′ = 2 + ( 2 − 1 ) ∗ ( 2 − 1 ) = 3 H_{in}^{\prime} =2+(2-1)*(2-1)=3 Hin=2+(21)(21)=3。如图上图所示,插值变换后得到的新的输入特征图为(3,3)。
转置卷积核: k e r n e l _ s i z e ( k ′ ) = 3 , s t r i d e ( s ′ ) = 1 , p a d d i n g ( p ′ ) = 3 − 0 − 1 = 2 kernel\_size(k^{\prime})=3,stride(s^{\prime})=1, padding(p^{\prime})=3-0-1=2 kernel_size(k)=3,stride(s)=1,padding(p)=301=2。如图上图所示,填充padding为2。
输出特征图(绿色): ( H o u t , W o u t ) = ( 5 , 5 ) (H_{out},W_{out})=(5,5) (Hout,Wout)=(5,5)

代入 公式 ( 5 ) 公式(5) 公式(5)中,可得:
H o u t = ( H i n − 1 ) ∗ s − 2 ∗ p + k H o u t = ( 2 − 1 ) ∗ 2 − 2 ∗ 0 + 3 = 5 \mathrm{H}_{out}=(\mathrm{H}_{in}-1)*\text{s}-2*\text{p}+\mathrm{k}\\ \mathrm{H}_{out}=(2-1)*2-2*0+3=5 Hout=(Hin1)s2p+kHout=(21)220+3=5

7.3 当步长stride=2,p=1,k=3

在这里插入图片描述

输入特征图(蓝色): ( H i n , W i n ) = ( 3 , 3 ) (H_{in},W_{in})=(3,3) (Hin,Win)=(3,3)
卷积核: k = 3 , s t r i d e ( s ) = 2 , p a d d i n g = 1 k=3,stride(s)=2, padding=1 k=3,stride(s)=2,padding=1
新的输入特征图: H i n ′ = 3 + ( 3 − 1 ) ∗ ( 2 − 1 ) = 5 H_{in}^{\prime} =3+(3-1)*(2-1)=5 Hin=3+(31)(21)=5。如图上图所示,插值变换后得到的新的输入特征图为(5,5)。
转置卷积核: k e r n e l _ s i z e ( k ′ ) = 3 , s t r i d e ( s ′ ) = 1 , p a d d i n g ( p ′ ) = 3 − 1 − 1 = 1 kernel\_size(k^{\prime})=3,stride(s^{\prime})=1, padding(p^{\prime})=3-1-1=1 kernel_size(k)=3,stride(s)=1,padding(p)=311=1。如图上图所示,填充padding为1。
输出特征图(绿色): ( H o u t , W o u t ) = ( 5 , 5 ) (H_{out},W_{out})=(5,5) (Hout,Wout)=(5,5)

代入 公式 ( 5 ) 公式(5) 公式(5)中,可得:
H o u t = ( H i n − 1 ) ∗ s − 2 ∗ p + k H o u t = ( 3 − 1 ) ∗ 2 − 2 ∗ 1 + 3 = 5 \mathrm{H}_{out}=(\mathrm{H}_{in}-1)*\text{s}-2*\text{p}+\mathrm{k}\\ \mathrm{H}_{out}=(3-1)*2-2*1+3=5 Hout=(Hin1)s2p+kHout=(31)221+3=5

8. 棋盘效应(Checkerboard Artifacts)

棋盘效应(Checkerboard Artifacts)
卷积操作总结(三)—— 转置卷积棋盘效应产生原因及解决
Deconvolution and Checkerboard Artifacts

棋盘效应是由于转置卷积的“不均匀重叠”(Uneven overlap)的结果,使图像中某个部位的颜色比其他部位更深。
在这里插入图片描述

9. 总结

  1. Conv2D,特征图变换:

H o u t = H i n + 2 p − K S + 1 H_{out}=\frac{H_{in}+2p-K}S+1 Hout=SHin+2pK+1

  1. Conv2DTranspose,特征图变换:

H o u t = ( H i n − 1 ) ∗ S − 2 p + K \mathrm{H_out}=(\mathrm{H}_{in}-1)*\text{S}-2\text{p}+\mathrm{K} Hout=(Hin1)S2p+K

  1. Conv2DConv2DTranspose 在输入和输出形状方面互为倒数
  2. 标准卷积(大图变小图,(5,5)到(3,3)),转置卷积(小图变大图,(3,3)到(5,5))。
  3. 第二步新卷积核的步长stride永远为1
  4. Conv2DTranspose()函数参数中的步长stride是指第三步进行标准卷积操作时的stride。

四、相关经验

tf.layers.Conv2DTranspose

TensorFlow函数:tf.layers.Conv2DTranspose

以 tensorflow2 框架的Conv2DTranspose为例,介绍转置卷积函数。

layers.Conv2DTranspose(filters,kernel_size,strides=(1, 1),padding='valid',output_padding=None,data_format=None,dilation_rate=(1, 1),activation=None,use_bias=True,kernel_initializer='glorot_uniform',bias_initializer='zeros',kernel_regularizer=None,bias_regularizer=None,activity_regularizer=None,kernel_constraint=None,bias_constraint=None,**kwargs,
)
Docstring:     
Transposed convolution layer (sometimes called Deconvolution).

参数解释

  • filters:整数,输出空间的维数(即卷积中的滤波器数)。
  • kernel_size:一个元组或2个正整数的列表,指定过滤器的空间维度;可以是单个整数,以指定所有空间维度的相同值。
  • strides:一个元组或2个正整数的列表,指定卷积的步长;可以是单个整数,以指定所有空间维度的相同值。
  • padding:可以是一个"valid"或"same"(不区分大小写)。
  • data_format:一个字符串,可以是一个 channels_last(默认)、channels_first,表示输入中维度的顺序。channels_last 对应于具有形状(batch, height, width, channels)的输入,而 channels_first 对应于具有形状(batch, channels, height, width)的输入。
  • dilation_rate:。
  • activation:激活功能,将其设置为“None”以保持线性激活。
  • use_bias:Boolean,表示该层是否使用偏置。
  • kernel_initializer:卷积内核的初始化程序。
  • bias_initializer:偏置向量的初始化器,如果为None,将使用默认初始值设定项。
  • kernel_regularizer:卷积内核的可选正则化器。
  • bias_regularizer:偏置矢量的可选正则化器。
  • activity_regularizer:输出的可选正则化函数。
  • kernel_constraint:由Optimizer更新后应用于内核的可选投影函数(例如,用于实现层权重的范数约束或值约束);该函数必须将未投影的变量作为输入,并且必须返回投影变量(必须具有相同的形状);在进行异步分布式培训时,使用约束是不安全的。
  • bias_constraint:由Optimizer更新后应用于偏置的可选投影函数。
  • trainable:Boolean,如果为True,还将变量添加到图集合GraphKeys。TRAINABLE_VARIABLES中(请参阅参考资料 tf.Variable)。
  • name:字符串,图层的名称。

torch.nn.ConvTranspose2d

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)

参数解释

  • in_channels (int) – Number of channels in the input image
  • out_channels (int) – Number of channels produced by the convolution
  • kernel_size (int or tuple) – Size of the convolving kernel
  • stride (int or tuple, optional) – Stride of the convolution. Default: 1
  • padding (int or tuple, optional) – dilation * (kernel_size - 1) - padding zero-padding will be added to both sides of each dimension in the input. Default: 0
  • output_padding (int or tuple, optional) – Additional size added to one side of each dimension in the output shape. Default: 0. Note that output_padding is only used to find output shape, but does not actually add zero-padding to output. 在计算得到的输出特征图的高、宽方向各填充几行或列0(注意,这里只是在上下以及左右的一侧one side填充,并不是两侧都填充)
  • groups (int, optional) – Number of blocked connections from input channels to output channels. Default: 1. 当使用到组卷积时才会用到的参数,默认为1即普通卷积。
  • bias (bool, optional) – If True, adds a learnable bias to the output. Default: True
  • dilation (int or tuple, optional) – Spacing between kernel elements. Default: 1. 当使用到空洞卷积(膨胀卷积)时才会使用该参数,默认为1即普通卷积。

代码示例(TensorFlow)

#创建生成器
def make_generator_model():model = tf.keras.Sequential()#创建模型实例#第一层须指定维度 #batch无限制model.add(layers.Dense(7*7*BATCH_SIZE, use_bias=False, input_shape=(100,)))#Desne第一层可以理解为全连接层输入,它的秩必须小于2model.add(layers.BatchNormalization())model.add(layers.LeakyReLU())model.add(layers.Reshape((7,7,256)))assert model.output_shape == (None,7,7,256)#转化为7*7*128model.add(layers.Conv2DTranspose(128,(5,5),strides=(1,1),padding='same',use_bias=False))assert model.output_shape == (None,7,7,128)model.add(layers.BatchNormalization())model.add(layers.LeakyReLU())#转化为14*14*64model.add(layers.Conv2DTranspose(64,(5,5),strides=(2,2),padding='same',use_bias=False))assert model.output_shape == (None,14,14,64)model.add(layers.BatchNormalization())model.add(layers.LeakyReLU())#转化为28*28*1model.add(layers.Conv2DTranspose(1, (5, 5), strides=(2, 2), padding='same', use_bias=False,activation='tanh'))assert model.output_shape == (None, 28, 28, 1)          return model

代码示例(PyTorch)

下面使用Pytorch框架来模拟s=1, p=0, k=3的转置卷积操作:

在这里插入图片描述
在代码中transposed_conv_official函数是使用官方的转置卷积进行计算,transposed_conv_self函数是按照上面讲的步骤自己对输入特征图进行填充并通过卷积得到的结果。

import torch
import torch.nn as nndef transposed_conv_official():feature_map = torch.as_tensor([[1, 0],[2, 1]], dtype=torch.float32).reshape([1, 1, 2, 2])print(feature_map)trans_conv = nn.ConvTranspose2d(in_channels=1, out_channels=1,kernel_size=3, stride=1, bias=False)trans_conv.load_state_dict({"weight": torch.as_tensor([[1, 0, 1],[0, 1, 1],[1, 0, 0]], dtype=torch.float32).reshape([1, 1, 3, 3])})print(trans_conv.weight)output = trans_conv(feature_map)print(output)def transposed_conv_self():feature_map = torch.as_tensor([[0, 0, 0, 0, 0, 0],[0, 0, 0, 0, 0, 0],[0, 0, 1, 0, 0, 0],[0, 0, 2, 1, 0, 0],[0, 0, 0, 0, 0, 0],[0, 0, 0, 0, 0, 0]], dtype=torch.float32).reshape([1, 1, 6, 6])print(feature_map)conv = nn.Conv2d(in_channels=1, out_channels=1,kernel_size=3, stride=1, bias=False)conv.load_state_dict({"weight": torch.as_tensor([[0, 0, 1],[1, 1, 0],[1, 0, 1]], dtype=torch.float32).reshape([1, 1, 3, 3])})print(conv.weight)output = conv(feature_map)print(output)def main():transposed_conv_official()print("---------------")transposed_conv_self()if __name__ == '__main__':main()

输出结果

tensor([[[[1., 0.],[2., 1.]]]])
Parameter containing:
tensor([[[[1., 0., 1.],[0., 1., 1.],[1., 0., 0.]]]], requires_grad=True)
tensor([[[[1., 0., 1., 0.],[2., 2., 3., 1.],[1., 2., 3., 1.],[2., 1., 0., 0.]]]], grad_fn=<SlowConvTranspose2DBackward>)
---------------
tensor([[[[0., 0., 0., 0., 0., 0.],[0., 0., 0., 0., 0., 0.],[0., 0., 1., 0., 0., 0.],[0., 0., 2., 1., 0., 0.],[0., 0., 0., 0., 0., 0.],[0., 0., 0., 0., 0., 0.]]]])
Parameter containing:
tensor([[[[0., 0., 1.],[1., 1., 0.],[1., 0., 1.]]]], requires_grad=True)
tensor([[[[1., 0., 1., 0.],[2., 2., 3., 1.],[1., 2., 3., 1.],[2., 1., 0., 0.]]]], grad_fn=<ThnnConv2DBackward>)Process finished with exit code 0

DCGAN

论文:Unsupervised Representation Learning with Deep Convolutional Generative Adversarial Networks

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

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

相关文章

STM32入门教程-2023版【3-2】点亮LED灯之库函数介绍

关注 点赞 不错过精彩内容 大家好&#xff0c;我是硬核王同学&#xff0c;最近在做免费的嵌入式知识分享&#xff0c;帮助对嵌入式感兴趣的同学学习嵌入式、做项目、找工作! 二、正式点亮一个LED灯 操作STM32的GPIO需要三个步骤&#xff1a; 1.使用RCC打开GPIO的时钟&#…

基于策略模式和简单工厂模式实现zip、tar、rar、7z四种压缩文件格式的解压

推荐语 这篇技术文章深入探讨了基于策略模式和简单工厂模式实现四种常见压缩文件格式的解压方法。通过阅读该文章&#xff0c;你将了解到如何利用这两种设计模式来实现灵活、可扩展的解压功能&#xff0c;同时适应不同的压缩文件格式。如果你对设计模式和文件处理感兴趣或刚好…

算法题Python常用内置函数、方法、技巧汇总(其八:推导式)

文章目录 推导式列表推导式元组推导式集合推导式字典推导式 华为OD算法/大厂面试高频题算法练习冲刺训练 推导式 python中的推导式是一种独特的数据处理方式&#xff0c;可以从一个数据序列构建另一个新的数据序列。可以简单理解为for循环语句(if条件语句)的简写版本&#xff…

Springboot配置http-Only

项目框架 jdk1.8、springboot2.5.10 情况一 项目中未使用&#xff08;权限认证框架&#xff1a;Sa-Token&#xff09; application.yml文件内增加配置 server.servlet.session.cookie.http-onlytrueserver.servlet.session.cookie.securetrue (此条配置建议也加上) 情况二…

Flink去重计数统计用户数

1.数据 订单表&#xff0c;分别是店铺id、用户id和支付金额 "店铺id,用户id,支付金额", "shop-1,user-1,1", "shop-1,user-2,1", "shop-1,user-2,1", "shop-1,user-3,1", "shop-1,user-3,1", "shop-1,user…

课题学习(十八)----捷联测试电路设计与代码实现(基于MPU6050和QMC5883L)

一、 电路设计 本周主要工作是在项目上&#xff0c;抽空做了一个跟本课题相关的电路板&#xff0c;之前用开发板来做测试&#xff0c;MPU6050和QMC5883L都是用杜邦线连接的&#xff0c;导致接线很乱&#xff0c;也不美观&#xff0c;当然也不符合“捷联”的定义。   下面是电…

哈希表基础

设计意义&#xff1a; 查找性能快&#xff0c;比搜索二叉树更快 二叉树查找速度O(log2N),哈希表一般可以达到O(1) 构建方法&#xff1a; 数组下标&#xff0c;关键字x通过哈希函数f(x)转换为下标 哈希函数&#xff1a; 根据关键字设计&#xff0c;主要原理是根据数组大小…

【领域驱动设计】模式--通用语言(Ubiquitous language)

一.前言 有道无术术可求&#xff0c;有术无道止于术。方法论的形成都是为了让我们能够更高效&#xff0c;系统的解决问题&#xff0c;而不至于遇到问题不知所措。 二.通用语言的必要性 相信大家在实际的软件开发流程过程中&#xff0c;经常会遇到参照 Prd原型 编码出的系统与实…

SSM驾校预约管理系统----计算机毕业设计

项目介绍 本项目分为管理员、教练、学员三种角色&#xff0c; 管理员角色包含以下功能&#xff1a; 学员管理、教练管理、车辆管理、关系管理、车辆维修管理、个人中心等功能。 教练角色包含以下功能&#xff1a; 我的课程、我的学员、车辆中心、个人中心等功能。 学员角色包…

zabbix添加监控主机(agent)并告警

一、添加监控主机 总体来说&#xff0c;在被监控主机上安装部署zabbix-agent&#xff0c;并修改配置文件&#xff08;zabbix_agentd.conf&#xff09;的参数。然后在zabbix 服务端zabbix-get检查是否可以监控。如果可以了&#xff0c;就可以在web页面添加了&#xff0c;要监控…

Vue3.2 自定义指令详解与实战

一、介绍 在Vue3中&#xff0c;自定义指令为开发者提供了一种灵活的方式来扩展Vue的HTML模板语法&#xff0c;使其能够执行特定的DOM操作或组件逻辑。不同于Vue2.x中的全局和局部指令注册方式&#xff0c;Vue3引入了Composition API&#xff0c;这使得自定义指令的编写和使用更…

Ubuntu16.04 安装Anaconda

步骤 1&#xff1a; 去官网下载安装包,链接如下: https://repo.anaconda.com/archive/ 找到对应版本下载至本地电脑&#xff0c;并上传至服务器。 步骤2: 通过命令解压 sh Anaconda3-2023.03-0-Linux-x86_64.sh 一路选择yes或则回车&#xff0c;直到安装成功出现下面画面&…

Spring高手之路-@Autowired和@Resource注解异同点

目录 相同点 不同点 1.来源不同。 2.包含的属性不同 3.匹配方式&#xff08;装配顺序&#xff09;不同。 ​编辑 4.支持的注入对象类型不同 5.应用地方不同 相同点 都可以实现依赖注入&#xff0c;通过注解将需要的Bean自动注入到目标类中。都可以用于注入任意类型的Bean…

如何使用ChatGPT来提高编程效率

如何使用ChatGPT来提高编程效率 在软件开发的世界中,时间就是金钱。程序员常常在寻找新方法和工具来提高他们的编程效率。而现代技术中,人工智能(AI)已经成为了一个不可或缺的助手。特别是OpenAI的大型语言模型,即ChatGPT,它的出现为编程领域带来了翻天覆地的变化。本文…

Docker六 | Docker Compose容器编排

目录 Docker Compose 基本概念 使用步骤 常用命令 Docker Compose Docker-Compose是Docker官方的开源项目&#xff0c;负责实现对Docker容器集群的快速编排。Compose可以管理多个Docker容器组成一个应用。 需要定义一个YAML格式的配置文件docker-compose.yml&#xff0c;…

win安装scoop,并配置环境

安装 PowerShell 非管理员权限运行下面三条命令。 Set-ExecutionPolicy RemoteSigned -scope CurrentUseriwr -useb scoop.201704.xyz -outfile install.ps1.\install.ps1 -ScoopDir D:\Scoop -ScoopGlobalDir D:\Scoop\GlobalApps更新scoop scoop install gitscoop bucket …

[NOIP2006 提高组] 金明的预算方案

[NOIP2006 提高组] 金明的预算方案 题目描述 金明今天很开心&#xff0c;家里购置的新房就要领钥匙了&#xff0c;新房里有一间金明自己专用的很宽敞的房间。更让他高兴的是&#xff0c;妈妈昨天对他说&#xff1a;“你的房间需要购买哪些物品&#xff0c;怎么布置&#xff0…

vue如何实现局部刷新?

应用场景&#xff1a; 比如你要切换tap栏实现刷新下面form表单等&#xff0c;相当于刷新页面。 如何使用如下&#xff1a; <div v-if"isReloadData"> 比如你想刷新那个位置就把 v-if"isReloadData"写到那个标签上 </div> 在data中定义刷新标…

如何本地搭建FastDFS文件服务器并实现远程访问【内网穿透】

文章目录 前言1. 本地搭建FastDFS文件系统1.1 环境安装1.2 安装libfastcommon1.3 安装FastDFS1.4 配置Tracker1.5 配置Storage1.6 测试上传下载1.7 与Nginx整合1.8 安装Nginx1.9 配置Nginx 2. 局域网测试访问FastDFS3. 安装cpolar内网穿透4. 配置公网访问地址5. 固定公网地址5.…

User maven 通过什么命令能查到那个包依赖了slf4j-simple-1.7.36.jar

要在 Maven 项目中查找哪个包依赖了 slf4j-simple-1.7.36.jar&#xff0c;您可以使用 Maven 的依赖树命令 mvn dependency:tree。这个命令会展示项目所有依赖的层次结构&#xff0c;包括传递依赖&#xff08;即一个依赖的依赖&#xff09;。然后&#xff0c;您可以搜索或过滤输…