#08 人工知能入門 DNN基礎

学習のループ——繰り返してどんどん賢くなる

学習は繰り返しで成り立つ

前回まで「フォワードパス → 損失計算 → バックプロパゲーション → 重み更新」の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(畳み込みニューラルネットワーク)に進みます。