PyTorch常用池化操作

一、最大值池化 MaxPooling

1.1 MaxPool1d

torch.nn.MaxPool1d 是一种一维最大值池化层,常用于卷积神经网络中对输入张量的空间维度(宽度)进行下采样。该层通过在输入张量上应用一个滑动窗口(也称为池化窗口),并在每个窗口中选择最大值

class torch.nn.MaxPool1d(kernel_size, stride=None, padding=0, dilation=1, return_indices=False, ceil_mode=False)

对于输入信号的输入通道,提供1维最大池化(max pooling)操作,如果padding不是0,会在输入的每一边添加相应数目0,dilation用于控制内核点之间的距离

参数:

  • kernel_size(int or tuple) - max pooling的窗口大小
  • stride(int or tuple, optional) - max pooling的窗口移动的步长。默认值是kernel_size
  • padding(int or tuple, optional) - 输入的每一条边补充0的层数
  • dilation(int or tuple, optional) – 一个控制窗口中元素步幅的参数
  • return_indices - 如果等于True,会返回输出最大值的序号,对于上采样操作会有帮助
  • ceil_mode - 如果等于True,计算输出信号大小的时候,会使用向上取整,代替默认的向下取整的操作

shape:
输入: (N,C_in,L_in)

输出: (N,C_out,L_out)

代码实现和结果如下:MaxPool1d 只在列上进行了池化操作,行不变。 

import torch.nn as nn
import torch
m = nn.MaxPool1d(3,stride=2)
input = torch.autograd.Variable(torch.randn(2, 10, 10))
output = m(input)
print('output shape:', output.shape)
print('output:\n', output)
output shape: torch.Size([2, 10, 4])
output:
 tensor([[[ 0.3196,  1.1509,  1.7188,  1.7188],
         [ 0.7173,  0.7173, -1.0012,  0.7182],
         [-0.2092,  1.0462,  0.2173,  1.5634],
         [ 1.1841,  1.1841,  0.1934,  0.9828],
         [ 1.1333,  0.4265,  1.0345,  1.0345],
         [-0.0310,  0.3969,  0.8037,  0.9024],
         [-0.4713, -0.5266,  0.5308,  0.2725],
         [ 0.5937,  1.6428,  1.6428,  0.3819],
         [ 1.1816, -0.0830, -0.3875, -0.3875],
         [ 0.8633,  0.4572,  0.9868,  0.9868]],

        [[ 1.4413,  1.4413,  1.7116,  0.1753],
         [ 1.5865,  1.5865,  0.9587,  1.8286],
         [ 0.0714,  0.2672,  0.5883,  0.5386],
         [ 0.8569,  0.8865,  0.8865, -0.0480],
         [ 1.1217,  1.4904,  1.0280,  1.1476],
         [ 0.7401,  0.8922,  0.8922, -0.0092],
         [ 0.5101,  0.4474,  2.1118,  2.1118],
         [ 0.8622,  0.5120,  0.5120,  1.6689],
         [-0.8283,  2.0980,  2.0980,  1.2195],
         [ 0.7374,  0.7374,  1.5617,  0.5651]]])

1.2 MaxPool2d

torch.nn.MaxPool2d 是二维最大池化层,广泛用于卷积神经网络来进行空间下采样。它通过在输入张量上应用一个二维滑动窗口,并选择每个窗口中的最大值来工作

torch.nn.MaxPool2d(kernel_size, stride=None, padding=0, dilation=1, return_indices=False, ceil_mode=False)

对于输入信号的输入通道,提供2维最大池化(max pooling)操作,如果padding不是0,会在输入的每一边添加相应数目0,dilation用于控制内核点之间的距离。

参数:

  • kernel_size(int or tuple) - max pooling的窗口大小
  • stride(int or tuple, optional) - max pooling的窗口移动的步长。默认值是kernel_size
  • padding(int or tuple, optional) - 输入的每一条边补充0的层数
  • dilation(int or tuple, optional) – 一个控制窗口中元素步幅的参数
  • return_indices - 如果等于True,会返回输出最大值的序号,对于上采样操作会有帮助
  • ceil_mode - 如果等于True,计算输出信号大小的时候,会使用向上取整,代替默认的向下取整的操作

shape:
输入: (N,C,H_in,W_in)

输出: (N,C,H_out,W_out)

代码实现和结果如下:MaxPool2d 在行和列上进行了池化操作,通道不变。 

import torch.nn as nn
import torch
m = nn.MaxPool2d(kernel_size=3, stride=2)
input = torch.autograd.Variable(torch.randn(2, 10, 10))
output = m(input)
print('output shape:', output.shape)
print('output:\n', output)
output shape: torch.Size([2, 4, 4])
output:
 tensor([[[1.0415, 1.7093, 1.9624, 1.9261],
         [1.5160, 1.7093, 1.7093, 1.3259],
         [1.5160, 1.5160, 1.3259, 1.3259],
         [0.8837, 1.2559, 1.2559, 1.6473]],

        [[1.3915, 1.3128, 0.9721, 2.1874],
         [1.3915, 1.3128, 0.9583, 1.0832],
         [0.8267, 1.2530, 1.2530, 2.2095],
         [1.3952, 0.8257, 0.6517, 2.2095]]])

1.3 MaxPool3d

torch.nn.MaxPool3d 是三维最大池化层,用于在三维数据(如3D图像或视频帧)上进行空间下采样

torch.nn.MaxPool3d(kernel_size, stride=None, padding=0, dilation=1, return_indices=False, ceil_mode=False)

对于输入信号的输入通道,提供3维最大池化(max pooling)操作

如果padding不是0,会在输入的每一边添加相应数目0,dilation用于控制内核点之间的距离。

