1. 環境は、Window 10 Home (64bit) 上で行った。
2. Anaconda3 (64bit) – Spyder上で、動作確認を行った。
3. python の バージョンは、python 3.6.5 である。
4. pytorch の バージョンは、pytorch 0.4.1 である。
5. GPU は, NVIDIA社 の GeForce GTX 1050 である。
今回確認した内容は、現場で使える! PyTorch開発入門 深層学習モデルの作成とアプリケーションへの実装 (AI & TECHNOLOGY) の 1.3 Tensorと自動微分(P.022 – P.023) である。
自動微分について, 少し理解を深めるため, 簡単な動作確認を行った.
※プログラムの詳細は、書籍を参考(P.022 – P.023)にして下さい。
■自動微分例①.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
# -*- coding: utf-8 -*- # 1. library import. from __future__ import print_function import torch # 2. automatic differentiation の 挙動確認. # Autograd: automatic differentiation. # https://pytorch.org/tutorials/beginner/blitz/autograd_tutorial.html#gradients # # requires_grad=False とすると, 以下のような実行時エラーが表示される. # RuntimeError: element 0 of tensors does not require grad and does not have a grad_fn # a = torch.randn(2, 2, requires_grad=False) a = torch.randn(3, 2, requires_grad=True) # b = a11 * a11 + a12 * a12 + a21 * a21 + a22 * a22 + a31 * a31 + a32 * a32 # のように計算している. # 但し, aij で, テンソルa の i行j列目 を表しているとする. b = (a * a).sum() print(a) print('--------------------------------------------------') print(b) print('--------------------------------------------------') print(b.grad_fn) print('--------------------------------------------------') b.backward() # a.grad で, ∂b/∂a11 = a11 * 2, ..., ∂b/∂a32 = a32 * 2 といった計算が行われ, 計算結果が表示される. print(a.grad) |
■実行結果①.
1 2 3 4 5 6 7 8 9 10 11 |
tensor([[ 0.4537, 0.2061], [-0.5527, -2.7338], [-0.1388, 1.5524]], requires_grad=True) -------------------------------------------------- tensor(10.4567, grad_fn=<SumBackward0>) -------------------------------------------------- <SumBackward0 object at 0x0000029B936FD3C8> -------------------------------------------------- tensor([[ 0.9074, 0.4122], [-1.1054, -5.4676], [-0.2775, 3.1047]]) |
■自動微分例②.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
# -*- coding: utf-8 -*- # 1. library import. from __future__ import print_function import torch # 2. automatic differentiation の 挙動確認. # Autograd: automatic differentiation. # https://pytorch.org/tutorials/beginner/blitz/autograd_tutorial.html#gradients # # a = torch.tensor([[1, 2, 3], [4, 5, 6]], requires_grad=True) # -> 以下のような実行時エラーが表示される. # RuntimeError: Only Tensors of floating point dtype can require gradients # a = torch.tensor([[1, 2, 3], [4, 5, 6.]], requires_grad=True) # b = (a11 + a12 + a13 + a21 + a22 + a23) / 6 # のように計算している. # 但し, aij で, テンソルa の i行j列目 を表しているとする. b = a.mean() print(a) print('--------------------------------------------------') print(b) print('--------------------------------------------------') print(b.grad_fn) print('--------------------------------------------------') b.backward() # a.grad で, ∂b/∂a11 = 1 / 6, ..., ∂b/∂a23 = 1 / 6 といった計算が行われ, 計算結果が表示される. print(a.grad) |
■実行結果②.
1 2 3 4 5 6 7 8 9 |
tensor([[1., 2., 3.], [4., 5., 6.]], requires_grad=True) -------------------------------------------------- tensor(3.5000, grad_fn=<MeanBackward1>) -------------------------------------------------- <MeanBackward1 object at 0x0000029B937199B0> -------------------------------------------------- tensor([[0.1667, 0.1667, 0.1667], [0.1667, 0.1667, 0.1667]]) |
■自動微分例③.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
# -*- coding: utf-8 -*- # 1. library import. from __future__ import print_function import torch # 2. automatic differentiation の 挙動確認. # Autograd: automatic differentiation. # https://pytorch.org/tutorials/beginner/blitz/autograd_tutorial.html#gradients # a = torch.tensor([[1, 2, 3], [5, 6, 4.]], requires_grad=True) # b = max(a11, a12, a13, a21, a22, a23) = a22 # のように計算している. # 但し, aij で, テンソルa の i行j列目 を表しているとする. b = torch.max(a) print(a) print('--------------------------------------------------') print(b) print('--------------------------------------------------') print(b.grad_fn) print('--------------------------------------------------') b.backward() # a.grad で, ∂b/∂a11 = 0, ..., ∂b/∂a22 = 1, ∂b/∂a23 = 0 といった計算が行われ, 計算結果が表示される. print(a.grad) |
■実行結果③.
1 2 3 4 5 6 7 8 9 |
tensor([[1., 2., 3.], [5., 6., 4.]], requires_grad=True) -------------------------------------------------- tensor(6., grad_fn=<MaxBackward1>) -------------------------------------------------- <MaxBackward1 object at 0x0000029B93719320> -------------------------------------------------- tensor([[0., 0., 0.], [0., 1., 0.]]) |
■自動微分例④.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
# -*- coding: utf-8 -*- # 1. library import. from __future__ import print_function import torch # 2. automatic differentiation の 挙動確認. # Autograd: automatic differentiation. # https://pytorch.org/tutorials/beginner/blitz/autograd_tutorial.html#gradients # a = torch.tensor([[1, 3], [4, 2.]], requires_grad=True) # b が, スカラーでない場合は, 以下のような実行時エラーが出力される. # RuntimeError: grad can be implicitly created only for scalar outputs # b = torch.mm(a.t(), a) # # b11 = a11 * a11 + a21 * a21 # b12 = a12 * a11 + a22 * a21 # b21 = a11 * a12 + a21 * a22 # b22 = a12 * a12 + a22 * a22 # のように計算している. # 但し, aij で, テンソルa の i行j列目 を表しているとする. b = torch.mm(a.t(), a) # c = (b11 + b12 + b21 + b22) / 4 のように計算している. c = b.mean() print(a) print('--------------------------------------------------') print(b) print('--------------------------------------------------') print(c) print('--------------------------------------------------') print(c.grad_fn) print('--------------------------------------------------') c.backward() # a.grad で, ∂c/∂a11 = (∂b11/∂a11 + ∂b12/∂a11 + ∂b21/∂a11 + ∂b22/∂a11) / 4 # = (a11 * 2 + a12 + a12) / 4, # ∂c/∂a12 = (∂b11/∂a12 + ∂b12/∂a12 + ∂b21/∂a12 + ∂b22/∂a12) / 4 # = (a11 + a11 + a12 * 2) / 4, ... # など計算が行われ, ∂c/∂a11, ..., ∂c/∂a22 の各計算結果が表示される. print(a.grad) |
■実行結果④.
1 2 3 4 5 6 7 8 9 10 11 12 |
tensor([[1., 3.], [4., 2.]], requires_grad=True) -------------------------------------------------- tensor([[17., 11.], [11., 13.]], grad_fn=<MmBackward>) -------------------------------------------------- tensor(13., grad_fn=<MeanBackward1>) -------------------------------------------------- <MeanBackward1 object at 0x0000029B936DCDA0> -------------------------------------------------- tensor([[2., 2.], [3., 3.]]) |
■注意点として, 以下のことが分かった.
① a に, requires_grad=False を指定すると,
RuntimeError: element 0 of tensors does not require grad and does not have a grad_fn
のようなエラーが出力されること.
② a が float型でないと,
RuntimeError: Only Tensors of floating point dtype can require gradients
のようなエラーが出力されること.
③ b が スカラーでないと,
RuntimeError: grad can be implicitly created only for scalar outputs
のようなエラーが出力されること.
■参考書籍
現場で使える! PyTorch開発入門 深層学習モデルの作成とアプリケーションへの実装 (AI & TECHNOLOGY)