第7章
推論だけしたい
ここでは、学習はせずに「答えを出すだけ」の流れを切り分けて見ます。
今日は何をしたい?
まだ学習(次章)をしていなくても、モデルに入力を通して答えを出すことはできます。これを推論と呼びます。推論は「答えを出すだけ」で、重みを変えません。
ここでは eval() と no_grad() を使って、「学習はしないで使うだけ」を短い形で確認します。
- eval()
- モデルを「推論モード」に切り替える。Dropout や BatchNorm の動きが変わる。
- no_grad()
- 勾配計算を省略する。推論だけなら必要ないので、メモリと速度が少し楽になる。
確認コード
import torch
import torch.nn as nn
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
model = nn.Sequential(
nn.Linear(4, 8),
nn.ReLU(),
nn.Linear(8, 2),
).to(device)
x = torch.randn(1, 4, device=device)
model.eval()
with torch.no_grad():
y = model(x)
print(y)
print(y.requires_grad)このコードを chapter07.py として保存して、python chapter07.py で実行します。
tensor([[ 0.1532, -0.0478]], device='cuda:0')
False
tensor の数値は毎回変わります(ランダムな重みで初期化されるため)。ただし requires_grad は何度実行しても False のままです。
False は「このモデルの重みを調整しようとしていない(=学習していない)」という意味です。ここでやっているのは答えを出すだけ(forward)です。
eval() + no_grad() のセットで「推論だけ」の姿勢になります。学習との違いは次章で見比べます。
どこがROCm?
model.to(device) で GPU に置いておけば、eval() + no_grad() の推論も GPU 側で動きます。推論は「答えを出すだけ」なので、学習より使う計算量が少なく、GPU の負荷も軽めです。
ここで出てきたPython
- with ...: — 一時的なモードを作る
- model.eval() — 推論モードへ切り替え
- torch.no_grad() — 勾配計算を省略
eval() と no_grad() の使い分け(クリックで開く)
eval() は Dropout や BatchNorm の動きを推論向けに切り替えます。no_grad() は勾配計算を省略し、メモリと速度が少し楽になります。推論だけの場面では両方をセットで使うのが基本です。
よくあるつまずき
- model.eval() は「推論向けの設定へ切り替える」ための一歩です。
- torch.no_grad() を忘れても動くことはありますが、推論だけの場面では入れておくと意図が伝わります。
- 「答えを出した」ことと「学習した」ことは別です。この章ではまだ学習していません。
1分演習
コードをそのまま 2 回実行してみましょう。tensor の数値は変わっても、requires_grad が両方とも False であることを確認してみてください。