本文へスキップ
BecomeCoder

PyTorchコース · 第2章 numpyで「学習」を実装する · レッスン7

学習率とエポック ― うまく学習させるコツ

ブラウザで完結

導入

同じモデル・同じデータでも、学習率エポック数の選び方で結果は大きく変わります。ここは初心者が最初につまずく所なので、実際に動かして感覚を掴みます。

説明

  • エポック(epoch):データ全体を使った学習を1周すること。エポック数=輪を何周回すか。
  • 学習率(lr):1回の更新の歩幅。
flowchart LR
  a["lrが小さすぎ<br/>なかなか谷底に<br/>着かない(遅い)"]
  b["lrがちょうど良い<br/>スムーズに収束"]
  c["lrが大きすぎ<br/>行き過ぎて発散<br/>(損失が増える)"]

コツは「まず損失が下がり続ける範囲で、できるだけ大きめの lr を選ぶ」こと。下がらず暴れるなら lr を小さく、下がるが遅いなら lr を大きく、エポックを増やします。

やってみよう

レッスン5の線形回帰を、複数の学習率で回して損失の推移を比べます。lr=0.001(遅い)、lr=0.05(良い)、lr=0.3(発散気味)で、最終損失がどう変わるか観察しましょう。

import numpy as np

x = np.array([0.0, 1.0, 2.0, 3.0, 4.0])
y = np.array([1.1, 2.9, 5.2, 6.8, 9.1])
n = len(x)

def train(lr, epochs=200):
    w, b = 0.0, 0.0
    for _ in range(epochs):
        error = (w * x + b) - y
        w -= lr * (2 / n) * np.sum(error * x)
        b -= lr * (2 / n) * np.sum(error)
    return np.mean(((w * x + b) - y) ** 2)

for lr in [0.001, 0.05, 0.3]:
    print(f"lr={lr:<6}:  200エポック後の損失 = {train(lr):.4f}")

演習

lr=0.001 のとき、エポック数を 200 から 5000 に増やすと損失はどうなるでしょうか。train(0.001, epochs=5000) を呼んで確かめましょう。

ヒント1を見る

print(train(0.001, epochs=5000)) を追加します。

ヒント2を見る

小さい lr は「一歩が小さい」だけなので、歩数(エポック)を増やせばちゃんと谷底に近づきます。ただし時間はかかります。

まとめ

  • エポック=データを何周学習するか。学習率=1歩の大きさ。
  • 「損失が下がり続ける範囲で大きめの lr」が基本の勘。
  • lr が小さいなら、エポックを増やせば補える(ただし遅い)。この2つは学習の最重要ツマミ。

実際に動かしてみよう

本文のサンプルや演習のコードは、コードブロック右上の「コピー」ボタンでコピーして、下のエディタに貼り付ければそのまま実行できます。

Python — ライブラリ付きで実行(Pyodide)

numpy / pandas / matplotlib が使える本物のPython(Pyodide)を読み込みます。初回のみ読み込みに少し時間がかかります(以降はブラウザにキャッシュされます)。
スクロールして表示された時点でも自動で読み込まれます。