本シリーズでは,ディープラーニングを実装する際に強力な手助けをしてくれる「PyTorch」についてです。公式チュートリアルを,初心者に向けてかみ砕きながら翻訳していこうと思います。(公式ページはこちらより)
今回はNo.1で,「PyTorchとは何か?」編です。その他の記事は,こちらの「PyTorchの公式チュートリアルを初心者向けに読み解く」をご覧ください。
読みたい場所へジャンプ!
PyTorchとは
チュートリアル中では,以下のことが挙げられていました。
●Numpyに代わってGPU上で動くパッケージ
●最も柔軟性があり高速な深層学習のプラットフォーム
PyTorchのインポート
import torch
空のテンソル作成
x = torch.empty(5, 3)
print(x)
out:
tensor([[ 1.2089e-36, 0.0000e+00, 4.4842e-44],
[ 0.0000e+00, nan, 0.0000e+00],
[ 2.1375e+20, 1.0514e-05, 6.6768e+22],
[ 3.4154e-06, 2.1253e-07, 5.3641e-08],
[ 2.1746e+23, 5.2062e+22, -2.0551e-02]])
空のテンソルを生成しています。チュートリアルではnanは出現していませんでしたが,私の環境では出現しました。
乱数生成
x = torch.rand(5, 3)
print(x)
out:
tensor([[0.3632, 0.5784, 0.2058],
[0.8037, 0.0831, 0.1879],
[0.4682, 0.1356, 0.5619],
[0.5482, 0.8745, 0.8813],
[0.2930, 0.5172, 0.2618]])
$[0,1)$の乱数を要素にもつテンソルを生成します。
ゼロテンソルの作成
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]])
整数型の$0$を要素にもつテンソルを生成します。
テンソルを直打ちで生成
x = torch.tensor([5.5, 3])
print(x)
out:
tensor([5.5000, 3.0000])
numpyと同じような形でpythonの配列をtensorにすることができます。
x = x.new_ones(5, 3, dtype=torch.double)
print(x)
x = torch.randn_like(x, dtype=torch.float)
print(x)
out:
tensor([[1., 1., 1.],
[1., 1., 1.],
[1., 1., 1.],
[1., 1., 1.],
[1., 1., 1.]], dtype=torch.float64)
tensor([[-0.7061, -1.2102, -0.5727],
[ 0.2896, 1.1286, 0.0940],
[-0.9989, 0.9799, 0.8011],
[ 1.1659, -0.2063, 1.3626],
[-0.3563, 1.0880, -0.3853]])
xに上書きする形で$1$を要素にもつテンソルを生成してます。dtypeをdoubleで生成していすが,pythonではdoubleとfloat64は同じですので,出力ではfloat64と表示されています。randn_likeでは正規乱数を生成しています。
大きさの確認
print(x.size())
out:
torch.Size([5, 3])
テンソルのサイズを確認しています。出力はタプルとして扱えます。
テンソルの足し算
y = torch.rand(5, 3)
print(x + y)
out:
tensor([[-0.3925, -0.2433, -0.2945],
[ 0.9040, 1.5724, 0.7819],
[-0.9293, 1.1928, 1.4424],
[ 1.2716, 0.0606, 1.7911],
[ 0.4971, 1.4094, 0.2141]])
print(torch.add(x, y))
out:
tensor([[-0.3925, -0.2433, -0.2945],
[ 0.9040, 1.5724, 0.7819],
[-0.9293, 1.1928, 1.4424],
[ 1.2716, 0.0606, 1.7911],
[ 0.4971, 1.4094, 0.2141]])
ここまでは,単に足し算の結果を出力しています。以下では,足し算の結果を他のテンソルに格納します。
result = torch.empty(5, 3)
torch.add(x, y, out=result)
print(result)
out:
tensor([[-0.3925, -0.2433, -0.2945],
[ 0.9040, 1.5724, 0.7819],
[-0.9293, 1.1928, 1.4424],
[ 1.2716, 0.0606, 1.7911],
[ 0.4971, 1.4094, 0.2141]])
y.add_(x)
print(y)
y.add_(x)
print(y)
テンソルのスライス
print(x[:, 1])
Numpyのようにテンソルをスライスすることができます。
テンソルのサイズ変更
x = torch.randn(4, 4)
y = x.view(16)
z = x.view(-1, 8)
print(x.size(), y.size(), z.size())
torch.Size([4, 4]) torch.Size([16]) torch.Size([2, 8])
Numpyでいうところのreshapeがこちらのviewです。-1はしわ寄せのための引数として与えています。つまり,インデックス2番目が8となるようにインデックス1を定めてねという意味です。
x = torch.randn(1)
print(x)
print(x.item())
out:
tensor([-0.4215])
-0.4215209484100342
tensorからvalueを取り出すには.item()を利用します。
Numpyとの相互変換
a = torch.ones(5)
print(a)
out:
tensor([1., 1., 1., 1., 1.])
b = a.numpy()
print(b)
[1. 1. 1. 1. 1.]
.numpy()を利用することでtensorをnumpy型に変換することができます。
a.add_(1)
print(a)
print(b)
out:
tensor([2., 2., 2., 2., 2.])
[2. 2. 2. 2. 2.]
import numpy as np
a = np.ones(5)
b = torch.from_numpy(a)
np.add(a, 1, out=a)
print(a)
print(b)
out:
[2. 2. 2. 2. 2.]
tensor([2., 2., 2., 2., 2.], dtype=torch.float64)
逆に,.from_numpy()を利用してnumpy型をtensorに変換することもできます。
GPUの使用
if torch.cuda.is_available():
device = torch.device("cuda") # deviceの定義
y = torch.ones_like(x, device=device) # yを定義するときに直接GPUに渡してしまう
x = x.to(device) # 定義してあるテンソルをGPUに渡す
z = x + y
print(z)
print(z.to("cpu", torch.double)) # 後からCPUに渡すこともできる。型も変えられる。
.toを利用することでGPUにtensorを渡すことができます。CPUにも渡すことができます。