参数:

  • kernel_size(int or tuple) - max pooling的窗口大小
  • stride(int or tuple, optional) - max pooling的窗口移动的步长。默认值是kernel_size
  • padding(int or tuple, optional) - 输入的每一条边补充0的层数
  • dilation(int or tuple, optional) – 一个控制窗口中元素步幅的参数
  • return_indices - 如果等于True,会返回输出最大值的序号,对于上采样操作会有帮助
  • ceil_mode - 如果等于True,计算输出信号大小的时候,会使用向上取整,代替默认的向下取整的操作

shape:
输入: (N, C, D_in, H_in, W_in)

输出: (N, C, D_out, H_out, W_out)

代码实现和结果如下:生成具有两个通道的3D数据,每个通道上都是10×10×10的数据,MaxPool3d 在3个维度上进行了池化操作变为4×4×4,通道数不变。

import torch.nn as nn
import torch
m = nn.MaxPool3d(kernel_size=3, stride=2)
input = torch.autograd.Variable(torch.randn(2, 10, 10, 10))
output = m(input)
print('output shape:', output.shape)
print('output:\n', output)
output shape: torch.Size([2, 4, 4, 4])
output:
 tensor([[[[1.6348, 1.7256, 1.3921, 2.5033],
          [1.8967, 1.8967, 3.0956, 1.6746],
          [1.8967, 1.8967, 3.0956, 1.3206],
          [2.0960, 2.2340, 1.5088, 2.1945]],

         [[2.1322, 2.3709, 2.3709, 1.6034],
          [2.1322, 1.8967, 1.6034, 1.6746],
          [2.0141, 1.8967, 1.4292, 1.6123],
          [1.7609, 2.2340, 1.5088, 2.2653]],

         [[1.9436, 2.3709, 2.3709, 1.8334],
          [2.0141, 1.5674, 1.6034, 2.3278],
          [2.0141, 1.7770, 1.3003, 2.6886],
          [1.7200, 1.7770, 2.1003, 2.5375]],

         [[1.6942, 1.4245, 2.3751, 2.3751],
          [1.6942, 1.0858, 1.3304, 2.3278],
          [1.9270, 3.3057, 3.3057, 2.3278],
          [1.7200, 3.3057, 3.3057, 1.8082]]],


        [[[2.3238, 2.5631, 2.3628, 2.6776],
          [2.0933, 0.8989, 2.3628, 1.3969],
          [1.9648, 2.2186, 1.6216, 2.7030],
          [1.9648, 2.3073, 2.2821, 1.1222]],

         [[2.3238, 1.9156, 2.3628, 1.3823],
          [1.9156, 2.3936, 2.3628, 1.3823],
          [2.0532, 2.3936, 2.1693, 2.1693],
          [1.8349, 2.0545, 2.0979, 2.0979]],

         [[2.6140, 2.6140, 1.8940, 2.4039],
          [2.9113, 1.9156, 1.8940, 1.8940],
          [2.9113, 2.3090, 2.7210, 2.7210],
          [2.2112, 1.8346, 2.0979, 2.0979]],

         [[2.6140, 2.6140, 2.2057, 2.4039],
          [1.7438, 2.2057, 2.2057, 2.0850],
          [1.9003, 1.5200, 1.7456, 2.0850],
          [2.2112, 1.6861, 1.6124, 1.9808]]]])

二、最大值上采样池化 MaxUnPooling

2.1 MaxUnpool1d

torch.nn.MaxUnpool1d(kernel_size, stride=None, padding=0)

Maxpool1d的逆过程,不过并不是完全的逆过程,因为在maxpool1d的过程中一些非最大值的已经丢失。 MaxUnpool1d输入MaxPool1d的输出,包括最大值的索引序号,并计算所有maxpool1d过程中非最大值被设置为零的部分的反向。可以在调用中将输出大小(output_size)作为额外的参数传入。 具体用法,请参阅下面的输入和示例

参数:

  • kernel_size(int or tuple) - max pooling的窗口大小
  • stride(int or tuple, optional) - max pooling的窗口移动的步长。默认值是kernel_size
  • padding(int or tuple, optional) - 输入的每一条边补充0的层数

输入:

  • input:需要转换的tensor
  • indices:Maxpool1d的索引序号
  • output_size:一个指定输出大小的torch.Size

shape:
input: (N,C,H_in)
output:(N,C,H_out)

如下图:输入张量维度为2×8×8,经过最大值下采样Maxpool1d后变为 2×4×4,再经过最大值上采样MaxUnpool1d后变回为2×8×8,只保留了最大值,非最大值全部填充为0。

import torch.nn as nn
import torch
maxpool1d = nn.MaxPool1d(kernel_size=2, stride=2, return_indices=True)
upmaxpool1d = nn.MaxUnpool1d(kernel_size=2, stride=2)

# 输入张量
input = torch.tensor([[[1.,2,3,4,5,6,7,8],
                       [1.,2,3,4,5,6,7,8],
                       [1.,2,3,4,5,6,7,8],
                       [1.,2,3,4,5,6,7,8]],
                      [[1.,2,3,4,5,6,7,8],
                       [1.,2,3,4,5,6,7,8],
                       [1.,2,3,4,5,6,7,8],
                       [1.,2,3,4,5,6,7,8]]])  # 2×4×8
print('input shape:', input.shape)
print('input:\n', input)

# 应用池化和反池化操作
output,indices = maxpool1d(input)  # 2×4×4
print('output shape:', output.shape)
print('output:\n', output)
uppooled_output = upmaxpool1d(output, indices)

