optimによるテンソルの更新(対象が複数個の場合)
SGDインスタンスの生成時に、リストにまとめて渡したテンソルは全て更新の対象となる。
code:optim3.py
import torch as pt
import torch.optim as optim
x0 = 1, 2
y0 = 3
alpha = 0.1
x = pt.tensor(x0, dtype=pt.float, requires_grad=True)
y = pt.tensor(y0, dtype=pt.float, requires_grad=True)
optimizer = optim.SGD(x, y, lr=alpha) # (1):2つのテンソルx, yが更新対象
z = x@x.T + y**2
z.backward() # (2):リーフテンソルのx, yに勾配が格納される
print('# 更新前 --------------')
print('x:', x)
print('x.grad:', x.grad)
print('y:', y)
print('y.grad:', y.grad)
optimizer.step()
print('# 更新後 --------------')
print('x:', x)
print('y:', y)
ベクトル$ \mathbf{x} については、各要素が独立した変数と考えると、$ \mathbf{x} = \left[\begin{array}{cc} x_1 & x_2 \end{array}\right] と表記できる。
$ z(x_1, x_2, y) = \left[\begin{array}{cc} x_1 & x_2 \end{array}\right] \left[\begin{array}{c} x_1 \\ x_2 \end{array}\right] + y^2 = x_1^2 + x_2^2 + y^2
$ \frac{\partial z}{\partial x_1} = 2x_1より、$ x_1=1のとき勾配は$ x_1.grad = 2
$ \frac{\partial z}{\partial x_2} = 2x_2より、$ x_2=2のとき勾配は$ x_2.grad = 4
まとめると、xの勾配は
$ x.grad = \left[\begin{array}{cc} 2&4 \end{array}\right]
となる。また、
$ \frac{\partial z}{\partial y} = 2yより、$ y=3のときの勾配は$ y.grad=6
となる。
以上より、学習率$ \alpha =0.1で$ x, yを更新した結果は次のようになる。
code:(結果).py
# 更新前 --------------
x: tensor(1., 2., requires_grad=True)
x.grad: tensor(2., 4.)
y: tensor(3., requires_grad=True)
y.grad: tensor(6.)
# 更新後 --------------
x: tensor(0.8000, 1.6000, requires_grad=True)
y: tensor(2.4000, requires_grad=True)
/icons/hr.icon
※ ブラウザのバックボタンで戻る