PyTorch : Tutorial 初級 : PyTorch とは何か?

PyTorch : Tutorial 初級 : PyTorch とは何か? (翻訳/解説)
翻訳 : (株)クラスキャット セールスインフォメーション
更新日時 : 07/22/2018 (0.4.0), 04/18/2018; 11/28/2017
作成日時 : 04/13/2017

* 0.4.0 に対応するために更新しました。
* 本ページは、PyTorch Tutorials の What is PyTorch? を動作確認・翻訳した上で適宜、補足説明したものです:

* ご自由にリンクを張って頂いてかまいませんが、sales-info@classcat.com までご一報いただけると嬉しいです。

 

PyTorch とは何か?

2つのセットのオーディエンスを対象とする Python ベースの科学計算パッケージです :

  • GPU のパワーを使用するための NumPy の置き換えです。
  • 最大限の柔軟性とスピードを提供する深層学習研究プラットフォームです。

 

Getting Started

テンソル

テンソルは numpy の ndarray に類似していますが、テンソルは GPU 上で計算を加速するために使用できることが付加されます。

from __future__ import print_function
import torch

(メモリが) 非初期化の 5×3 行列をコンストラクトします :

x = torch.empty(5, 3)
print(x)

Out:

tensor([[ 1.0057e-08,  4.5755e-41,  1.8933e-38],
        [ 3.0962e-41,  1.8139e-09,  4.5755e-41],
        [ 1.8157e-09,  4.5755e-41,  1.3858e-08],
        [ 4.5755e-41,  1.3776e-08,  4.5755e-41],
        [ 1.8155e-09,  4.5755e-41,  1.8155e-09]])

ランダムに初期化された行列をコンストラクトします :

x = torch.rand(5, 3)
print(x)

Out:

tensor([[ 0.7479,  0.2333,  0.2893],
        [ 0.3516,  0.4779,  0.6052],
        [ 0.8902,  0.6741,  0.6272],
        [ 0.6205,  0.1641,  0.6893],
        [ 0.2046,  0.3201,  0.5206]])                                                     

ゼロで満たされた dtype long の行列をコンストラクトします :

x = torch.zeros(5, 3, dtype=torch.long)
print(x)

Out:

tensor([[ 0,  0,  0],
        [ 0,  0,  0],
        [ 0,  0,  0],
        [ 0,  0,  0],
        [ 0,  0,  0]])

データから直接 tensor をコンストラクトします :

x = torch.tensor([5.5, 3])
print(x)

Out:

tensor([ 5.5000,  3.0000])

あるいは既存の tensor を基に tensor を作成します。新しい値がユーザにより提供されないのであればこれらのメソッドは入力 tensor のプロパティを再利用します、e.g. dtype。

x = x.new_ones(5, 3, dtype=torch.double)      # new_* methods take in sizes
print(x)

x = torch.randn_like(x, dtype=torch.float)    # override dtype!
print(x)    

Out:

tensor([[ 1.,  1.,  1.],
        [ 1.,  1.,  1.],
        [ 1.,  1.,  1.],
        [ 1.,  1.,  1.],
        [ 1.,  1.,  1.]], dtype=torch.float64)
tensor([[ 0.2125,  0.8487, -0.1981],
        [ 0.6821,  1.3270, -0.5024],
        [ 0.4968,  0.1023, -1.6708],
        [ 0.6607,  0.6271,  0.5538],
        [ 0.1562, -0.5792, -0.5589]])

そのサイズを得ます :

print(x.size())

Out:

torch.Size([5, 3])

[注意]

torch.Size は実際にはタプルですので、それは総てのタプル演算をサポートします。

 

演算

演算のためには複数のシンタックスがあります。次の例では、加算演算を見ます。

加算: シンタクス 1

# x = torch.rand(5, 3)
y = torch.rand(5, 3)
print(x + y)

Out:

tensor([[ 1.1730,  1.1569,  1.3879],
        [ 1.5143,  0.4410,  0.8776],
        [ 0.9693,  1.4725,  1.2213],
        [ 1.1008,  0.7631,  0.2593],
        [ 1.2640,  1.3030,  1.0865]])

加算: シンタクス 2

print(torch.add(x, y))

Out:

tensor([[ 1.1730,  1.1569,  1.3879],
        [ 1.5143,  0.4410,  0.8776],
        [ 0.9693,  1.4725,  1.2213],
        [ 1.1008,  0.7631,  0.2593],
        [ 1.2640,  1.3030,  1.0865]])

