Calculated output size (128x0x0):UNet 在池化前已只剩 1×1

简介: 该错误源于对1×1特征图执行无padding的2×2 MaxPool2d,导致输出尺寸坍缩为0×0。根本原因是空间维度不足,与损失函数无关。需通过前向hook定位尺寸瓶颈,结合合理padding、输入缩放或结构调整修复,同时确保编码器-解码器及skip连接尺寸对齐。(239字)

原帖用 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)。

相关文章
|
2天前
|
并行计算 PyTorch 算法框架/工具
CUBLAS_STATUS_ALLOC_FAILED when calling cublasCreate(handle):先区分显存不足和已有 CUDA 错误
Colab中`cublasCreate`失败非单纯batch过大所致,需区分环境异常与资源不足:重启运行时、验证CUDA可用性、用小矩阵测试基础算力,并对比`nvidia-smi`与`memory_summary`定位真实瓶颈。(239字)
|
2天前
|
缓存 Unix PyTorch
OSError: [Errno 24] Too many open files:两个 DataLoader 可以 zip,先查文件描述符
原帖双Loader并发读取ZIP导致“Too many open files”(Errno 24),实为文件描述符泄漏或生命周期管理不当,非ZIP不支持DataLoader。需排查Dataset中图像/HDF5/ZIP句柄是否及时释放,并优先采用单Loader配对Dataset保障数据一致性与资源可控性。(239字)
|
2天前
|
并行计算 PyTorch 算法框架/工具
Expected all tensors to be on the same device, cuda:0 and cpu:恢复训练时检查 SGD 动量
该问题源于断点续训时优化器状态(如SGD动量缓冲区)未与模型参数同设备,导致`optimizer.step()`中跨设备张量运算失败。前向/反向可正常执行,但动量更新报错“cuda:0 and cpu”。需检查并统一`param`、`grad`及`optimizer.state`中所有Tensor的设备。
|
2天前
|
并行计算 PyTorch Linux
libtorch_python.so: cannot open shared object file:文件缺失时先修复 torch 安装
该问题核心是 PyTorch 1.0.1.post2 安装不完整,`torch/lib/` 下缺失关键文件 `libtorch_python.so`,非环境变量(LD_LIBRARY_PATH)可解决。需先用 `importlib.util.find_spec` 定位真实安装路径,核对文件存在性;再通过 `pip show -f torch` 验证分发完整性。切勿混用版本或复制库文件。
|
2天前
|
并行计算 PyTorch Linux
RuntimeError: CUDA error: device-side assert triggered:Colab 先重启,再找首次断言
该文详解CUDA断言错误调试策略:强调先重启运行时、启用`CUDA_LAUNCH_BLOCKING=1`,用最小张量验证环境;区分“会话已坏”与新操作触发,主张逐段定位而非臆测标签越界,提供实用边界检查函数与验证流程。(239字)
|
2天前
|
并行计算 PyTorch 异构计算
can’t convert CUDA tensor to numpy:只取分类索引时直接用 torch.argmax
原帖因直接对CUDA张量调用`.data.numpy().argmax()`报错:“无法将CUDA张量转为NumPy”。正确做法是:在GPU上用`output.argmax(dim=1).item()`获取单图预测索引,避免全量拷贝,仅传回标量,高效且安全。(239字)
|
2天前
|
PyTorch 算法框架/工具 索引
ValueError: only one element tensors can be converted to Python scalars:张量列表先检查形状,再 stack
该文解析PyTorch中`list(tensor)`引发的`ValueError`根源:列表含多元素张量时,不可直接转Python标量。强调应通过`tensor.shape`或遍历打印各张量尺寸来查形状;同形张量用`torch.stack`(增维)而非`cat`或`item`;异形则保留原结构,避免强行转换。
|
2天前
|
数据可视化 PyTorch 算法框架/工具
only batches of spatial targets supported:三通道分割 one-hot 转为每像素类别编号
该报错源于PyTorch交叉熵要求标签为`[N, H, W]`(3D),但输入了`[N, 3, H, W]`(4D)掩码。需先验证三通道是否为互斥one-hot,再用`argmax(dim=1)`转为整型标签,并妥善处理全零未标注像素(设`ignore_index`),避免误判为背景类。(239字)
|
2天前
|
PyTorch 算法框架/工具 异构计算
Expected object of scalar type Float but got scalar type Double for argument #4 'mat1':NumPy 输入与 Linear 权重怎样统一类型
PyTorch中`RuntimeError: Expected Float but got Double`常因输入Tensor(float64)与模型权重(float32)类型不一致导致。关键在第一层Linear的输入与权重dtype需统一:可将数据转为float32(推荐),或模型整体升为float64。务必检查`tensor.dtype`而非数值显示,并确保`loss.backward()`前类型已对齐。(239字)
|
2天前
|
机器学习/深度学习 索引
The size of tensor a (133) must match tensor b (10):分类任务换 MSELoss 后先查标签含义
原帖网络输出133类logits,CrossEntropyLoss支持类别索引输入(如`[10]`),而MSELoss要求`outputs`与`target`形状严格匹配(如`[10,133]`)。报错因`target`为`[10]`,无法广播匹配`[10,133]`输出,本质是两类损失对标签格式约定不同。

热门文章

最新文章