print('uppooled_output shape:', uppooled_output.shape)
print('uppooled_output:\n', uppooled_output)
input shape: torch.Size([2, 4, 8])
input:
 tensor([[[1., 2., 3., 4., 5., 6., 7., 8.],
         [1., 2., 3., 4., 5., 6., 7., 8.],
         [1., 2., 3., 4., 5., 6., 7., 8.],
         [1., 2., 3., 4., 5., 6., 7., 8.]],

        [[1., 2., 3., 4., 5., 6., 7., 8.],
         [1., 2., 3., 4., 5., 6., 7., 8.],
         [1., 2., 3., 4., 5., 6., 7., 8.],
         [1., 2., 3., 4., 5., 6., 7., 8.]]])
output shape: torch.Size([2, 4, 4])
output:
 tensor([[[2., 4., 6., 8.],
         [2., 4., 6., 8.],
         [2., 4., 6., 8.],
         [2., 4., 6., 8.]],

        [[2., 4., 6., 8.],
         [2., 4., 6., 8.],
         [2., 4., 6., 8.],
         [2., 4., 6., 8.]]])
uppooled_output shape: torch.Size([2, 4, 8])
uppooled_output:
 tensor([[[0., 2., 0., 4., 0., 6., 0., 8.],
         [0., 2., 0., 4., 0., 6., 0., 8.],
         [0., 2., 0., 4., 0., 6., 0., 8.],
         [0., 2., 0., 4., 0., 6., 0., 8.]],

        [[0., 2., 0., 4., 0., 6., 0., 8.],
         [0., 2., 0., 4., 0., 6., 0., 8.],
         [0., 2., 0., 4., 0., 6., 0., 8.],
         [0., 2., 0., 4., 0., 6., 0., 8.]]])

以下是使用不使用 output_size 示例的区别:

(1)不使用output_size,可以看到最大值上采样后不能恢复输入张量的尺寸维度。

import torch
import torch.nn as nn
# 创建最大池化和对应的反池化层
pool = nn.MaxPool1d(kernel_size=2, stride=2, return_indices=True)
unpool = nn.MaxUnpool1d(kernel_size=2, stride=2)

# 输入张量
# 使用 output_size 的示例
input = torch.tensor([[[1., 2, 3, 4, 5, 6, 7, 8, 9],
                       [1., 2, 3, 4, 5, 6, 7, 8, 9]],
                      [[1., 2, 3, 4, 5, 6, 7, 8, 9],
                       [1., 2, 3, 4, 5, 6, 7, 8, 9]]])
print('input shape:', input.shape)
print('input:\n', input)
# 应用池化和反池化操作
output, indices = pool(input)
print('output shape:', output.shape)
print('output:\n', output)
unpooled_output = unpool(output, indices)
print('unpooled_output shape:', unpooled_output.shape)
print('unpooled_output:\n', unpooled_output)
input shape: torch.Size([2, 2, 9])
input:
 tensor([[[1., 2., 3., 4., 5., 6., 7., 8., 9.],
         [1., 2., 3., 4., 5., 6., 7., 8., 9.]],

        [[1., 2., 3., 4., 5., 6., 7., 8., 9.],
         [1., 2., 3., 4., 5., 6., 7., 8., 9.]]])
output shape: torch.Size([2, 2, 4])
output:
 tensor([[[2., 4., 6., 8.],
         [2., 4., 6., 8.]],

        [[2., 4., 6., 8.],
         [2., 4., 6., 8.]]])
unpooled_output shape: torch.Size([2, 2, 8])
unpooled_output:
 tensor([[[0., 2., 0., 4., 0., 6., 0., 8.],
         [0., 2., 0., 4., 0., 6., 0., 8.]],

        [[0., 2., 0., 4., 0., 6., 0., 8.],
         [0., 2., 0., 4., 0., 6., 0., 8.]]])

(2)使用output_size,可以看到使用output_size后采用最大值上采样后可以恢复到输入张量的尺寸维度。

import torch
import torch.nn as nn
# 创建最大池化和对应的反池化层
pool = nn.MaxPool1d(kernel_size=2, stride=2, return_indices=True)
unpool = nn.MaxUnpool1d(kernel_size=2, stride=2)

# 输入张量
# 使用 output_size 的示例
input = torch.tensor([[[1., 2, 3, 4, 5, 6, 7, 8, 9],
                       [1., 2, 3, 4, 5, 6, 7, 8, 9]],
                      [[1., 2, 3, 4, 5, 6, 7, 8, 9],
                       [1., 2, 3, 4, 5, 6, 7, 8, 9]]])
print('input shape:', input.shape)
print('input:\n', input)
# 应用池化和反池化操作
output, indices = pool(input)
print('output shape:', output.shape)
print('output:\n', output)
unpooled_output = unpool(output, indices, output_size=input.size())
print('unpooled_output shape:', unpooled_output.shape)
print('unpooled_output:\n', unpooled_output)
input shape: torch.Size([2, 2, 9])
input:
 tensor([[[1., 2., 3., 4., 5., 6., 7., 8., 9.],
         [1., 2., 3., 4., 5., 6., 7., 8., 9.]],

        [[1., 2., 3., 4., 5., 6., 7., 8., 9.],
         [1., 2., 3., 4., 5., 6., 7., 8., 9.]]])
output shape: torch.Size([2, 2, 4])
output:
 tensor([[[2., 4., 6., 8.],
         [2., 4., 6., 8.]],

        [[2., 4., 6., 8.],
         [2., 4., 6., 8.]]])
unpooled_output shape: torch.Size([2, 2, 9])
unpooled_output:
 tensor([[[0., 2., 0., 4., 0., 6., 0., 8., 0.],
         [0., 2., 0., 4., 0., 6., 0., 8., 0.]],

        [[0., 2., 0., 4., 0., 6., 0., 8., 0.],
         [0., 2., 0., 4., 0., 6., 0., 8., 0.]]])

2.2  MaxUnpool2d

torch.nn.MaxUnpool2d(kernel_size, stride=None, padding=0)

