← Python and ROCm 教室へ戻る

第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

eval() と no_grad() の使い分け(クリックで開く)

eval() は Dropout や BatchNorm の動きを推論向けに切り替えます。no_grad() は勾配計算を省略し、メモリと速度が少し楽になります。推論だけの場面では両方をセットで使うのが基本です。

よくあるつまずき

1分演習

コードをそのまま 2 回実行してみましょう。tensor の数値は変わっても、requires_grad が両方とも False であることを確認してみてください。