はじめに
PyTorch入門第1回では,pytorchの基本操作を行いました.ここら辺は,numpyやmatlabを触ったことがあるので行列操作は問題ありませんでした.頑張るのはここからです.DeepLearning初心者にとっては厳しいですね….
autograd
PyTorchのニューラルネットワークはautograd
パッケージが中心になっています.autograd
は自動微分機能を提供します.つまり,このパッケージを使うと勝手に微分の計算を行ってくれると言うことです.
これはdefine-by-runフレームワークです.define-by-runについてはここを参照(まとめると,順伝播のコードを書くだけで逆伝播が定義できると言うことらしいです).
勾配の計算
autograd
については言葉で説明するより,実際のコードを見た方が理解が早いと思うので,簡単な式の勾配を計算するコードを参考に説明します.
##コードの全体像
import torch
# テンソルを作成
# requires_grad=Trueで自動微分対象を指定
x = torch.tensor(1.0, requires_grad=True)
w = torch.tensor(2.0, requires_grad=True)
b = torch.tensor(3.0, requires_grad=True)
# 計算グラフを構築
# y = 2 * x + 3
y = w * x + b
# 勾配を計算
y.backward()
# 勾配を表示
print(x.grad) # dy/dx = w = 2
print(w.grad) # dy/dw = x = 1
print(b.grad) # dy/db = 1
tensor(2.)
tensor(1.)
tensor(1.)
##コードの詳細
##計算グラフの構築
計算グラフは, requires_grad=True
で微分対象に指定されたtensorと,Function
パッケージの2つで構築されます.
# テンソルを作成
# requires_grad=Trueで自動微分対象を指定
x = torch.tensor(1.0, requires_grad=True)
w = torch.tensor(2.0, requires_grad=True)
b = torch.tensor(3.0, requires_grad=True)
# 計算グラフを構築
# y = 2 * x + 3
y = w * x + b
###requires_grad
requires_grad
では,requires_grad=True
とすることで微分対象のtensorを指定します.デフォルトではrequires_grad=False
となっており,このままだと微分の対象にはならず,勾配にはNoneが返ります.requires_grad=False
はFine-tuningで層のパラメータを固定したいときに便利だそうです.
実際に,requires_grad=True
と指定すると,以下のように表示されます.
x = torch.tensor(1.0, requires_grad=True)
print(x)
tensor(1., requires_grad=True)
###grad_fn
autograd
にはFunction
と言うパッケージがあります.requires_grad=True
で指定されたtensorとFunction
は内部で繋がっており,この2つで計算グラフが構築されています.この計算グラフに計算の記録が全て残ります.生成されたtensorのそれぞれに.grad_fn
という属性があり,この属性によってどのFunction
によってtensorが生成されたのかを参照できます.ただし,ユーザによって作られたtensorの場合grad_fn
はNoneとなります.
a = torch.tensor(1.0, requires_grad=True)
print(a.grad_fn)
b = a+2 # bは足し算(add)によって形成
print(b.grad_fn)
None
<AddBackward object at 0x7f740ffc0eb8>
##勾配の算出
# 勾配を計算
y.backward()
# 勾配を表示
print(x.grad) # dy/dx = w = 2
print(w.grad) # dy/dw = x = 1
print(b.grad) # dy/db = 1
backward()
を実行すると,グラフを構築する勾配を計算し,各変数の.grad
と言う属性にその勾配が入ります.