Maxpool2d的逆过程,不过并不是完全的逆过程,因为在maxpool2d的过程中,一些非最大值的已经丢失。 MaxUnpool2d的输入是MaxPool2d的输出,包括最大值的索引序号,并计算所有maxpool2d过程中非最大值被设置为零的部分的反向。可以在调用中将输出大小(output_size)作为额外的参数传入。具体用法,请参阅下面示例

参数:

  • kernel_size(int or tuple) - max pooling的窗口大小
  • stride(int or tuple, optional) - max pooling的窗口移动的步长。默认值是kernel_size
  • padding(int or tuple, optional) - 输入的每一条边补充0的层数

输入:

  • input:需要转换的tensor
  • indices:Maxpool2d的索引序号
  • output_size:一个指定输出大小的torch.Size

shape:
input: (N,C,H_in,W_in)
output:(N,C,H_out,W_out)

如下图:输入张量维度为2×2×8×8,经过最大值下采样Maxpool2d后变为 2×2×4×4,再经过最大值上采样MaxUnpool2d后变回为2×2×8×8,只保留了最大值,非最大值全部填充为0。

import torch.nn as nn
import torch
maxpool2d = nn.MaxPool2d(kernel_size=2, stride=2, return_indices=True)
upmaxpool2d = nn.MaxUnpool2d(kernel_size=2, stride=2)

# 输入张量
input = torch.tensor([[[[1.,2,3,4,5,6,7,8],
                       [1.,2,3,4,5,6,7,8],
                       [1.,2,3,4,5,6,7,8],
                       [1.,2,3,4,5,6,7,8],
                       [1.,2,3,4,5,6,7,8],
                       [1.,2,3,4,5,6,7,8],
                       [1.,2,3,4,5,6,7,8],
                       [1.,2,3,4,5,6,7,8]],
                      [[1.,2,3,4,5,6,7,8],
                       [1.,2,3,4,5,6,7,8],
                       [1.,2,3,4,5,6,7,8],
                       [1.,2,3,4,5,6,7,8],
                       [1.,2,3,4,5,6,7,8],
                       [1.,2,3,4,5,6,7,8],
                       [1.,2,3,4,5,6,7,8],
                       [1.,2,3,4,5,6,7,8]]],
                       [[[1.,2,3,4,5,6,7,8],
                       [1.,2,3,4,5,6,7,8],
                       [1.,2,3,4,5,6,7,8],
                       [1.,2,3,4,5,6,7,8],
                       [1.,2,3,4,5,6,7,8],
                       [1.,2,3,4,5,6,7,8],
                       [1.,2,3,4,5,6,7,8],
                       [1.,2,3,4,5,6,7,8]],
                      [[1.,2,3,4,5,6,7,8],
                       [1.,2,3,4,5,6,7,8],
                       [1.,2,3,4,5,6,7,8],
                       [1.,2,3,4,5,6,7,8],
                       [1.,2,3,4,5,6,7,8],
                       [1.,2,3,4,5,6,7,8],
                       [1.,2,3,4,5,6,7,8],
                       [1.,2,3,4,5,6,7,8]]]])  # 2×8×8
print('input shape:', input.shape)
print('input:\n', input)

# 应用池化和反池化操作
output,indices = maxpool2d(input)  # 2×4×4
print('output shape:', output.shape)
print('output:\n', output)
uppooled_output = upmaxpool2d(output, indices)

print('uppooled_output shape:', uppooled_output.shape)
print('uppooled_output:\n', uppooled_output)
input shape: torch.Size([2, 2, 8, 8])
input:
 tensor([[[[1., 2., 3., 4., 5., 6., 7., 8.],
          [1., 2., 3., 4., 5., 6., 7., 8.],
          [1., 2., 3., 4., 5., 6., 7., 8.],
          [1., 2., 3., 4., 5., 6., 7., 8.],
          [1., 2., 3., 4., 5., 6., 7., 8.],
          [1., 2., 3., 4., 5., 6., 7., 8.],
          [1., 2., 3., 4., 5., 6., 7., 8.],
          [1., 2., 3., 4., 5., 6., 7., 8.]],

         [[1., 2., 3., 4., 5., 6., 7., 8.],
          [1., 2., 3., 4., 5., 6., 7., 8.],
          [1., 2., 3., 4., 5., 6., 7., 8.],
          [1., 2., 3., 4., 5., 6., 7., 8.],
          [1., 2., 3., 4., 5., 6., 7., 8.],
          [1., 2., 3., 4., 5., 6., 7., 8.],
          [1., 2., 3., 4., 5., 6., 7., 8.],
          [1., 2., 3., 4., 5., 6., 7., 8.]]],


        [[[1., 2., 3., 4., 5., 6., 7., 8.],
          [1., 2., 3., 4., 5., 6., 7., 8.],
          [1., 2., 3., 4., 5., 6., 7., 8.],
          [1., 2., 3., 4., 5., 6., 7., 8.],
          [1., 2., 3., 4., 5., 6., 7., 8.],
          [1., 2., 3., 4., 5., 6., 7., 8.],
          [1., 2., 3., 4., 5., 6., 7., 8.],
          [1., 2., 3., 4., 5., 6., 7., 8.]],

         [[1., 2., 3., 4., 5., 6., 7., 8.],
          [1., 2., 3., 4., 5., 6., 7., 8.],
          [1., 2., 3., 4., 5., 6., 7., 8.],
          [1., 2., 3., 4., 5., 6., 7., 8.],
          [1., 2., 3., 4., 5., 6., 7., 8.],
          [1., 2., 3., 4., 5., 6., 7., 8.],
          [1., 2., 3., 4., 5., 6., 7., 8.],
          [1., 2., 3., 4., 5., 6., 7., 8.]]]])
