Batch Size
バッチサイズとは、重みを1回更新するごとにモデルが処理する学習例の数です。GPUメモリの使用量、学習速度、勾配ノイズを左右します。
バッチサイズとは、モデルがモデルの重みを更新する前に、まとめて処理する学習サンプルの数です。学習データセット全体を一度にニューラルネットワークへ入力するのではなく、学習データをバッチに分割します。各バッチについて、モデルが予測を行い、損失関数が予測を評価し、誤差逆伝播で勾配を計算し、オプティマイザーが1ステップ進みます。バッチサイズは、学習に必要なGPUメモリ量、各エポックの実行速度、勾配推定のノイズの大きさという3つを同時に左右するハイパーパラメーターです。
バッチサイズが学習に与える影響#
各バッチは、最適化アルゴリズムにデータセット全体に対する勾配の推定値を与え、バッチが大きいほど推定値の精度が上がります。以下のPyTorchのコードでは、各サイズのランダムなバッチを多数使い、サンプルごとの勾配を平均することで、この精度を直接測定します。
import torch
torch.manual_seed(0)
# Per-sample gradients of a squared-error loss for 10,000 samples
x = torch.randn(10_000)
y = 2 * x + torch.randn(10_000)
w = torch.tensor(0.0)
per_sample_grads = 2 * (w * x - y) * x
# Estimate the gradient from 1,000 random batches at each batch size
for batch_size in (8, 64, 512):
idx = torch.randint(0, len(x), (1000, batch_size))
batch_grads = per_sample_grads[idx].mean(dim=1)
print(f"batch {batch_size:3d}: gradient std {batch_grads.std():.3f}")勾配推定値のばらつきは、バッチサイズ8の2.248から、64では0.771、512では0.267へと減少します。バッチサイズを8倍にするごとにノイズは約2.9分の1になり、独立したサンプルを平均するときの特性である√8に近い値になります。
このノイズが小さなバッチと大きなバッチのトレードオフを左右します。
- 小さなバッチ(例: 8~32): 更新のノイズが大きく、1エポックあたりのステップ数も多くなります。このノイズは弱い正則化として働き、多くの場合、確率的勾配降下法(SGD)の汎化性能を高めます。また、小さなバッチは比較的低性能なハードウェアでも処理できますが、GPUが部分的にアイドル状態になるため、各エポックに時間がかかります。
- 大きなバッチ(例: 256以上): 勾配が滑らかになり、1エポックあたりのステップ数が減り、ハードウェア使用率が高くなります。Keskar氏らが示したように、非常に大きなバッチでは汎化性能が低い鋭い極小値に収束しやすくなります。また、1エポックあたりのステップ数が少ないため、それに比例して高い学習率とウォームアップ期間が必要です。この線形スケーリング則を用いて、Goyal氏らは256基のGPUにまたがるバッチサイズ8,192で、1時間でImageNetのResNet-50を学習し、小さなバッチでの学習と同等の精度を達成しました。
メモリ制限と勾配蓄積#
GPUメモリには、モデルの重み、オプティマイザーの状態、誤差逆伝播で必要となる中間活性化値を保持する必要があります。活性化値のメモリ使用量は、バッチサイズと画像解像度に比例して増加します。バッチがメモリに収まらない場合、学習はメモリ不足(OOM)エラーで停止します。混合精度学習では活性化値のメモリ使用量をおよそ半分にでき、勾配蓄積では、複数の小さなバッチの勾配を重み更新の前に合算し、より大きな実効バッチサイズを実現します。
Ultralytics YOLOのトレーニングにはこの仕組みが組み込まれており、約64枚、つまり公称バッチサイズnbs分の画像を処理するまで勾配を蓄積し、ウォームアップ後はデフォルトのbatch=16により4バッチごとに1回重みを更新します。batch=-1を設定するとAutoBatchが実行され、空きCUDAメモリの約60%に収まる最大のバッチサイズを選択し、CPUとApple MPSデバイスではバッチサイズ16にフォールバックします。
from ultralytics import YOLO
# 事前学習済みYOLO26nモデルを読み込みます
model = YOLO("yolo26n.pt")
# batch=-1を指定すると、AutoBatchが利用可能なGPUメモリに基づいてバッチサイズを選択します
# 固定サイズには整数(batch=16)を、メモリ使用率には浮動小数点数(batch=0.70)を指定します
results = model.train(data="coco8.yaml", epochs=5, batch=-1)学習開始前に、AutoBatchはバッチサイズ1~16(16 GB以上のGPUでは最大64)でYOLO26モデルを実行し、測定したメモリ使用量に直線を当てはめます。その直線から、目標の使用率に達するバッチサイズを求めます。
バッチサイズと関連用語の比較#
- エポックとイテレーション: エポックはデータセット全体を1回処理すること、イテレーションは重みを1回更新することです。1エポックあたりのイテレーション数は、データセットのサイズをバッチサイズで割って切り上げた値です。そのため、画像1,000枚をバッチサイズ100で処理すると、イテレーション数は10になります。
- ミニバッチ: ディープラーニングに関する多くの文献では、バッチと同義です。厳密には、バッチ勾配降下法では更新ごとにデータセット全体を使用し、確率的勾配降下法ではサンプルを1つ使用します。ミニバッチ勾配降下法はその中間に位置し、現代のほぼすべてのネットワークがこの方法で学習します。
- バッチ正規化: 現在のバッチの平均と分散で活性化値を正規化する層であり、バッチサイズが非常に小さいと統計量の信頼性が低下します。グループ正規化はこの依存性を避けられ、バッチサイズ2のImageNetにおけるResNet-50では、バッチ正規化よりエラー率を10.6%低減したと報告されています。
- 推論バッチサイズ: デプロイ時のバッチ処理は、推論レイテンシとスループットのトレードオフになります。複数のカメラからのフレームをまとめると、1秒あたりの処理画像数は増えますが、各フレームはバッチがそろうまで待機します。










