PyTorch中的反卷积 (Transposed Convolution)

目录

  • PyTorch中的反卷积(Transposed Convolution)
      • Output计算公式
      • 反卷积的stride
      • 反卷积的dilation
      • 反卷积的padding

PyTorch中的反卷积(Transposed Convolution)

反卷积是计算机视觉领域中的一种上采样的方法,除了反卷积以外,还可以采用unpooling和bilinear interpolation方法做上采样。反卷积并不是卷积操作的逆过程。通过反卷积,只能恢复原矩阵的大小,但并不能完全恢复原矩阵的数值

Output计算公式

在pytorch中,反卷积的函数为ConvTranspose. 因为最近需要用到一维的反卷积,所以下面以一维的反卷积操作为例。计算反卷积output shape的公式如下:
I n p u t : ( N , C i n , L i n ) O u t p u t : ( N , C o u t , L o u t ) L o u t = ( L i n − 1 ) × s t r i d e − 2 × p a d d i n g + d i l a t i o n × ( k e r n e l _ s i z e − 1 ) + o u t p u t _ p a d d i n g + 1 Input: (N, C_{in}, L_{in}) \\ Output:(N, C_{out}, L_{out}) \\ L_{out} =(L_{in}−1)×stride−2×padding+dilation×(kernel\_size−1)+output\_padding+1 Input:(N,Cin,Lin)Output:(N,Cout,Lout)Lout=(Lin1)×stride2×padding+dilation×(kernel_size1)+output_padding+1

  • N: batch number
  • C: Channel
  • L: 一维数据的维度

下面这段代码的kernel是[1, 2, 3]

input = torch.ones(1, 1, 4) # input [[[1, 1, 1, 1]]]
t_conv = nn.ConvTranspose1d(
	in_channels=1, 
	out_channels=1, 
	stride=1, 
	kernel_size=3, 
	padding=0, 
	output_padding=0,
	dilation=1, 
	padding_mode="zeros", 
	bias=False
)
t_conv.weight.data = torch.tensor(data=[[[1, 2, 3]]], dtype=torch.float)
print(t_conv(input)) # output [[[1, 3, 6, 6, 5, 3]]]

in_channels,out_channels,output_padding, kernel_size相对好理解。ConvTranspose1d目前只支持“zeros”这一种padding模式。

反卷积的stride

首先来看一下stride, 反卷积中的stride与卷积操中的stride是类似的,可以简单理解为kernel滑动的步长,可以先看一下snippet code:

input = torch.ones(1, 1, 4) # input [[[1, 1, 1, 1]]]
t_conv = nn.ConvTranspose1d(
	in_channels=1, 
	out_channels=1, 
	stride=2, 
	kernel_size=3, 
	padding=0, 
	output_padding=0,
	dilation=1, 
	padding_mode="zeros", 
	bias=False
)
t_conv.weight.data = torch.tensor(data=[[[1, 2, 3]]], dtype=torch.float)
print(t_conv(input)) # output [[[1., 2., 4., 2., 4., 2., 4., 2., 3.]]]

当stride设置为2时,根据公式 o = s × ( i − 1 ) + d × ( k − 1 ) + 1 o = s \times (i - 1) + d \times (k - 1) + 1 o=s×(i1)+d×(k1)+1我们可以计算出此时的output维度是9,那么这个结果是怎么得到的呢。请看下图:
PyTorch中的反卷积 (Transposed Convolution)_第1张图片
通过图片就可以很清楚的看到,stride变为2时,kernel滑动的步长增加了一位。

反卷积的dilation

反卷积的dilation也和卷积操作中的dilation类似,指出了kernel间隔的距离。我们还是先看一下snippet code:

input = torch.ones(1, 1, 4) # input [[[1, 1, 1, 1]]]
t_conv = nn.ConvTranspose1d(
	in_channels=1, 
	out_channels=1, 
	stride=1, 
	kernel_size=3, 
	padding=0, 
	output_padding=0,
	dilation=2, 
	padding_mode="zeros", 
	bias=False
)
t_conv.weight.data = torch.tensor(data=[[[1, 2, 3]]], dtype=torch.float)
print(t_conv(input)) # output[[[1., 1., 3., 3., 5., 5., 3., 3.]]]

然后再根据图解就能很好的理解这个结果是怎么得到的了:
PyTorch中的反卷积 (Transposed Convolution)_第2张图片

反卷积的padding

padding和卷积操作的padding就有些不同了,反卷积的padding加在input上,但在结果中却要将padding去掉,我们直接看一下python运行的结果:

input = torch.ones(1, 1, 4) # input [[[1, 1, 1, 1]]]
t_conv = nn.ConvTranspose1d(
	in_channels=1, 
	out_channels=1, 
	stride=1, 
	kernel_size=3, 
	padding=1, 
	output_padding=0,
	dilation=1, 
	padding_mode="zeros", 
	bias=False
)
t_conv.weight.data = torch.tensor(data=[[[1, 2, 3]]], dtype=torch.float)
print(t_conv(input)) # output[[[3., 6., 6., 5.]]]

与第一段代码的结果相比,我们可以发现加了padding以后,我们的结果的维度反而减少了,这和公式是一致的,其实就是在结果的两端,减去padding所取值的维度。当然padding值如果过大,结果的维度不再大于0时,pytorch会报错。

而output_padding必须要小于stride或dilation其中之一,output_padding只会在output的后端添加padding去掉的值,如果没有padding,则会添加0。所以output_padding,并不会对称的添加数值。

最后做个总结的话,可以发现tranposed convolution实现上采样的方式是比较灵活的,不同参数的组合可能会得到相同大小的matrix,不知道有没有最佳的选择方式。

你可能感兴趣的:(pytorch,深度学习,神经网络,机器学习)