← Python and ROCm 教室へ戻る

第9章

学習と推論の違いを見比べたい

似たコードに見えても、重みが動くかどうかで中身はかなり違います。

今日は何をしたい?

推論は「答えを出すだけ」、学習は「答えを出してから直すまで」です。この違いを、同じモデルを使った短いコードで見比べて、自分の言葉で説明できるようにします。

推論学習
forward(答えを出す)するする
loss(ずれを測る)しないする
backward(勾配を計算)しないする
step(重みを更新)しないする
重みが変わるか変わらない変わる

確認コード

import torch
import torch.nn as nn

device = torch.device("cuda" if torch.cuda.is_available() else "cpu")

model = nn.Linear(1, 1).to(device)
optimizer = torch.optim.SGD(model.parameters(), lr=0.1)
x = torch.tensor([[1.0]], device=device)
y_true = torch.tensor([[2.0]], device=device)

# 変化を追うため、学習前の重みの値をコピーして保存しておきます
before = model.weight.detach().clone()

# --- 推論(forward だけ) ---
model.eval()
with torch.no_grad():
    answer = model(x)

# --- 学習(forward → loss → backward → step) ---
model.train()
# (model(x) - y_true).pow(2).mean() は第8章の nn.MSELoss() と同じ計算を手書きしています
loss = (model(x) - y_true).pow(2).mean()
optimizer.zero_grad()
loss.backward()
optimizer.step()

# 学習後の重みをコピーして、変化を確認します
after = model.weight.detach().clone()

print("inference output:", answer.item())
print("weight changed:", not torch.equal(before, after))

このコードでは、前半が推論、後半が学習です。最後の weight changedTrue なら、「学習側では重みが動いた」と読めます。

inference output: 0.3127 weight changed: True
weight changed: True が見えれば、「学習側では重みが動いた」と確認できます。推論 vs 学習の違いはこの 1 行に出ます。

実行コマンド

ファイルを chapter09.py という名前で保存したら、ターミナルで次のコマンドを実行します。

python chapter09.py

どこがROCm?

推論は forward だけ、学習は forward に加えて backward(勾配の計算)と step(重みの更新)も入ります。ROCm の見方では、学習のほうが GPU にやらせる仕事がずっと多くなります。特に backward の勾配計算は大量の行列演算を含むため、GPU の並列処理が効きやすい場面です。

ここで出てきたPython

eval() だけでは不十分な理由(クリックで開く)

model.eval() だけでは「絶対に学習しない」わけではありません。学習しない流れは no_grad() とセットで見ると分かりやすいです。推論で答えを出しても、重みは変わりません。

よくあるつまずき

1分演習

optimizer.step() を一度コメントアウトして、weight changed がどう変わるかを見てみましょう。