導入
同じモデル・同じデータでも、学習率とエポック数の選び方で結果は大きく変わります。ここは初心者が最初につまずく所なので、実際に動かして感覚を掴みます。
説明
- エポック(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つは学習の最重要ツマミ。