損失のグラフは、中学で習った放物線
前のレッスンでは、勾配降下法を「足元の傾きだけを頼りに谷底を目指す方法」として説明しました。このレッスンでは、その「傾き」を、中学数学だけを使って実際に計算してみます。
話を分かりやすくするため、データは次の2件だけにします。
x = 1 x = 1 x = 1 のとき y = 2 y = 2 y = 2
x = 2 x = 2 x = 2 のとき y = 4 y = 4 y = 4
モデルは y = a x y = ax y = a x とします(切片 b b b は0に固定して、a a a だけを動かして考えます)。a a a の値を変えると、損失(平均二乗誤差)は次のように変わります。
損失 = ( a × 1 − 2 ) 2 + ( a × 2 − 4 ) 2 2 \text{損失} = \frac{(a \times 1 - 2)^2 + (a \times 2 - 4)^2}{2} 損失 = 2 ( a × 1 − 2 ) 2 + ( a × 2 − 4 ) 2
a = 2 a = 2 a = 2 のとき予測がぴったり当たり、損失は0になります。そこから左右に離れるほど、損失は同じように大きくなっています(a = 1 a = 1 a = 1 と a = 3 a = 3 a = 3 、a = 0 a = 0 a = 0 と a = 4 a = 4 a = 4 で損失が同じです)。
実はこの式は、中学3年で習う展開を使うと 2.5 ( a − 2 ) 2 2.5(a - 2)^2 2.5 ( a − 2 ) 2 と同じです。( 2 a − 4 ) 2 = 4 ( a − 2 ) 2 (2a - 4)^2 = 4(a - 2)^2 ( 2 a − 4 ) 2 = 4 ( a − 2 ) 2 なので、( a − 2 ) 2 + 4 ( a − 2 ) 2 = 5 ( a − 2 ) 2 (a - 2)^2 + 4(a - 2)^2 = 5(a - 2)^2 ( a − 2 ) 2 + 4 ( a − 2 ) 2 = 5 ( a − 2 ) 2 となり、それを2で割るからです。
ここで、a − 2 a - 2 a − 2 をひとまとまりと見て t t t と置くと、損失 = 2.5 t 2 = 2.5t^2 = 2.5 t 2 になります。これは中学3年で習った「y y y は x x x の2乗に比例する」関数と同じ形(比例定数が2.5)で、グラフは放物線です。中学で習ったグラフは x = 0 x = 0 x = 0 のところが谷底でしたが、今回は t = a − 2 = 0 t = a - 2 = 0 t = a − 2 = 0 、つまり a = 2 a = 2 a = 2 のところが谷底 になります。
a 損失 0 1 2 3 4 谷底 横軸をa、縦軸を損失にしたグラフ。a=2で損失が0の谷底になる、お椀のような形の放物線です。
学習とは、この 放物線の谷底を探すこと です。今回はグラフ全体が見えているので、答えが a = 2 a = 2 a = 2 だとすぐに分かります。しかし実際のモデルでは、動かす数値が何百万個もあるため、グラフを描いて眺めることはできません。そこで、「今いる場所の傾き」だけから進む向きを決める方法が必要になります。
勾配は「変化の割合」
中学2年の一次関数で、変化の割合 を習いました。
変化の割合 = y の増加量 x の増加量 \text{変化の割合} = \frac{y\text{の増加量}}{x\text{の増加量}} 変化の割合 = x の増加量 y の増加量
一次関数では変化の割合がどこでも同じ(傾きそのもの)でしたが、中学3年の「y y y は x x x の2乗に比例する」関数では、どの区間で計算するかによって値が変わりました。放物線は場所によって傾きが違うからです。
勾配も、この変化の割合で計算できます。例えば今 a = 3 a = 3 a = 3 にいるとします。a a a をほんの少し、0.01だけ増やしたとき、損失がどれだけ増えるかを調べます。
a = 3 a = 3 a = 3 のときの損失: 2.5 × ( 3 − 2 ) 2 = 2.5 2.5 \times (3 - 2)^2 = 2.5 2.5 × ( 3 − 2 ) 2 = 2.5
a = 3.01 a = 3.01 a = 3.01 のときの損失: 2.5 × ( 3.01 − 2 ) 2 = 2.55025 2.5 \times (3.01 - 2)^2 = 2.55025 2.5 × ( 3.01 − 2 ) 2 = 2.55025
変化の割合 = 2.55025 − 2.5 0.01 = 5.025 \text{変化の割合} = \frac{2.55025 - 2.5}{0.01} = 5.025 変化の割合 = 0.01 2.55025 − 2.5 = 5.025
プラスの値なので、「a a a を増やすと損失が増える」、つまり a a a を減らせば損失が減る ことが分かります。a = 1 a = 1 a = 1 で同じ計算をすると − 4.975 -4.975 − 4.975 とマイナスになり、今度は「a a a を増やせば損失が減る」ことが分かります。
a 損失 0 1 2 3 4 谷底 a = 3 での傾き a=3の点での傾き(点線)。右上がりなので、谷底に近づくにはaを減らす(左に進む)必要があります。
増やす幅を0.01から0.0001に小さくすると、変化の割合は5.00025になり、幅を小さくするほど 5 に近づいていきます。この「幅をどんどん小さくしたときに近づいていく値」が、その点での 勾配 です。高校数学で習う 微分 は、この値を式で正確に求める方法です。
もう一つ大事な性質があります。a = 4 a = 4 a = 4 では勾配は10になり、a = 3 a = 3 a = 3 の5より大きくなります。谷底から遠いほど坂が急で、勾配が大きくなる のです。勾配降下法では勾配に比例した歩幅で進むので、遠いうちは大きく、近づくと小さく動くことになります。
自分で勾配降下法を動かす
ここまでの考え方を、そのままPythonで書いてみます。使っているのは、足し算・引き算・掛け算・割り算とfor文だけです。
def loss(a):
return ((a * 1 - 2) ** 2 + (a * 2 - 4) ** 2) / 2
def gradient(a):
h = 0.0001 # aをほんの少しだけ増やす幅
return (loss(a + h) - loss(a)) / h # 変化の割合
a = 0.0 # スタート地点(適当な値)
lr = 0.1 # 学習率(1歩の大きさ)
for step in range(30):
a = a - lr * gradient(a) # 勾配と逆向きに少しだけ動く
print(step + 1, a, loss(a))
実行すると、a a a と損失は次のように変わっていきます(小数は丸めています)。
a a a が1回ごとに谷底の2へ近づき、損失が小さくなっていきます。30回繰り返すと、a a a は約1.99995になり、ほぼ正解の2にたどり着きます。
ここで注目してほしいのは、このプログラムは 放物線の全体像を一度も見ていない ということです。毎回やっているのは「今いる場所で、ほんの少し動いたら損失がどう変わるか」を調べて、下る向きに一歩進むことだけです。それだけで、正しい答えにたどり着けました。
これが、第1章で学んだ「予測する → ズレ(損失)を確かめる → 少しずつ調整する → 繰り返す」という学習の正体です。
学習率の大きさと、よくある誤解
学習率が大きすぎるとどうなるか
先ほどのプログラムで、学習率lrを変えて試すと、次のようになります。
lr = 0.1: a a a は 1.0 → 1.5 → 1.75 → … と、谷底の2に近づく
lr = 0.4: a a a は 4 → 0 → 4 → 0 → … と、谷底を挟んで行ったり来たりし続ける
lr = 0.5: a a a は 5 → −2.5 → 8.75 → … と、谷底からどんどん離れていく
歩幅が大きすぎると、谷底を飛び越えて反対側の坂に出てしまいます。飛び越えた先の坂がもっと急だと、次はさらに大きく飛ばされ、損失はむしろ増えていきます。逆に学習率が小さすぎると、正しい向きには進むものの、谷底に着くまでに非常に長い時間がかかります。ちょうど良い学習率を選ぶことは、実務でも重要な調整の一つです。
誤解:「微分を知らないと、勾配は計算できない?」
このレッスンで見たように、勾配は「ほんの少し動かしたときの変化の割合」として、中学数学だけで計算できます。実際のライブラリは、微分の公式を使ってもっと正確に、速く計算していますが、求めているものは同じです。
動かす数値が2つ以上あるとき
a a a と b b b の両方を動かすときは、「b b b を固定して a a a だけを少し動かしたときの変化の割合」と「a a a を固定して b b b だけを少し動かしたときの変化の割合」を別々に計算し、それぞれを同時に更新します。ディープラーニングのモデルでは、この動かす数値が数百万個から数千億個にもなりますが、一つ一つに対してやっていることは、このレッスンとまったく同じです。
振り返り
損失のグラフは、中学3年で習う放物線と同じ形で、学習とはその谷底を探すこと
勾配は、ごく小さい区間での「変化の割合」。プラスなら減らす、マイナスなら増やす
勾配と逆向きに、学習率の分だけ動くことを繰り返すと、グラフを見なくても谷底にたどり着ける