本文へスキップ
BecomeCoder

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

勾配降下法で直線を当てはめる

ブラウザで完結

導入

いよいよ本物の学習です。バラついたデータ点に、いちばんよく合う直線 y = w * x + b を、勾配降下法で見つけます。w(傾き)と b(切片)が、AIが学習するパラメータです。

説明

やることは第1章の輪そのものです。

  1. いまの w, b で予測する:pred = w * x + b
  2. 損失(MSE)を測る
  3. w, b それぞれについて勾配を求める
  4. 勾配の逆向きへ w, b を更新する

MSE を w, b で微分すると、勾配は次の式になります(導出は次のレッスンで扱います。ここは公式として使います)。

flowchart LR
  init["w, b を適当に初期化"] --> pred["pred = w*x + b"]
  pred --> loss["MSE を計算"]
  loss --> grad["勾配 dw, db を計算"]
  grad --> upd["w -= lr*dw<br/>b -= lr*db"]
  upd --> pred

やってみよう

下のコードは、y ≈ 2*x + 1 の関係を持つデータから、wb を学習で復元します。実行すると、損失が下がりながら w が 2 に、b が 1 に近づいていくのが分かります。あなたはどこにも「2」や「1」と教えていません。データだけから、AIが自力で見つけ出します。

import numpy as np

# データ(本当は y = 2x + 1 だが、少しノイズを混ぜてある)
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])

w, b = 0.0, 0.0     # パラメータを 0 から出発
lr = 0.05
n = len(x)

for epoch in range(200):
    pred = w * x + b
    error = pred - y
    dw = (2 / n) * np.sum(error * x)   # 損失を w で微分した勾配
    db = (2 / n) * np.sum(error)       # 損失を b で微分した勾配
    w -= lr * dw
    b -= lr * db
    if epoch % 40 == 0:
        loss = np.mean(error ** 2)
        print(f"epoch {epoch:3d}:  w={w:.3f}  b={b:.3f}  loss={loss:.4f}")

print(f"\n学習結果:  y = {w:.3f} * x + {b:.3f}  (正解は y = 2x + 1)")

演習

新しい入力 x = 10 に対する家賃…もとい予測値を、学習後の w, b で計算して表示してみましょう(答えはおよそ 21 になるはずです)。

ヒント1を見る

ループの後に print("x=10の予測:", w * 10 + b) を足します。

ヒント2を見る

y = 2x + 1x=10 を入れると 21。学習した直線もそれに近い値を返すはずです。

まとめ

  • 線形回帰は「データにいちばん合う直線 y=wx+b」を勾配降下法で見つける学習。
  • w, b を 0 から始めても、輪を回すうちにデータの正解(傾き2・切片1)へ収束する。
  • 学習後のモデルは、見たことのない入力にも予測できる(x=10 → 約21)。

実際に動かしてみよう

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

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

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