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

为何使用DataLoader训练模型与手动分批次的训练结果不同?

两种鸢尾花模型训练方式结果差异的原因分析

你观察到的训练结果和速度差异,核心原因是DataLoader版本的训练代码存在循环嵌套错误,导致参数更新次数暴增,同时数据集shuffle策略也有差异,具体如下:

1. 循环嵌套导致迭代次数远超预期

手动分批次的训练逻辑是正确的:每个epoch遍历一次训练集的所有batch(120个训练样本,batch_size=5,共24个batch),每个batch完成一次参数更新,1个epoch总计24次参数更新。

而DataLoader版本的train函数里出现了多余的循环嵌套:

# 错误的双层循环
for start in bar:  # 这层循环遍历24个batch起始索引
    for X_train_batch, y_train_batch in train_dataloader:  # 这层循环又遍历整个训练集的24个batch
        # 参数更新操作

这导致每个epoch实际执行了24*24=576次参数更新,相当于手动版本24个epoch的训练量。更多的迭代次数让模型收敛得更充分(MSE更低),但也因为做了大量重复计算,运行速度远慢于手动版本。

2. 数据集shuffle策略的差异

  • 手动版本:仅在train_test_split时做了一次shuffle,后续每个epoch都是按固定顺序切分batch,样本顺序无变化。
  • DataLoader版本:设置了shuffle=True,每个epoch都会重新打乱数据集的样本顺序,让模型每次接触的样本组合更随机,这也会辅助模型更好地收敛,但这不是结果差异的核心原因。

修正后的DataLoader训练函数

去掉多余的外层循环,直接遍历DataLoader即可让训练逻辑和手动版本对齐:

def train(model, loss_fn, optimizer):
    model.train()
    # 直接用DataLoader作为tqdm的迭代对象
    with tqdm.tqdm(train_dataloader, unit="batch", mininterval=0, disable=False) as bar:
        bar.set_description(f"Epoch {epoch}")
        for X_train_batch, y_train_batch in bar:
            y_pred = model(X_train_batch)
            loss = loss_fn(y_pred, y_train_batch)
            optimizer.zero_grad()
            loss.backward()
            optimizer.step()
            bar.set_postfix(mse=float(loss))

修正后,每个epoch的参数更新次数和手动版本一致,训练速度和收敛效果会与手动版本接近。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 04:10:57