PyTorch训练自编码器出现输入目标尺寸不匹配问题排查
问题核心原因
当前报错无法仅靠封装DataLoader解决,核心错误在训练循环的逻辑,直接触发了维度不匹配:
- 你写的
for i, data in enumerate(features)是逐行遍历全量特征张量,每次取出的data是单条样本,形状为[51],经模型前向传播得到的outputs形状同样是[51] - 计算损失时你传入的目标是整个全量特征集
features,形状为[116247, 51],和单条输出的形状不匹配,触发PyTorch广播机制,计算出的损失完全错误,根本没有实现自编码器“重构输入”的训练目标。
封装DataLoader是PyTorch批量训练的标准规范,可以大幅提升训练速度、稳定梯度更新,但属于优化手段,不是修复当前错误的核心。
修正步骤
- 先修正训练逻辑:自编码器的训练目标是让输出重构对应输入,计算损失时必须保证输出和目标是同一样本/同一批次的配对数据,不能拿全量数据集当单样本的标签。
- 用
TensorDataset+DataLoader封装数据,实现批量加载,替代原来的逐样本遍历。 - 调整不合理的超参数:原代码设置的学习率
lr=0.1过大,很容易导致训练震荡不收敛,建议初始值设为1e-3。
修正后的可运行代码如下:
import torch import torch.nn as nn import torch.optim as optim from torch.utils.data import TensorDataset, DataLoader import numpy as np # 模型结构保持原有定义即可 class denoising_model(nn.Module): def __init__(self): super().__init__() self.encoder=nn.Sequential( nn.Linear(51,30), nn.ReLU(), nn.Linear(30,20), nn.ReLU(), nn.Linear(20,10), nn.ReLU(), nn.Linear(10,3) ) self.decoder=nn.Sequential( nn.Linear(3,10), nn.ReLU(), nn.Linear(10,20), nn.ReLU(), nn.Linear(20,30), nn.ReLU(), nn.Linear(30,51), nn.Tanh() ) def forward(self, x): encoded=self.encoder(x) decoded=self.decoder(encoded) return decoded net = denoising_model() criterion = nn.MSELoss() optimizer = optim.Adam(net.parameters(), lr=1e-3) # 数据预处理 completed_data_copy = completed_data_copy.astype(np.float32) features = torch.tensor(completed_data_copy.values) features = features[torch.randperm(features.size()[0])] # 全局打乱样本 # 封装数据集:自编码器输入和重构目标都是特征本身 dataset = TensorDataset(features, features) # 封装DataLoader,设置批量大小,可根据显存调整batch_size dataloader = DataLoader(dataset, batch_size=256, shuffle=False) # 修正后的训练循环 for epoch in range(10): # 原代码仅训练1轮,可根据收敛情况调整轮数 running_loss = 0.0 for i, (batch_inputs, batch_targets) in enumerate(dataloader): optimizer.zero_grad() outputs = net(batch_inputs) # 同批次输出和对应目标计算损失,形状完全匹配,不会触发维度警告 loss = criterion(outputs, batch_targets) loss.backward() optimizer.step() running_loss += loss.item() if i % 100 == 99: print(f'[{epoch + 1}, {i + 1:5d}] loss: {running_loss / 100:.6f}') running_loss = 0.0 print('Finished Training')
补充说明
- 如果要训练去噪自编码器,只需要在训练时给
batch_inputs添加随机噪声(比如高斯噪声、随机置零掩码),batch_targets保留原始无噪声样本即可,符合去噪训练目标。 - 批量训练相比原代码的逐样本训练,速度可提升数十倍,梯度更新更稳定,是PyTorch模型训练的标准写法。
内容的提问来源于stack exchange,提问作者Nicholas Taylor
相关产品推荐
相关产品推荐

