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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 10:36:16