一、最大值池化 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])