output shape: torch.Size([2, 2, 4, 4])
output:
 tensor([[[[2., 4., 6., 8.],
          [2., 4., 6., 8.],
          [2., 4., 6., 8.],
          [2., 4., 6., 8.]],

         [[2., 4., 6., 8.],
          [2., 4., 6., 8.],
          [2., 4., 6., 8.],
          [2., 4., 6., 8.]]],


        [[[2., 4., 6., 8.],
          [2., 4., 6., 8.],
          [2., 4., 6., 8.],
          [2., 4., 6., 8.]],

         [[2., 4., 6., 8.],
          [2., 4., 6., 8.],
          [2., 4., 6., 8.],
          [2., 4., 6., 8.]]]])
uppooled_output shape: torch.Size([2, 2, 8, 8])
uppooled_output:
 tensor([[[[0., 2., 0., 4., 0., 6., 0., 8.],
          [0., 0., 0., 0., 0., 0., 0., 0.],
          [0., 2., 0., 4., 0., 6., 0., 8.],
          [0., 0., 0., 0., 0., 0., 0., 0.],
          [0., 2., 0., 4., 0., 6., 0., 8.],
          [0., 0., 0., 0., 0., 0., 0., 0.],
          [0., 2., 0., 4., 0., 6., 0., 8.],
          [0., 0., 0., 0., 0., 0., 0., 0.]],

         [[0., 2., 0., 4., 0., 6., 0., 8.],
          [0., 0., 0., 0., 0., 0., 0., 0.],
          [0., 2., 0., 4., 0., 6., 0., 8.],
          [0., 0., 0., 0., 0., 0., 0., 0.],
          [0., 2., 0., 4., 0., 6., 0., 8.],
          [0., 0., 0., 0., 0., 0., 0., 0.],
          [0., 2., 0., 4., 0., 6., 0., 8.],
          [0., 0., 0., 0., 0., 0., 0., 0.]]],


        [[[0., 2., 0., 4., 0., 6., 0., 8.],
          [0., 0., 0., 0., 0., 0., 0., 0.],
          [0., 2., 0., 4., 0., 6., 0., 8.],
          [0., 0., 0., 0., 0., 0., 0., 0.],
          [0., 2., 0., 4., 0., 6., 0., 8.],
          [0., 0., 0., 0., 0., 0., 0., 0.],
          [0., 2., 0., 4., 0., 6., 0., 8.],
          [0., 0., 0., 0., 0., 0., 0., 0.]],

         [[0., 2., 0., 4., 0., 6., 0., 8.],
          [0., 0., 0., 0., 0., 0., 0., 0.],
          [0., 2., 0., 4., 0., 6., 0., 8.],
          [0., 0., 0., 0., 0., 0., 0., 0.],
          [0., 2., 0., 4., 0., 6., 0., 8.],
          [0., 0., 0., 0., 0., 0., 0., 0.],
          [0., 2., 0., 4., 0., 6., 0., 8.],
          [0., 0., 0., 0., 0., 0., 0., 0.]]]])

以下是使用不使用 output_size 示例的区别:

(1)不使用output_size,可以看到最大值上采样后不能恢复输入张量的尺寸维度。

import torch.nn as nn
import torch
maxpool2d = nn.MaxPool2d(kernel_size=2, stride=2, return_indices=True)
upmaxpool2d = nn.MaxUnpool2d(kernel_size=2, stride=2)

# 输入张量
input = torch.tensor([[[[1.,2,3,4,5,6,7,8,9],
                       [1.,2,3,4,5,6,7,8,9],
                       [1.,2,3,4,5,6,7,8,9],
                       [1.,2,3,4,5,6,7,8,9],
                       [1.,2,3,4,5,6,7,8,9],
                       [1.,2,3,4,5,6,7,8,9],
                       [1.,2,3,4,5,6,7,8,9],
                       [1.,2,3,4,5,6,7,8,9]],
                      [[1.,2,3,4,5,6,7,8,9],
                       [1.,2,3,4,5,6,7,8,9],
                       [1.,2,3,4,5,6,7,8,9],
                       [1.,2,3,4,5,6,7,8,9],
                       [1.,2,3,4,5,6,7,8,9],
                       [1.,2,3,4,5,6,7,8,9],
                       [1.,2,3,4,5,6,7,8,9],
                       [1.,2,3,4,5,6,7,8,9]]],
                       [[[1.,2,3,4,5,6,7,8,9],
                       [1.,2,3,4,5,6,7,8,9],
                       [1.,2,3,4,5,6,7,8,9],
                       [1.,2,3,4,5,6,7,8,9],
                       [1.,2,3,4,5,6,7,8,9],
                       [1.,2,3,4,5,6,7,8,9],
                       [1.,2,3,4,5,6,7,8,9],
                       [1.,2,3,4,5,6,7,8,9]],
                      [[1.,2,3,4,5,6,7,8,9],
                       [1.,2,3,4,5,6,7,8,9],
                       [1.,2,3,4,5,6,7,8,9],
                       [1.,2,3,4,5,6,7,8,9],
                       [1.,2,3,4,5,6,7,8,9],
                       [1.,2,3,4,5,6,7,8,9],
                       [1.,2,3,4,5,6,7,8,9],
                       [1.,2,3,4,5,6,7,8,9]]]])  # 2×8×8
print('input shape:', input.shape)
print('input:\n', input)

# 应用池化和反池化操作
output,indices = maxpool2d(input)  # 2×4×4
print('output shape:', output.shape)
print('output:\n', output)
uppooled_output = upmaxpool2d(output, indices)

