2017年9月26日火曜日

PyTorch練習 01日目

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_gradvolatileの二つのフラグを持っていて,これらのフラグをもとに勾配計算に置いて考慮しないくていい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 件のコメント:

コメントを投稿