学習のループ——繰り返してどんどん賢くなる
学習は繰り返しで成り立つ
前回まで「フォワードパス → 損失計算 → バックプロパゲーション → 重み更新」の1サイクルを学びました。でも実際には、このサイクルを何千・何万回と繰り返すことで、ネットワークはどんどん賢くなっていきます。
今回はその「繰り返し」を管理するための重要な概念を整理します。
バッチとは
データを1件ずつ処理する方法もありますが、実際には複数のデータをまとめて処理するバッチ(Batch) という単位を使います。
全データ: 10,000件の画像
↓
バッチサイズ = 32 に分割
↓
1バッチ目(1〜32枚) → 損失計算 → 重み更新
2バッチ目(33〜64枚) → 損失計算 → 重み更新
...
312バッチ目(9,985〜10,000枚) → 損失計算 → 重み更新
| 方法 | 内容 | 特徴 |
|---|---|---|
| バッチ学習 | 全データを一度に処理 | 安定するが遅い・メモリ大量消費 |
| オンライン学習 | 1件ずつ処理 | 速いが不安定 |
| ミニバッチ学習 | 数十〜数百件ずつ処理 | バランスが良い(実際はほぼこれ) |
バッチサイズは32や64が定番です。GPUの並列処理能力を活かせるサイズが選ばれます。
エポックとは
全データを1回通り終えることを1エポック(Epoch) と言います。
エポック1: 全10,000件を処理(312バッチ)→ 重みが更新される
エポック2: 全10,000件をシャッフルして再処理 → さらに改善
エポック3: 同様
...
エポック50: ある程度収束する
「何エポック学習するか」はハイパーパラメータ(人間が決める設定値)の1つです。エポック数が少なすぎると学習不足、多すぎると過学習(後述)になることがあります。
学習率の重要性
学習率(Learning Rate)は前回も触れましたが、学習ループの中でとても重要な設定値です。
大きすぎる学習率: ドンドン進みすぎて谷を飛び越える
小さすぎる学習率: 亀のように遅い、局所解にはまる
適切な学習率: 安定してゆっくり谷に降りていく
学習率スケジューリング という技法では、学習の途中で学習率を変えます:
最初は大きい学習率 → 大まかに良い場所を見つける
後半は小さい学習率 → 細かく最適な場所に近づく
損失の推移を見る
学習が進むにつれて損失がどう変わるかを学習曲線で確認します。
損失
↑
1.0 |○
| ○
0.5 | ○ ○
| ○ ○ ○ ○ ─ ─
0.1 |
+──────────────────→ エポック
1 5 10 20 50
正常な学習:エポックが進むにつれてスムーズに損失が下がる。
過学習とは
過学習(Overfitting)とは「訓練データには完璧に正解できるが、新しいデータには弱い」状態です。
学習データを暗記してしまっているので、未知のデータに対応できません。
損失
↑
| ─── 訓練データの損失(下がり続ける)
| ─ ─ テストデータの損失
| /
| ─ ─/
| ── ←ここから過学習が始まる
+──────────────────→ エポック
1 5 10 20 50
訓練データの損失が下がり続けるのに、テストデータの損失が途中から上がり始める——これが過学習のサインです。
訓練・検証・テストデータの役割
過学習を防ぐために、データを3つに分けて使います。
全データ(例: 10,000件)
├── 訓練データ(70%: 7,000件) → 重みの更新に使う
├── 検証データ(15%: 1,500件) → 学習中に評価(過学習チェック)
└── テストデータ(15%: 1,500件) → 最終的な性能評価
検証データ(Validation Data) は学習には使わず、「今の重みが汎用的かどうか」を確認するために使います。検証データの損失が上がり始めたら学習を止める(早期終了、Early Stopping)のが定石です。
過学習の対策
| 対策 | 内容 |
|---|---|
| データ拡張(Data Augmentation) | 画像を回転・反転して訓練データを水増し |
| ドロップアウト(Dropout) | 学習中に一部のニューロンをランダムに無効化 |
| L2正則化(Weight Decay) | 重みが大きくなりすぎないようにペナルティを加える |
| 早期終了(Early Stopping) | 検証損失が上がり始めたら学習を止める |
学習ループの全体像
# 学習ループの擬似コード
for epoch in range(num_epochs):
# ミニバッチで訓練
for batch in train_dataloader:
入力, 正解 = batch
予測値 = model(入力) # 順伝播
損失 = loss_fn(予測値, 正解) # 損失計算
損失.backward() # 逆伝播
optimizer.step() # 重み更新
optimizer.zero_grad() # 勾配をリセット
# 検証データで評価(過学習チェック)
val_loss = evaluate(model, val_dataloader)
print(f"Epoch {epoch}: val_loss = {val_loss:.4f}")
まとめ
- バッチは複数データをまとめて処理する単位。ミニバッチ(32〜64件)が実用的
- エポックは全データを1周すること。何エポック学習するかは人間が設定する
- 学習率は重み更新の大きさ。大きすぎても小さすぎても問題
- 過学習は「訓練データを暗記してしまう」現象。検証データで早期検知する
- 学習 = 正解を見ながら重みをバッチ・エポック単位で繰り返し修正すること
これでDNN基礎シリーズは完了です。ニューラルネットワークの仕組みから学習の全体像まで、基礎がひと通り揃いました。次のシリーズでは画像認識に特化したCNN(畳み込みニューラルネットワーク)に進みます。