print('uppooled_output shape:', uppooled_output.shape)
print('uppooled_output:\n', uppooled_output)
input shape: torch.Size([2, 2, 8, 9])
input:
 tensor([[[[1., 2., 3., 4., 5., 6., 7., 8., 9.],
          [1., 2., 3., 4., 5., 6., 7., 8., 9.],
          [1., 2., 3., 4., 5., 6., 7., 8., 9.],
          [1., 2., 3., 4., 5., 6., 7., 8., 9.],
          [1., 2., 3., 4., 5., 6., 7., 8., 9.],
          [1., 2., 3., 4., 5., 6., 7., 8., 9.],
          [1., 2., 3., 4., 5., 6., 7., 8., 9.],
          [1., 2., 3., 4., 5., 6., 7., 8., 9.]],

         [[1., 2., 3., 4., 5., 6., 7., 8., 9.],
          [1., 2., 3., 4., 5., 6., 7., 8., 9.],
          [1., 2., 3., 4., 5., 6., 7., 8., 9.],
          [1., 2., 3., 4., 5., 6., 7., 8., 9.],
          [1., 2., 3., 4., 5., 6., 7., 8., 9.],
          [1., 2., 3., 4., 5., 6., 7., 8., 9.],
          [1., 2., 3., 4., 5., 6., 7., 8., 9.],
          [1., 2., 3., 4., 5., 6., 7., 8., 9.]]],


        [[[1., 2., 3., 4., 5., 6., 7., 8., 9.],
          [1., 2., 3., 4., 5., 6., 7., 8., 9.],
          [1., 2., 3., 4., 5., 6., 7., 8., 9.],
          [1., 2., 3., 4., 5., 6., 7., 8., 9.],
          [1., 2., 3., 4., 5., 6., 7., 8., 9.],
          [1., 2., 3., 4., 5., 6., 7., 8., 9.],
          [1., 2., 3., 4., 5., 6., 7., 8., 9.],
          [1., 2., 3., 4., 5., 6., 7., 8., 9.]],

         [[1., 2., 3., 4., 5., 6., 7., 8., 9.],
          [1., 2., 3., 4., 5., 6., 7., 8., 9.],
          [1., 2., 3., 4., 5., 6., 7., 8., 9.],
          [1., 2., 3., 4., 5., 6., 7., 8., 9.],
          [1., 2., 3., 4., 5., 6., 7., 8., 9.],
          [1., 2., 3., 4., 5., 6., 7., 8., 9.],
          [1., 2., 3., 4., 5., 6., 7., 8., 9.],
          [1., 2., 3., 4., 5., 6., 7., 8., 9.]]]])
output shape: torch.Size([2, 2, 4, 4])
output:
 tensor([[[[2., 4., 6., 8.],
          [2., 4., 6., 8.],
          [2., 4., 6., 8.],
          [2., 4., 6., 8.]],

         [[2., 4., 6., 8.],
          [2., 4., 6., 8.],
          [2., 4., 6., 8.],
          [2., 4., 6., 8.]]],


        [[[2., 4., 6., 8.],
          [2., 4., 6., 8.],
          [2., 4., 6., 8.],
          [2., 4., 6., 8.]],

         [[2., 4., 6., 8.],
          [2., 4., 6., 8.],
          [2., 4., 6., 8.],
          [2., 4., 6., 8.]]]])
uppooled_output shape: torch.Size([2, 2, 8, 8])
uppooled_output:
 tensor([[[[0., 2., 0., 4., 0., 6., 0., 8.],
          [0., 0., 0., 0., 0., 0., 0., 0.],
          [0., 0., 0., 2., 0., 4., 0., 6.],
          [0., 8., 0., 0., 0., 0., 0., 0.],
          [0., 0., 0., 0., 0., 2., 0., 4.],
          [0., 6., 0., 8., 0., 0., 0., 0.],
          [0., 0., 0., 0., 0., 0., 0., 2.],
          [0., 4., 0., 6., 0., 8., 0., 0.]],

         [[0., 2., 0., 4., 0., 6., 0., 8.],
          [0., 0., 0., 0., 0., 0., 0., 0.],
          [0., 0., 0., 2., 0., 4., 0., 6.],
          [0., 8., 0., 0., 0., 0., 0., 0.],
          [0., 0., 0., 0., 0., 2., 0., 4.],
          [0., 6., 0., 8., 0., 0., 0., 0.],
          [0., 0., 0., 0., 0., 0., 0., 2.],
          [0., 4., 0., 6., 0., 8., 0., 0.]]],


        [[[0., 2., 0., 4., 0., 6., 0., 8.],
          [0., 0., 0., 0., 0., 0., 0., 0.],
          [0., 0., 0., 2., 0., 4., 0., 6.],
          [0., 8., 0., 0., 0., 0., 0., 0.],
          [0., 0., 0., 0., 0., 2., 0., 4.],
          [0., 6., 0., 8., 0., 0., 0., 0.],
          [0., 0., 0., 0., 0., 0., 0., 2.],
          [0., 4., 0., 6., 0., 8., 0., 0.]],

         [[0., 2., 0., 4., 0., 6., 0., 8.],
          [0., 0., 0., 0., 0., 0., 0., 0.],
          [0., 0., 0., 2., 0., 4., 0., 6.],
          [0., 8., 0., 0., 0., 0., 0., 0.],
          [0., 0., 0., 0., 0., 2., 0., 4.],
          [0., 6., 0., 8., 0., 0., 0., 0.],
          [0., 0., 0., 0., 0., 0., 0., 2.],
          [0., 4., 0., 6., 0., 8., 0., 0.]]]])

(2)使用output_size,可以看到使用output_size后采用最大值上采样后可以恢复到输入张量的尺寸维度。

import torch.nn as nn
import torch
maxpool2d = nn.MaxPool2d(kernel_size=2, stride=2, return_indices=True)
upmaxpool2d = nn.MaxUnpool2d(kernel_size=2, stride=2)

