4. Batch Size基础

大家好,我是你们的老朋友。今天咱们来聊聊 Batch Size 这个基础但极其关键的概念。

说实话,我见过太多同学在调参时,把 Batch Size 当成一个「随便填个 32 或 64 就行」的参数。结果呢?要么显存爆了,要么模型收敛慢得像蜗牛。今天我就把这块掰开揉碎了讲清楚。

4.1 Batch Size 到底是什么?

Batch Size,中文叫「批大小」。说白了,就是每次参数更新前,你一次性喂给 GPU 的样本数量。

举个例子:

  • 你有 10000 张猫狗图片
  • 你设置 Batch Size = 64
  • 那么每次迭代,GPU 会同时处理 64 张图片
  • 处理完这 64 张,算一次梯度,更新一次参数
  • 全部 10000 张跑完,需要 10000 / 64 ≈ 157 次迭代

这 157 次迭代,就是 1 个 epoch(完整遍历一次数据集)。

核心公式:

每次迭代的样本数 = Batch Size

每个 epoch 的迭代次数 = 总样本数 / Batch Size

我刚开始做训练时,总把 Batch Size 和「学习率」搞混。后来我给自己编了个口诀:Batch Size 管「一次看多少」,学习率管「一次改多大」。这样就好记多了。

4.2 Batch Size 对训练的影响

Batch Size 的影响,比你想象的要大得多。它不只是个「显存消耗量」的问题。

4.2.1 对收敛速度的影响

很多人以为 Batch Size 越大,训练越快。嗯,这话只说对了一半。

  • 小 Batch Size(比如 8、16): 梯度噪声大,每次更新方向不稳定。但正因为有噪声,反而容易跳出局部最优。收敛曲线看起来「抖」,但最终精度可能更高。
  • 大 Batch Size(比如 256、512): 梯度估计更准,每次更新方向稳定。但容易陷入尖锐的局部极小值,泛化能力可能下降。

我在项目中遇到过一件事:用 Batch Size = 32 训练一个图像分类模型,验证集精度 92%。换成 Batch Size = 256 后,精度掉到了 88%。我当时百思不得其解,后来发现是 Batch Size 太大,模型「过拟合」了训练集的噪声模式。

我的经验:

对于大多数视觉任务,Batch Size 在 32-128 之间是个安全区间。太小(< 8)梯度噪声太大,太大(> 512)需要配合学习率 warmup 策略。

4.2.2 对梯度质量的影响

为什么会这样?我们来拆解一下。

小 Batch Size 的梯度,相当于用少量样本估计全量数据的梯度。这就像你只问了 10 个人的意见就做决策——可能不准,但灵活。大 Batch Size 相当于问了 1000 个人——更准,但可能错过一些「少数派」的好方向。

我记得有一篇经典论文提到:Batch Size 与学习率之间存在线性缩放关系。也就是说,你把 Batch Size 翻倍,学习率也应该翻倍,才能保持相似的训练动态。

但注意,这个规律只在「一定范围内」成立。我试过把 Batch Size 从 64 提到 1024,学习率也对应提高,结果模型直接炸了——梯度爆炸。所以,线性缩放规则不是万能的。

4.3 Batch Size 与显存的关系

这部分是实战中最容易踩坑的地方。咱们直接上公式:

显存占用 ≈ Batch Size × (输入数据大小 + 中间激活值大小 + 参数梯度大小)

说白了,Batch Size 每翻一倍,显存占用也差不多翻一倍。但这里有个很多人忽略的点:中间激活值。

你想想看,每次前向传播,每一层的输出(激活值)都要保存在显存里,因为反向传播时要用到。Batch Size 越大,同时保存的激活值就越多。

举个例子:

Batch Size 输入数据 (MB) 中间激活 (MB) 参数+梯度 (MB) 总显存 (MB)
32 12 180 50 242
64 24 360 50 434
128 48 720 50 818
256 96 1440 50 1586

看到没?中间激活值才是显存消耗的大头。参数和梯度反而只占一小部分。

避坑指南:

我曾经在 8GB 显存的卡上,试图用 Batch Size = 256 训练一个 ResNet-50。结果显存直接爆了。后来我算了一下,中间激活值就占了 1.4GB,加上其他开销,8GB 根本不够用。

所以,调 Batch Size 前,先算算你的显存够不够。不够的话,要么减小 Batch Size,要么用梯度累积(后面会讲)。

4.4 知识体系总览

为了让你更直观地理解 Batch Size 在整个训练流程中的位置,我画了一张图:

Batch Size 知识体系 Batch Size 定义:每次迭代的样本数 对训练的影响:收敛速度 + 梯度质量 显存关系:线性增长,激活值是大头 小 Batch:噪声大,易跳出局部最优 中 Batch:平衡之选,32-128 推荐 大 Batch:梯度准,需配合 warmup 核心原则:显存允许范围内,选择能稳定收敛的最大 Batch Size

这张图把 Batch Size 的三个维度串起来了。你从中间的核心节点出发,往左看是定义,往右看是影响,往下看是显存关系。最下面三个子节点,是我对不同 Batch Size 区间的总结。

4.5 实战建议

说了这么多,最后给你几条实在的建议:

  1. 先看显存,再定 Batch Size。 用 nvidia-smi 看看你的卡还剩多少显存,然后从 32 开始试。爆了就减半,不爆就翻倍。
  2. 小 Batch 配小学习率,大 Batch 配大学习率。 但别死板,线性缩放只是起点,实际要调。
  3. 如果显存不够,别硬撑。 用梯度累积(gradient accumulation)模拟大 Batch Size。比如你 Batch Size 想设 128,但显存只够 32,那就累积 4 次梯度再更新。
  4. 注意中间激活值。 有些框架(比如 PyTorch)可以用 checkpointing 技术,用计算换显存。但会增加训练时间,是个 trade-off。

一个小技巧:

我习惯在训练脚本里加一段显存预估代码。每次改 Batch Size 前,先跑一个 mini-batch 看看显存占用,心里有个数。这样就不会在训练到一半时突然 OOM(Out of Memory)了。