pytorch中的上采样(上采样,转置卷积,上池化,PixelShuffle)

Upsample(上采样,插值)

Upsample

torch.nn.Upsample(size=Nonescale_factor=Nonemode='nearest'align_corners=None)

 Upsamples a given multi-channel 1D (temporal), 2D (spatial) or 3D (volumetric) data.

对给定的多通道1D(时间)、2D(空间)或3D(容量)数据进行上采样。

The input data is assumed to be of the form minibatch x channels x [optional depth] x [optional height] x width. Hence, for spatial inputs, we expect a 4D Tensor and for volumetric inputs, we expect a 5D Tensor.

输入格式:

一维数据 [N, C, W]

二维数据 [N, C, H, W]

三维数据 [N, C, D,  H, W]

The algorithms available for upsampling are nearest neighbor and linear, bilinear, bicubic and trilinear for 3D, 4D and 5D input Tensor, respectively.

Upsample可用的算法是最近邻和线性,双线性,双三次和三线性插值算法。

One can either give a scale_factor or the target output size to calculate the output size. (You cannot give both, as it is ambiguous)

可以给出scale_factor或目标输出大小来计算输出大小(不能同时给出两者)。 

参数说明:

size: (int or Tuple[int] or Tuple[intint] or Tuple[intintint]optional) – output spatial sizes

scale_factor :(float or Tuple[float] or Tuple[floatfloat] or Tuple[floatfloatfloat],optional) – multiplier for spatial size. Has to match input size if it is a tuple.

输出尺寸可以指定size,也可以通过缩放的倍数指定。

mode: (stroptional) – the upsampling algorithm: one of 'nearest''linear''bilinear''bicubic' and 'trilinear'. Default: 'nearest'

align_corners (booloptional) – if True, the corner pixels of the input and output tensors are aligned, and thus preserving the values at those pixels. This only has effect when mode is 'linear''bilinear', or 'trilinear'. Default: False

输入输出形状:

 注意:

在align_corners = True的情况下,线性插值模式(线性,双线性,双三次和三线性)不会按比例对齐输出像素和输入像素,因此输出值可能取决于输入大小。 这是这些模式(0.3.1版之前)的默认行为。 从那时起,默认行为是align_corners = False。 有关如何影响输出的具体示例,请参见下文。

关于align_corners的解释参考知乎这篇文章

输入为:

  对它上采样两倍后,得到下图:

  首先介绍 align_corners=False,它是 pytorch 中 interpolate 的默认选项。这种设定下,我们认定像素值位于像素块的中心。首先观察绿色框内的像素,我们会发现它们严格遵守了 bilinear 的定义。而对于角上的四个点,其像素值保持了原图的值。边上的点则根据角点的值,进行了 bilinear 插值。所以,我们从全局来看,内部和边缘处采用了比较不同的规则。

 在 align_corners=True世界观里,像素值位于网格上,如上图所示:

 

  这里仔细的读者会发现,3*3 的图像上采两倍后,变成了 5*5。更广泛地来讲,对于输入尺寸是 (2x+1) * (2x+1) 的图片,其经过 align_corners=True 的上采样后,尺寸变为 (4x+1) * (4x+1)。所以虽然内容上整齐了,外在的数目上,却没了那种 2 的整数次幂的美感。(注:这里指定了输出为5x5)

具体区别呢?
查找pytorch论坛得图:

  • 当**align_corners = True**时,像素被视为网格的格子上的点,拐角处的像素对齐.可知是点之间是等间距的
  • 当**align_corners = False**时, 像素被视为网格的交叉线上的点, 拐角处的点依然是原图像的拐角像素,但是插值的点间却按照上图的取法取,导致点与点之间是不等距的

如果要下采样/常规调整大小,则应使用interpolate()。

UpsamplingNearest2d

torch.nn.UpsamplingNearest2d(size=Nonescale_factor=None)

UpsamplingBilinear2d

torch.nn.UpsamplingBilinear2d(size=Nonescale_factor=None)

ConvTranspose(转置卷积)

torch.nn.ConvTranspose1d

torch.nn.ConvTranspose1d(in_channelsout_channelskernel_sizestride=1padding=0output_padding=0groups=1bias=Truedilation=1padding_mode='zeros')

对由多个输入平面组成的输入图像应用1D转置卷积算子。

这个模块可以看作是相对于其输入的Conv1d的梯度。它也被称为分数步卷积或反卷积、去卷积(尽管它不是一个实际的数学上的反卷积操作)。

