You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PyTorch训练不同尺寸图像数据集报张量尺寸不匹配的解决方法

问题根因

报错核心原因:PyTorch默认DataLoader的default_collate拼接函数会将同批次所有张量沿batch维度堆叠,强制要求同批次张量尺寸完全一致。你的数据集图像尺寸从[3, 300, 535]到[3, 1080, 1920]不等,直接堆叠必然触发尺寸不匹配的RuntimeError。
调整batch size、kernel size完全解决不了这个问题:batch size仅控制单批次样本数量,kernel size是卷积操作的窗口大小,二者都不能让不同尺寸的图像自动对齐。此外你当前的神经网络存在通道数不匹配、卷积核尺寸过大的硬伤,就算解决拼接问题也无法正常运行。

可落地解决方案

方案1:统一输入尺寸(最通用,90%以上视觉任务推荐使用)

通过预处理变换把所有图像缩放到固定尺寸,是最简单、训练效率最高的方案:

  • 第一步:给数据集传入标准化预处理变换,修改主文件里的数据集初始化代码
from torchvision import transforms

# 定义预处理流水线:统一缩放到224*224,转张量、归一化
base_transform = transforms.Compose([
    transforms.ToPILImage(),  # 适配read_image读取的uint8张量格式
    transforms.Resize((224, 224)),  # 所有图像强制对齐到224*224,可根据任务调整尺寸
    transforms.ToTensor(),
    transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])
])

# 初始化数据集时传入transform
test_dataset = dataset.csHeadBody(
    csv_file="images\\test_labels.csv",
    root_dir="images\\test",
    transform=base_transform
)
train_dataset = dataset.csHeadBody(
    csv_file="images\\train_labels.csv",
    root_dir="images\\train",
    transform=base_transform
)
  • 第二步:修复神经网络结构错误,替换原有不合理的卷积、全连接层配置
import torch.nn.functional as F
import torch.nn as nn
import torch

class Net(nn.Module):
    def __init__(self, num_classes=10):
        super().__init__()
        self.conv1 = nn.Conv2d(3, 16, kernel_size=3, padding=1)
        self.pool = nn.MaxPool2d(2, 2)
        self.conv2 = nn.Conv2d(16, 32, kernel_size=3, padding=1)
        self.conv3 = nn.Conv2d(32, 64, kernel_size=3, padding=1)
        # 224*224输入经过3次2*2池化后尺寸为28*28,通道数64
        self.fc1 = nn.Linear(64 * 28 * 28, 120)
        self.fc2 = nn.Linear(120, 84)
        self.fc3 = nn.Linear(84, num_classes)

    def forward(self, x):
        x = self.pool(F.relu(self.conv1(x)))
        x = self.pool(F.relu(self.conv2(x)))
        x = self.pool(F.relu(self.conv3(x)))
        x = torch.flatten(x, 1)
        x = F.relu(self.fc1(x))
        x = F.relu(self.fc2(x))
        x = self.fc3(x)
        return x
  • 补充:你的数据集定义文件缺少必要依赖导入,需要在文件开头加上以下代码,否则初始化时会报名称错误:
import os
import pandas as pd
from torchvision.io import read_image
from torch.utils.data import Dataset

方案2:自定义批次拼接逻辑+自适应池化(不想强制拉伸图像时使用)

如果担心强制resize破坏图像宽高比,可以自定义collate_fn,配合网络中的自适应池化层实现变尺寸训练:

  • 第一步:自定义collate函数,初始化DataLoader时传入
from torchvision import transforms

def variable_size_collate(batch):
    imgs = []
    labels = []
    for img, label in batch:
        # 短边对齐到256像素,保持原始宽高比
        _, h, w = img.shape
        scale = 256 / min(h, w)
        new_h = int(h * scale)
        new_w = int(w * scale)
        img = transforms.functional.resize(img, (new_h, new_w))
        imgs.append(img)
        labels.append(label)
    labels = torch.tensor(labels, dtype=torch.long)
    return imgs, labels

# 初始化DataLoader时指定自定义拼接函数
train_loader = DataLoader(
    dataset=train_dataset,
    batch_size=batch_size,
    shuffle=True,
    collate_fn=variable_size_collate
)
test_loader = DataLoader(
    dataset=test_dataset,
    batch_size=batch_size,
    shuffle=True,
    collate_fn=variable_size_collate
)
  • 第二步:修改网络结构,加入自适应池化层统一特征图尺寸
import torch.nn.functional as F
import torch.nn as nn
import torch

class Net(nn.Module):
    def __init__(self, num_classes=10):
        super().__init__()
        self.conv1 = nn.Conv2d(3, 16, kernel_size=3, padding=1)
        self.pool = nn.MaxPool2d(2, 2)
        self.conv2 = nn.Conv2d(16, 32, kernel_size=3, padding=1)
        self.conv3 = nn.Conv2d(32, 64, kernel_size=3, padding=1)
        # 自适应池化:无论输入特征图尺寸多大,统一输出7*7大小
        self.adaptive_pool = nn.AdaptiveAvgPool2d((7,7))
        self.fc1 = nn.Linear(64 * 7 * 7, 120)
        self.fc2 = nn.Linear(120, 84)
        self.fc3 = nn.Linear(84, num_classes)

    def forward(self, x):
        batch_features = []
        # 逐张提取卷积特征
        for img in x:
            img = img.unsqueeze(0) # 补充单样本batch维度
            feat = self.pool(F.relu(self.conv1(img)))
            feat = self.pool(F.relu(self.conv2(feat)))
            feat = self.pool(F.relu(self.conv3(feat)))
            feat = self.adaptive_pool(feat)
            batch_features.append(feat)
        # 所有特征对齐后再拼接成batch
        x = torch.cat(batch_features, dim=0)
        x = torch.flatten(x, 1)
        x = F.relu(self.fc1(x))
        x = F.relu(self.fc2(x))
        x = self.fc3(x)
        return x

注意:方案2训练速度比方案1慢30%以上,因为需要逐张做卷积前向,没有批量计算的优势,非必要优先选方案1。

内容的提问来源于stack exchange,提问作者IEatGemstones

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 21:27:19