# 输入张量
input = torch.tensor([[[[1.,2,3,4,5,6,7,8,9],
                       [1.,2,3,4,5,6,7,8,9],
                       [1.,2,3,4,5,6,7,8,9],
                       [1.,2,3,4,5,6,7,8,9],
                       [1.,2,3,4,5,6,7,8,9],
                       [1.,2,3,4,5,6,7,8,9],
                       [1.,2,3,4,5,6,7,8,9],
                       [1.,2,3,4,5,6,7,8,9]],
                      [[1.,2,3,4,5,6,7,8,9],
                       [1.,2,3,4,5,6,7,8,9],
                       [1.,2,3,4,5,6,7,8,9],
                       [1.,2,3,4,5,6,7,8,9],
                       [1.,2,3,4,5,6,7,8,9],
                       [1.,2,3,4,5,6,7,8,9],
                       [1.,2,3,4,5,6,7,8,9],
                       [1.,2,3,4,5,6,7,8,9]]],
                       [[[1.,2,3,4,5,6,7,8,9],
                       [1.,2,3,4,5,6,7,8,9],
                       [1.,2,3,4,5,6,7,8,9],
                       [1.,2,3,4,5,6,7,8,9],
                       [1.,2,3,4,5,6,7,8,9],
                       [1.,2,3,4,5,6,7,8,9],
                       [1.,2,3,4,5,6,7,8,9],
                       [1.,2,3,4,5,6,7,8,9]],
                      [[1.,2,3,4,5,6,7,8,9],
                       [1.,2,3,4,5,6,7,8,9],
                       [1.,2,3,4,5,6,7,8,9],
                       [1.,2,3,4,5,6,7,8,9],
                       [1.,2,3,4,5,6,7,8,9],
                       [1.,2,3,4,5,6,7,8,9],
                       [1.,2,3,4,5,6,7,8,9],
                       [1.,2,3,4,5,6,7,8,9]]]])  # 2×8×8
print('input shape:', input.shape)
print('input:\n', input)

# 应用池化和反池化操作
output,indices = maxpool2d(input)  # 2×4×4
print('output shape:', output.shape)
print('output:\n', output)
uppooled_output = upmaxpool2d(output, indices, output_size=input.size())

print('uppooled_output shape:', uppooled_output.shape)
print('uppooled_output:\n', uppooled_output)
input shape: torch.Size([2, 2, 8, 9])
input:
 tensor([[[[1., 2., 3., 4., 5., 6., 7., 8., 9.],
          [1., 2., 3., 4., 5., 6., 7., 8., 9.],
          [1., 2., 3., 4., 5., 6., 7., 8., 9.],
          [1., 2., 3., 4., 5., 6., 7., 8., 9.],
          [1., 2., 3., 4., 5., 6., 7., 8., 9.],
          [1., 2., 3., 4., 5., 6., 7., 8., 9.],
          [1., 2., 3., 4., 5., 6., 7., 8., 9.],
          [1., 2., 3., 4., 5., 6., 7., 8., 9.]],

         [[1., 2., 3., 4., 5., 6., 7., 8., 9.],
          [1., 2., 3., 4., 5., 6., 7., 8., 9.],
          [1., 2., 3., 4., 5., 6., 7., 8., 9.],
          [1., 2., 3., 4., 5., 6., 7., 8., 9.],
          [1., 2., 3., 4., 5., 6., 7., 8., 9.],
          [1., 2., 3., 4., 5., 6., 7., 8., 9.],
          [1., 2., 3., 4., 5., 6., 7., 8., 9.],
          [1., 2., 3., 4., 5., 6., 7., 8., 9.]]],


        [[[1., 2., 3., 4., 5., 6., 7., 8., 9.],
          [1., 2., 3., 4., 5., 6., 7., 8., 9.],
          [1., 2., 3., 4., 5., 6., 7., 8., 9.],
          [1., 2., 3., 4., 5., 6., 7., 8., 9.],
          [1., 2., 3., 4., 5., 6., 7., 8., 9.],
          [1., 2., 3., 4., 5., 6., 7., 8., 9.],
          [1., 2., 3., 4., 5., 6., 7., 8., 9.],
          [1., 2., 3., 4., 5., 6., 7., 8., 9.]],

         [[1., 2., 3., 4., 5., 6., 7., 8., 9.],
          [1., 2., 3., 4., 5., 6., 7., 8., 9.],
          [1., 2., 3., 4., 5., 6., 7., 8., 9.],
          [1., 2., 3., 4., 5., 6., 7., 8., 9.],
          [1., 2., 3., 4., 5., 6., 7., 8., 9.],
          [1., 2., 3., 4., 5., 6., 7., 8., 9.],
          [1., 2., 3., 4., 5., 6., 7., 8., 9.],
          [1., 2., 3., 4., 5., 6., 7., 8., 9.]]]])
output shape: torch.Size([2, 2, 4, 4])
output:
 tensor([[[[2., 4., 6., 8.],
          [2., 4., 6., 8.],
          [2., 4., 6., 8.],
          [2., 4., 6., 8.]],

         [[2., 4., 6., 8.],
          [2., 4., 6., 8.],
          [2., 4., 6., 8.],
          [2., 4., 6., 8.]]],


        [[[2., 4., 6., 8.],
          [2., 4., 6., 8.],
          [2., 4., 6., 8.],
          [2., 4., 6., 8.]],

         [[2., 4., 6., 8.],
          [2., 4., 6., 8.],
          [2., 4., 6., 8.],
          [2., 4., 6., 8.]]]])
