PyTorchは人気上昇中のニューラルネットワークライブラリ. numpyと親和性が高い.
from __future__ import print_function
import numpy as np
import torch
from torch.autograd import Variable
PyTorchの変数はtorch.Tensor
型として定義し,numpy.arrayと似た振る舞いをする.
x = torch.Tensor(5, 3) # メモリは初期化されない
print(x)
0.0000e+00 0.0000e+00 5.7260e+31
4.5801e-41 2.6699e+09 4.5801e-41
-1.3889e-14 3.0737e-41 -1.3889e-14
3.0737e-41 3.3887e+37 4.5801e-41
3.2915e+37 4.5801e-41 1.7148e+29
[torch.FloatTensor of size 5x3]
torch.rand(5, 3) #[0, 1]上の一様分布
0.0090 0.0027 0.8066
0.7704 0.8939 0.8752
0.2019 0.2329 0.0885
0.9281 0.5321 0.4206
0.4536 0.0725 0.3961
[torch.FloatTensor of size 5x3]
torch.randn(5, 3) # 標準正規分布
0.9565 -0.0533 -0.1352
0.7636 0.0229 1.2910
0.2379 -0.4774 -1.2879
0.3506 -0.2690 0.9901
0.1157 -0.3185 -0.0382
[torch.FloatTensor of size 5x3]
torch.ones(5, 3)
1 1 1
1 1 1
1 1 1
1 1 1
1 1 1
[torch.FloatTensor of size 5x3]
torch.zeros(5, 3)
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
[torch.FloatTensor of size 5x3]
torch.diag(torch.arange(0, 5))
0 0 0 0 0
0 1 0 0 0
0 0 2 0 0
0 0 0 3 0
0 0 0 0 4
[torch.FloatTensor of size 5x5]
torch.eye(5)
1 0 0 0 0
0 1 0 0 0
0 0 1 0 0
0 0 0 1 0
0 0 0 0 1
[torch.FloatTensor of size 5x5]
print(x[:, 1]) # インデクシングもpythonと変わらない
0.0000e+00
2.6699e+09
3.0737e-41
3.3887e+37
4.5801e-41
[torch.FloatTensor of size 5]
a = np.ones(5) # numpy.arrayからtorch.Tensorへの変換
b = torch.from_numpy(a) # このときaに加えた変更はbに遺伝する
np.add(a, 1, out=a) # 忘れていると痛い目にあいそう
print(a)
print(b)
[ 2. 2. 2. 2. 2.]
2
2
2
2
2
[torch.DoubleTensor of size 5]
torch.cuda.is_available() # cudaが使えるか判定
True
x = x.cuda() # .cuda()によってGPUメモリ上に変数を移動できる.
x
0.0000e+00 0.0000e+00 5.7260e+31
4.5801e-41 2.6699e+09 4.5801e-41
-1.3889e-14 3.0737e-41 -1.3889e-14
3.0737e-41 3.3887e+37 4.5801e-41
3.2915e+37 4.5801e-41 1.7148e+29
[torch.cuda.FloatTensor of size 5x3 (GPU 0)]
自動微分
PyTorchでは勾配計算をするときは変数をtorch.autograd.Variable型に入れる.
Variableのインスタンスはrequires_grad
とvolatile
の二つのフラグを持っていて,これらのフラグをもとに勾配計算に置いて考慮しないくていいsubgraphを除外し,効率的な計算を実現している.
requires_grad
変数が関数の引数となるとき,もまたによって勾配計算が出来るべきで,逆に言えば,の勾配を計算できなくてもよいのはの全てが勾配を計算しなくても良いときである.
x = Variable(torch.ones(2, 2), requires_grad=True)
y = 2 * x
z = y * y * 3
print(y.requires_grad, z.requires_grad)
True True
x = Variable(torch.ones(2, 2), requires_grad=False)
y = 2 * x
z = sum(sum(y))
print(y.requires_grad, z.requires_grad)
False False
と関数があって,と書けるとする.
がrequires_gradであるときもrequires_gradであって,.backward()としてから.gradとすると,が得られる. また,で,.backward()としてから.gradとするとが得られる.
x = Variable(torch.ones(2, 2), requires_grad=True)
y = 2 * x
z = y * y * 3
out = z.mean()
out.backward()
print(y.backward)
<bound method Variable.backward of Variable containing:
2 2
2 2
[torch.FloatTensor of size 2x2]
>
print(x.backward)
<bound method Variable.backward of Variable containing:
1 1
1 1
[torch.FloatTensor of size 2x2]
>
x = Variable(torch.ones(2, 2), requires_grad=True)
y = 2 * x
z = y * y * 3
out = z.mean()
z.backward() # zが多次元なためにエラー
x.grad
---------------------------------------------------------------------------
RuntimeError Traceback (most recent call last)
<ipython-input-20-c3877ab6bd13> in <module>()
3 z = y * y * 3
4 out = z.mean()
----> 5 z.backward() # zが多次元なためにエラー
6 x.grad
/usr/local/lib/python3.5/dist-packages/torch/autograd/variable.py in backward(self, gradient, retain_graph, create_graph, retain_variables)
154 Variable.
155 """
--> 156 torch.autograd.backward(self, gradient, retain_graph, create_graph, retain_variables)
157
158 def register_hook(self, hook):
/usr/local/lib/python3.5/dist-packages/torch/autograd/__init__.py in backward(variables, grad_variables, retain_graph, create_graph, retain_variables)
84 grad_variables = list(grad_variables)
85
---> 86 grad_variables, create_graph = _make_grads(variables, grad_variables, create_graph)
87
88 if retain_variables is not None:
/usr/local/lib/python3.5/dist-packages/torch/autograd/__init__.py in _make_grads(outputs, grads, user_create_graph)
32 if out.requires_grad:
33 if out.numel() != 1:
---> 34 raise RuntimeError("grad can be implicitly created only for scalar outputs")
35 data = out.data
36 new_grads.append(
RuntimeError: grad can be implicitly created only for scalar outputs
0 件のコメント:
コメントを投稿