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

机器学习训练中分数Steps是否通常向下取整?相关实践咨询

关于Epoch、Steps与Batch Size的实际训练处理问题

问题背景

在训练机器学习模型时,对epoch、steps等核心训练概念存在困惑,通过关联公式计算后得到分数形式的steps_per_epoch(如10000样本、batch size=32时算出312.5),对实际训练中的具体处理方式产生疑问,包括分数steps的取整逻辑、样本是否会被跳过,以及主流框架的默认行为。

示例计算代码:

total_samples = 10000  # 数据集中的样本总数
batch_size = 32        # 计划使用的batch size
epochs = 10            # 计划训练的epoch数

steps_per_epoch = total_samples / batch_size
total_steps = (epochs * total_samples) / batch_size

print(f"Steps per epoch: {steps_per_epoch}")
print(f"Total steps: {total_steps}")

输出结果:

Steps per epoch: 312.5
Total steps: 3125.0

疑问解答

1. 实际操作中分数steps是否通常向下取整?

不是绝对的向下取整,主流有两种处理方式:

  • 直接向下取整:只处理整数部分的完整batch(比如312个);
  • 保留最后一个不完整batch:处理完312个完整batch后,再用剩余的16个样本组成小batch继续训练。

具体选择取决于训练需求:如果追求batch大小完全统一,可能会跳过剩余样本;如果希望充分利用所有数据,就会保留最后一个小batch。

2. 若进行取整,是否意味着每轮训练会跳过部分样本?

如果选择向下取整且丢弃剩余样本,确实会跳过部分样本(示例中每轮跳过16个)。但多数场景下不会直接跳过,常用替代方案有两种:

  • 处理最后一个小batch:即使batch size小于设定值,仍用这些样本更新模型;
  • 样本填充:每轮epoch洗牌后,补充少量重复样本凑成整数个batch,避免出现小batch。

3. 主流机器学习框架如何处理这种情况?

  • TensorFlow/Keras:默认会处理最后一个不完整batch。若手动设置steps_per_epoch为整数,则按设定步数执行;若不设置,框架会自动遍历所有样本。也可通过drop_remainder=True参数丢弃最后一个不完整batch。
  • PyTorch:DataLoader默认保留最后一个不完整batch,可通过drop_last=True参数丢弃剩余样本。训练循环需手动遍历DataLoader,默认会处理所有batch(包括小batch)。
  • Scikit-learn:大部分模型内部会自动遍历所有样本,处理batch时会考虑剩余样本,不会直接跳过。

实操示例(PyTorch)

新手实现训练循环时,推荐优先保留所有样本,示例代码如下:

import torch
from torch.utils.data import DataLoader, TensorDataset

# 构造示例数据集
X = torch.randn(10000, 10)
y = torch.randint(0, 2, (10000,))
dataset = TensorDataset(X, y)
# 默认保留最后一个不完整batch,shuffle=True保证每轮样本顺序不同
dataloader = DataLoader(dataset, batch_size=32, shuffle=True)

model = torch.nn.Linear(10, 2)
optimizer = torch.optim.SGD(model.parameters(), lr=0.01)
loss_fn = torch.nn.CrossEntropyLoss()

for epoch in range(10):
    model.train()
    total_loss = 0.0
    # 遍历所有batch,包括最后一个16样本的小batch
    for X_batch, y_batch in dataloader:
        optimizer.zero_grad()
        outputs = model(X_batch)
        loss = loss_fn(outputs, y_batch)
        loss.backward()
        optimizer.step()
        total_loss += loss.item()
    print(f"Epoch {epoch+1}, Average Loss: {total_loss/len(dataloader):.4f}")

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 21:13:29