Parameters:

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 tupleoptional) – Stride of the convolution. Default: 1 控制交叉相关的步幅。

padding (int or tupleoptional) – dilation (kernel_size 1) padding zero-padding will be added to both sides of the input. Default: 0 控制两侧的隐式零填充量dilation (kernel_size 1) padding。 有关详细信息,请参见下面的注释。

output_padding (int or tupleoptional) – Additional size added to one side of the output shape. Default: 0 控制添加到输出形状一侧的附加大小。详情请参阅下面的说明。

groups (intoptional) – Number of blocked connections from input channels to output channels. Default: 1 控制输入和输出之间的连接。 in_channels和out_channels必须都可以被groups整除。

bias (booloptional) – If True, adds a learnable bias to the output. Default: True

dilation (int or tupleoptional) – Spacing between kernel elements. Default: 1 controls the spacing between the kernel points; also known as the à trous algorithm. It is harder to describe, but this link has a nice visualization of what dilation does. 控制卷积核核点之间的间隔,也被称为à trous算法。这很难描述,但是这个链接很好地展示了膨胀的作用。

注意: 

Depending of the size of your kernel, several (of the last) columns of the input might be lost, because it is a valid cross-correlation, and not a full cross-correlation. It is up to the user to add proper padding.

根据卷积核的大小,输入的(最后一列)几列可能会丢失,因为它是有效的互相关,而不是完整的互相关。 用户可以自行添加适当的填充。

The padding argument effectively adds dilation * (kernel_size - 1) - padding amount of zero padding to both sides of the input. This is set so that when a Conv1d and a ConvTranspose1d are initialized with same parameters, they are inverses of each other in regard to the input and output shapes. However, when stride > 1, Conv1d maps multiple input shapes to the same output shape. output_padding is provided to resolve this ambiguity by effectively increasing the calculated output shape on one side. Note that output_padding is only used to find output shape, but does not actually add zero-padding to output.

padding参数有效地将diation *(kernel_size-1)-padding个零填充的填充量添加到输入的两侧。 进行设置是为了使Conv1d和ConvTranspose1d用相同的参数初始化时,它们在输入和输出形状方面彼此相反。 但是,当stride> 1时,Conv1d会将多个输入形状映射到相同的输出形状。 提供output_padding可以通过有效地增加一侧的计算输出形状来解决这种歧义。 请注意,output_padding仅用于查找输出形状,但实际上并未向输出添加零填充。

In some circumstances when using the CUDA backend with CuDNN, this operator may select a nondeterministic algorithm to increase performance. If this is undesirable, you can try to make the operation deterministic (potentially at a performance cost) by setting torch.backends.cudnn.deterministic True. Please see the notes on Reproducibility for background.

在某些情况下,将CUDA后端与CuDNN一起使用时,该运算符可能会选择不确定的算法来提高性能。 如果不希望这样做,则可以通过将torch.backends.cudnn.deterministic = True设置为确定性操作(可能以性能为代价)。 请参阅有关可重现性的说明作为背景。

输入输出形状:

Input: (N, Cin, Lin)

Output: (N,Cout,Lout) where

Lout=(Lin−1)×stride−2×padding+dilation×(kernel_size−1)+output_padding+1

Variables

ConvTranspose1d.weight (Tensor)

ConvTranspose1d.bias (Tensor)

torch.nn.ConvTranspose2d

torch.nn.ConvTranspose2d(in_channelsout_channelskernel_sizestride=1padding=0output_padding=0groups=1bias=Truedilation=1padding_mode='zeros')

The parameters kernel_sizestridepaddingoutput_padding can either be:

  • a single int – in which case the same value is used for the height and width dimensions 高宽两个方向参数相同

  • tuple of two ints – in which case, the first int is used for the height dimension, and the second int for the width dimension分别为高宽两个方向指定参数

Shape:

  • Input: (N,Cin​,Hin​,Win​)
  • Output: (N,Cout​,Hout​,Wout​) where

Hout=(Hin​−1)×stride[0]−2×padding[0]+dilation[0]×(kernel_size[0]−1)+output_padding[0]+1

Hout=(Hin​−1)×stride[0]−2×padding[0]+dilation[0]×(kernel_size[0]−1)+output_padding[0]+1

torch.nn.ConvTranspose3d

torch.nn.ConvTranspose3d(in_channelsout_channelskernel_sizestride=1padding=0output_padding=0groups=1bias=Truedilation=1padding_mode='zeros')

