原帖用 68×68 输入,在后续 MaxPool2d 处把 1×1 特征图继续下采样,得到零尺寸:
RuntimeError: Given input size: (128x1x1). Calculated output size: (128x0x0). Output size is too small at /pytorch/torch/lib/THCUNN/generic/SpatialDilatedMaxPooling.cu:69
零尺寸来自空间链路,不是 BCE 目标
原题在 MaxPool2d 中失败,损失尚未执行。1×1 空间无法容纳无 padding 的 2×2 池化;但 UNetConvBlock 的完整定义缺失,所以不能只按“共有四次 pool”给出精确最小输入。先把每层卷积与池化的尺寸链打印出来。
128 是错误中记录的通道数;真正放不下的是空间维。无 padding 的 2×2 池化无法在 1×1 输入上产生有效输出,改变类别数不会修复它。
先给所有池化层加前向输入检查,确认空间尺寸在哪一步变小。inputs 为真实图像 batch:
import torch.nn as nn
print("josh050608")
print("input:", inputs.shape)
handles = []
def before_pool(layer, args):
print("pool input:", args[0].shape, "kernel:", layer.kernel_size, "stride:", layer.stride)
for layer in model.modules():
if isinstance(layer, nn.MaxPool2d):
handles.append(layer.register_forward_pre_hook(before_pool))
try:
model(inputs)
finally:
for handle in handles:
handle.remove()
再展开 UNetConvBlock 的卷积配置。若连续无 padding 的卷积先缩小空间,再多次池化,68×68 可能不足。原帖没有完整 block 实现,不能只按池化次数断定一个最小输入数字。
修复可以是使用足够大的有效输入、减少下采样层,或按网络设计给卷积合适 padding 以保留尺寸。不要临时删掉一个 pool 却不调整解码器和 skip connection 的对齐规则;ceil_mode 也不能普遍修复所有卷积/拼接尺寸问题。
原帖还称输入一通道,而展示的首 block 参数为 4,应同时核对实际运行模型,避免粘贴版本不同。损失只有在前向成功后才参与,不是当前零尺寸的原因。
验证完整编码/解码链、跳接尺寸以及最终输出与掩码的空间大小,再进行反向。
用最小池化例子证明边界
下面 CPU 示例直接展示 1×1 失败与 2×2 通过。它不构造原 UNet,仅验证当前错误最直接的算子约束:
import torch
from torch import nn
pool = nn.MaxPool2d(2, stride=2)
too_small = torch.ones(1, 128, 1, 1)
try:
pool(too_small)
except RuntimeError as exc:
print("1x1 rejected:", exc)
valid = torch.ones(1, 128, 2, 2, requires_grad=True)
pooled = pool(valid)
assert pooled.shape == (1, 128, 1, 1)
pooled.sum().backward()
assert valid.grad is not None
print("valid input/output:", valid.shape, pooled.shape)
真实网络里每个无 padding 的 3×3 卷积都会缩小两侧空间,再叠加池化,下采样前可能比单看输入尺寸预想得更小。使用 hook 定位首次接近边界的层,连同 block 内部参数记录,而不只看整个编码器的名称。
选择扩大输入、减少层数或调整 padding 时,要同步验证 skip connection 与解码器输出。ceil_mode 可能改变某次池化取整,无法保证后续卷积和跳接全部可行;临时删一层也可能破坏通道与分辨率关系。
原题还存在描述一通道与首 block 参数 4 不一致,先确认实际运行模型。完成标准是编码器、解码器与目标掩码尺寸一致,并能计算损失与反向;修到不再产生 0×0 只是第一步。
参考:原始求助帖;技术依据:MaxPool2d(2.5)、Conv2d(2.5)、nn.Module(2.5)。