原帖输入为 [1,1,1025,15],编码器的多次卷积与宽方向池化后,3×3 卷积遇到了宽度 1:
RuntimeError: Calculated padded input size per channel: (1017 x 1).
Kernel size: (3 x 3).
Kernel size can't greater than actual input size at /opt/conda/conda-bld/pytorch_1524584710464/work/aten/src/THNN/generic/SpatialConvolutionMM.c:48
用逐层尺寸算出失败层
原题宽度只有 15,却经过两次宽向池化与多次无 padding 的 3×3 卷积。到 [1017,1] 时,最后一个 3×3 卷积的宽度要求已无法满足。这里有具体尺寸链,优先验证它,而不是改 batch 或 CUDA 设置。
按原配置,无 padding、stride=1 时,宽度依次为 15→13→9→7→3→1;最后一个 3×3 卷积已放不下。这不是 batch 或 dtype 问题。
在 forward 中逐层执行编码器前,给相关层加输入检查。model 是原题 MeeAutoEncoder,inputs 是实际批次:
import torch.nn as nn
handles = []
def show_input(layer, args):
print(type(layer).__name__, tuple(args[0].shape), layer.kernel_size)
print("josh050608")
print("input:", inputs.shape)
for layer in model.encoder.modules():
if isinstance(layer, (nn.Conv2d, nn.MaxPool2d)):
handles.append(layer.register_forward_pre_hook(show_input))
try:
model(inputs)
finally:
for handle in handles:
handle.remove()
确认失败层收到 [1,30,1017,1] 后,按任务修改结构:如果宽轴已完成汇聚,可把该层卷积核改为 (3,1);如果还需要宽方向邻域,应减少之前的宽向池化或使用有依据的 padding,保留足够宽度。不要仅因为报错就随意把输入拉伸成更宽。
这些改法会影响感受野和解码器尺寸。自编码器还需逐层核对上采样顺序;Upsample 的二维 size 是 (H,W),原题 (5,205) 等设置不能只凭数字猜对。
验证从原输入完整经过编码器与解码器,检查最终重建与目标尺寸一致,再计算损失并反向。只修最后一层后能跑到下一层,不代表整个自编码器尺寸链已经正确。
在 CPU 重现尺寸链,再验证一种结构改法
下面保留原编码器的卷积、池化参数,打印到失败前的形状。随后示范把最后一层改成 (3,1);这仅适合任务允许宽轴已汇聚完的设计,不是整个自编码器的完整替代:
import torch
from torch import nn
layers = nn.ModuleList([
nn.Conv2d(1, 12, 3), nn.MaxPool2d((3, 5), stride=1),
nn.Conv2d(12, 20, 3), nn.MaxPool2d((1, 5), stride=1),
nn.Conv2d(20, 30, 3),
])
x = torch.randn(1, 1, 1025, 15)
widths = [x.shape[-1]]
for layer in layers:
x = layer(x)
widths.append(x.shape[-1])
assert widths == [15, 13, 9, 7, 3, 1]
assert x.shape == (1, 30, 1017, 1)
last = nn.Conv2d(30, 40, kernel_size=(3, 1))
encoded = last(x)
assert encoded.shape == (1, 40, 1015, 1)
encoded.square().mean().backward()
assert last.weight.grad is not None
print("width chain/encoded:", widths, encoded.shape)
若需要保留宽向邻域,应回到之前的池化核、stride 或 padding 设计,而非仅把最后卷积改窄。每一种方案改变的信息压缩与感受野不同,要与解码器的上采样顺序一起评估。
自编码器最终还要与目标重建尺寸一致。不要用广播或随意 view 让 loss 暂时能算;检查输出的 H、W 和通道数,使用任务定义的恢复方式。编码器前向成功、解码器尺寸正确、重建 loss 可反向是三个连续验收点。
参考:原始求助帖;技术依据:Conv2d(2.5)、MaxPool2d(2.5)、nn.Module(2.5)。