ConvTranspose2d原理,深度网络如何进行上采样?

 

unpooling(上池化)

另一种上采样的方法是,参考代码:segnet_pytorch

        # Stage 5
        x51 = F.relu(self.bn51(self.conv51(x4p)))
        x52 = F.relu(self.bn52(self.conv52(x51)))
        x53 = F.relu(self.bn53(self.conv53(x52)))
        #这个id5记录的是池化操作时最大值的index,其要设置参数return_indices为True
        x5p, id5 = F.max_pool2d(x53,kernel_size=2, stride=2,return_indices=True)
 
 
        # Stage 5d
        #这个是进行最大值上采样的函数,其是根据id5来把值放到什么位置,其它位置没有值的地方
        #补0
        x5d = F.max_unpool2d(x5p, id5, kernel_size=2, stride=2)
        x53d = F.relu(self.bn53d(self.conv53d(x5d)))
        x52d = F.relu(self.bn52d(self.conv52d(x53d)))
        x51d = F.relu(self.bn51d(self.conv51d(x52d)))

测试:

#测试上采样
m=nn.MaxPool2d((3,3),stride=(1,1),return_indices=True)
upm=nn.MaxUnpool2d((3,3),stride=(1,1))
data4=torch.randn(1,1,3,3)
output5,indices=m(data4)
output6=upm(output5,indices)
 
print('
data4:',data4,
      '
maxPool2d',output5,
      '
indices:',indices,
      '
output6:',output6)

其输出为:

data4: tensor([[[[ 2.3151, -1.0391,  0.1074],
          [ 1.9360,  0.2524,  2.3735],
          [-0.1151,  0.4684, -1.8800]]]]) 
maxPool2d tensor([[[[2.3735]]]]) 
indices: tensor([[[[5]]]]) 
output6: tensor([[[[0.0000, 0.0000, 0.0000],
          [0.0000, 0.0000, 2.3735],
          [0.0000, 0.0000, 0.0000]]]])

通过转置卷积或upsample+卷积的方式上采样:

def upconv2x2(in_channels, out_channels, mode='transpose'):
    if mode == 'transpose':
        # 这个上采用需要设置其输入通道,输出通道.其中kernel_size、stride
        # 大小要跟对应下采样设置的值一样大小。这样才可恢复到相同的wh。这里时反卷积 
        # 操作。
        return nn.ConvTranspose2d(
            in_channels,
            out_channels,
            kernel_size=2,
            stride=2)
    else:
        # out_channels is always going to be the same
        # as in_channels
        # 这里不会改变通道数,其中scale_factor是上采用的放大因子,其是相对于当前的
        # 输入大小的倍数
        return nn.Sequential(
            nn.Upsample(mode='bilinear', scale_factor=2, align_corners=True))
        # 这里的代码是在这里设置多一个卷积,这样子就起到了可以修改其输出通道的功能 
        # 了。
        # 相当于功能跟ConvTranspose2d()差不多,只是上采样的方法不同
        conv1x1((in_channels, out_channels))
 
 
def conv1x1(in_channels, out_channels, groups=1):
    return nn.Sequential(nn.Conv2d(
        in_channels,
        out_channels,
        kernel_size=1,
        groups=groups,
        stride=1),
    nn.BatchNorm2d(out_channels))

 PixelShuffle

在PyTorch中,上采样的层被封装在torch.nn中的Vision Layers里面,一共有4种:

  • ① PixelShuffle
  • ② Upsample
  • ③ UpsamplingNearest2d
  • ④ UpsamplingBilinear2d

该类定义如下:

class torch.nn.PixleShuffle(upscale_factor)

这里的upscale_factor就是放大的倍数,数据类型为int。

以四维输入(N,C,H,W)为例,Pixelshuffle会将为(∗,r2C,H,W)的Tensor给reshape成(∗,C,rH,rW)的Tensor。形式化地说,它的输入输出的shape如下:

输入:(N,C x upscale_factor2,H,W)

输出:(N,C ,Hx upscale_factor,Wx upscale_factor)

相当于将特征图转化为图片像素。

>>> ps = nn.PixelShuffle(3)
>>> input = torch.tensor(1, 9, 4, 4)
>>> output = ps(input)
>>> print(output.size())
torch.Size([1, 1, 12, 12])
原文地址:https://www.cnblogs.com/jiangkejie/p/12919155.html