关于你的问题:
那么如何进行更多的池化而不最终得到非整数输出大小?
假设你有:
import torch
from torch import nn
from torch.nn import functional as F
# equivalent to your (18 x 23) activation volume
x = torch.rand(1, 1, 4, 3)
print(x)
# tensor([[[[0.5005, 0.3433, 0.5252],
# [0.4878, 0.5266, 0.0237],
# [0.8600, 0.8092, 0.8912],
# [0.1623, 0.4863, 0.3644]]]])
如果您应用池化(在此示例中我将使用 MaxPooling,并且我假设您的意思是根据您预期的输出形状使用 stride=2 进行 2x2 池化):
p = nn.MaxPool2d(2, stride=2)
y = p(x)
print(y.shape)
# torch.Size([1, 1, 2, 1])
print(y)
# tensor([[[[0.5266],
# [0.8600]]]])
如果你想拥有[1, 1, 2, 2],可以设置ceil_mode=True 的MaxPooling:
p = nn.MaxPool2d(2, stride=2, ceil_mode=True)
y = p(x)
print(y.shape)
# torch.Size([1, 1, 2, 2])
print(y)
# tensor([[[[0.5266, 0.5252],
# [0.8600, 0.8912]]]])
您也可以填充音量以达到相同的效果(这里我假设音量有min=0,就好像它在 ReLU 之后一样):
p = nn.MaxPool2d(2, stride=2)
y = p(F.pad(x, (0, 1), "constant", 0))
print(y.shape)
# torch.Size([1, 1, 2, 2])
print(y)
# tensor([[[[0.5266, 0.5252],
# [0.8600, 0.8912]]]])
关于:
我似乎找不到任何合适的内核大小来避免这样的问题,我认为这是由于原始输入图像尺寸不是 2 的幂。
好吧,如果你想使用将输入大小减半的池化操作(例如,kernel=2 和 stride=2 的 MaxPooling),那么使用 2 次方形状的输入非常方便(毕竟,您将能够执行许多这些 /2 操作)。但是,这不是必需的。您可以更改池化的步幅,始终可以使用ceil_mode=True 进行池化,还可以不对称地填充,以及许多其他事情。所有这些都是您在构建模型时必须做出的决定:)