加算: 出力テンソルを引数として提供します :

result = torch.empty(5, 3)
torch.add(x, y, out=result)
print(result)

Out:

tensor([[ 1.1730,  1.1569,  1.3879],
        [ 1.5143,  0.4410,  0.8776],
        [ 0.9693,  1.4725,  1.2213],
        [ 1.1008,  0.7631,  0.2593],
        [ 1.2640,  1.3030,  1.0865]])

加算: in-place

# adds x to y
y.add_(x)
print(y)

Out:

tensor([[ 1.1730,  1.1569,  1.3879],
        [ 1.5143,  0.4410,  0.8776],
        [ 0.9693,  1.4725,  1.2213],
        [ 1.1008,  0.7631,  0.2593],
        [ 1.2640,  1.3030,  1.0865]])

[注意]

tensor を in-place で変化させる任意の演算は _ で post-fix されます。例えば : x.copy_(y), x.t_(), は x を変更します。

 
標準的な NumPy-ライクなインデキシングもあらゆるものと一緒に (= with all bells and whistles) 使用できます!

x = torch.rand(5, 3)
print(x)
print(x[:, 1])

Out:

tensor([[ 0.4409,  0.8285,  0.8918],
        [ 0.7014,  0.3659,  0.5467],
        [ 0.9397,  0.0767,  0.7690],
        [ 0.5209,  0.6222,  0.1750],
        [ 0.3288,  0.4374,  0.2605]])
tensor([ 0.8285,  0.3659,  0.0767,  0.6222,  0.4374])

リサイズ: tensor をリサイズ/reshape することを望む場合、torch.view が利用できます:

x = torch.randn(4, 4)
y = x.view(16)
z = x.view(-1, 8)  # the size -1 is inferred from other dimensions
print(x.size(), y.size(), z.size())

Out:

torch.Size([4, 4]) torch.Size([16]) torch.Size([2, 8])

1 要素 tensor を持つ場合、Python 数としての値を得るために .item() が使用できます :

x = torch.randn(1)
print(x)
print(x.item())

Out:

tensor([-0.1460])
-0.1460116058588028

Read later:

100+ Tensor operations, including transposing, indexing, slicing, mathematical operations, linear algebra, random numbers, etc are described here

 

Numpy ブリッジ

Torch テンソルを NumPy 配列に変換することそしてその逆も簡単なことです。

Torch テンソルと NumPy 配列はそれらの基礎となるメモリ位置を共有するでしょう、そして一方の変更は他方を変更します。

Torch テンソルを NumPy 配列に変換する

a = torch.ones(5)
print(a)

Out:

tensor([ 1.,  1.,  1.,  1.,  1.])
b = a.numpy()
print(b)

Out:

[1. 1. 1. 1. 1.]

numpy 配列が値についてどのように変更されるかを見ます。

a.add_(1)
print(a)
print(b)
tensor([ 2.,  2.,  2.,  2.,  2.])
[2. 2. 2. 2. 2.]

NumPy 配列を Torch テンソルに変換する

np 配列の変更がどのように Torch テンソルを自動的に変更するかを見ます。
(訳注: 要はメモリを共有しているということです。)

import numpy as np
a = np.ones(5)
b = torch.from_numpy(a)
np.add(a, 1, out=a)
print(a)
print(b)
[2. 2. 2. 2. 2.]
tensor([ 2.,  2.,  2.,  2.,  2.], dtype=torch.float64)

CharTensor を除く CPU 上の全てのテンソルは Numpy への変換とその逆をサポートします。

 

CUDA テンソル

テンソルは .to メソッドを使用して任意のデバイス上へ移動できます

# let us run this cell only if CUDA is available
# We will use ``torch.device`` objects to move tensors in and out of GPU
if torch.cuda.is_available():
    device = torch.device("cuda")          # a CUDA device object
    y = torch.ones_like(x, device=device)  # directly create a tensor on GPU
    x = x.to(device)                       # or just use strings ``.to("cuda")``
    z = x + y
    print(z)
    print(z.to("cpu", torch.double))       # ``.to`` can also change dtype together!

Out:

tensor([ 2.3159], device='cuda:0')
tensor([ 2.3159], dtype=torch.float64)

訳注: 0.4.0 以前は .cuda メソッドで GPU へ移動させていました。

# let us run this cell only if CUDA is available
if torch.cuda.is_available():
    x = x.cuda()
    y = y.cuda()
    x + y
 

以上