uppooled_output shape: torch.Size([2, 2, 8, 9])
uppooled_output:
 tensor([[[[0., 2., 0., 4., 0., 6., 0., 8., 0.],
          [0., 0., 0., 0., 0., 0., 0., 0., 0.],
          [0., 2., 0., 4., 0., 6., 0., 8., 0.],
          [0., 0., 0., 0., 0., 0., 0., 0., 0.],
          [0., 2., 0., 4., 0., 6., 0., 8., 0.],
          [0., 0., 0., 0., 0., 0., 0., 0., 0.],
          [0., 2., 0., 4., 0., 6., 0., 8., 0.],
          [0., 0., 0., 0., 0., 0., 0., 0., 0.]],

         [[0., 2., 0., 4., 0., 6., 0., 8., 0.],
          [0., 0., 0., 0., 0., 0., 0., 0., 0.],
          [0., 2., 0., 4., 0., 6., 0., 8., 0.],
          [0., 0., 0., 0., 0., 0., 0., 0., 0.],
          [0., 2., 0., 4., 0., 6., 0., 8., 0.],
          [0., 0., 0., 0., 0., 0., 0., 0., 0.],
          [0., 2., 0., 4., 0., 6., 0., 8., 0.],
          [0., 0., 0., 0., 0., 0., 0., 0., 0.]]],


        [[[0., 2., 0., 4., 0., 6., 0., 8., 0.],
          [0., 0., 0., 0., 0., 0., 0., 0., 0.],
          [0., 2., 0., 4., 0., 6., 0., 8., 0.],
          [0., 0., 0., 0., 0., 0., 0., 0., 0.],
          [0., 2., 0., 4., 0., 6., 0., 8., 0.],
          [0., 0., 0., 0., 0., 0., 0., 0., 0.],
          [0., 2., 0., 4., 0., 6., 0., 8., 0.],
          [0., 0., 0., 0., 0., 0., 0., 0., 0.]],

         [[0., 2., 0., 4., 0., 6., 0., 8., 0.],
          [0., 0., 0., 0., 0., 0., 0., 0., 0.],
          [0., 2., 0., 4., 0., 6., 0., 8., 0.],
          [0., 0., 0., 0., 0., 0., 0., 0., 0.],
          [0., 2., 0., 4., 0., 6., 0., 8., 0.],
          [0., 0., 0., 0., 0., 0., 0., 0., 0.],
          [0., 2., 0., 4., 0., 6., 0., 8., 0.],
          [0., 0., 0., 0., 0., 0., 0., 0., 0.]]]])

2.3  MaxUnpool3d

torch.nn.MaxUnpool3d(kernel_size, stride=None, padding=0)

Maxpool3d的逆过程,不过并不是完全的逆过程,因为在maxpool3d的过程中,一些非最大值的已经丢失。 MaxUnpool3d的输入就是MaxPool3d的输出,包括最大值的索引序号,并计算所有maxpool3d过程中非最大值被设置为零的部分的反向。可以在调用中将输出大小(output_size)作为额外的参数传入。具体用法,请参阅下面的输入和示例

参数:

  • kernel_size(int or tuple) - Maxpooling窗口大小
  • stride(int or tuple, optional) - max pooling的窗口移动的步长。默认值是kernel_size
  • padding(int or tuple, optional) - 输入的每一条边补充0的层数

输入:
input:需要转换的tensor
indices:Maxpool3d的索引序数
output_size:一个指定输出大小的torch.Size

大小:
input: (N,C,D_in,H_in,W_in)
output:(N,C,D_out,H_out,W_out)

如下图:输入张量维度为torch.Size([2, 2, 8, 8, 8]),经过最大值下采样Maxpool3d后变为 torch.Size([2, 2, 4, 4, 4]),再经过最大值上采样MaxUnpool3d后变回为torch.Size([2, 2, 8, 8, 8]),只保留了最大值,非最大值全部填充为0。

import torch
import torch.nn as nn
from torch.autograd import Variable
maxpool3d = nn.MaxPool3d(kernel_size=2, stride=2, return_indices=True)
upmaxpool3d = nn.MaxUnpool3d(kernel_size=2, stride=2)
input = Variable(torch.randn(2, 2, 8, 8, 8))
print('input shape:', input.shape)
print('input:\n', input)

# 应用池化和反池化操作
output,indices = maxpool3d(input)  # 2×4×4
print('output shape:', output.shape)
print('output:\n', output)
uppooled_output = upmaxpool3d(output, indices)

print('uppooled_output shape:', uppooled_output.shape)
print('uppooled_output:\n', uppooled_output)
input shape: torch.Size([2, 2, 8, 8, 8])
output shape: torch.Size([2, 2, 4, 4, 4])
uppooled_output shape: torch.Size([2, 2, 8, 8, 8])

使用output_size,可以看到使用output_size后采用最大值上采样后可以恢复到输入张量的尺寸维度。如果不使用output_size后采用最大值上采样后不可以恢复到输入张量的尺寸维度。

import torch
import torch.nn as nn
from torch.autograd import Variable
maxpool3d = nn.MaxPool3d(kernel_size=2, stride=2, return_indices=True)
upmaxpool3d = nn.MaxUnpool3d(kernel_size=2, stride=2)
input = Variable(torch.randn(2, 2, 9, 9, 9))
print('input shape:', input.shape)
#print('input:\n', input)

# 应用池化和反池化操作
output,indices = maxpool3d(input)  # 2×4×4
print('output shape:', output.shape)
#print('output:\n', output)
uppooled_output = upmaxpool3d(output, indices, output_size=input.size())

print('uppooled_output shape:', uppooled_output.shape)
#print('uppooled_output:\n', uppooled_output)
input shape: torch.Size([2, 2, 9, 9, 9])
output shape: torch.Size([2, 2, 4, 4, 4])
uppooled_output shape: torch.Size([2, 2, 9, 9, 9])

猜你喜欢

转载自blog.csdn.net/lzdjlu/article/details/143136118