#はじめに
研究室でPyTorchを使うということで,PyTorchの勉強を始めました.
PyTorchの公式チュートリアルを参考に,自分なりにPyTorchの使い方を基礎からまとめることで勉強していこうかと思います.公式チュートリアルが割と親切なので,とても助かります.
#Tensor
PyTorchではTensorという型で行列を表現します.
TensorはNumpyのndarrayと似ていますが,ndarrayと比べて,GPUを使うことで処理を高速化できるらしいです.
#行列の作成
from __future__ import print_function
import torch
###初期化されていない5x3行列
PyTorchでは初期化しないと,何かしらの値が入っている.
x = torch.empty(5, 3)
print(x)
tensor([[-1.6809e+27, 4.5759e-41, -1.6809e+27],
[ 4.5759e-41, -1.6808e+27, 4.5759e-41],
[-1.0937e+14, 3.0683e-41, -1.0983e+14],
[ 3.0683e-41, -1.6808e+27, 4.5759e-41],
[ 4.8761e+19, 1.8522e+28, 1.8057e+28]])
###乱数で初期化された5x3行列
x = torch.rand(5, 3)
print(x)
tensor([[0.9196, 0.4354, 0.0992],
[0.6225, 0.3860, 0.0710],
[0.4529, 0.0680, 0.2155],
[0.6509, 0.8464, 0.9153],
[0.6973, 0.3458, 0.6611]])
###ゼロで満たされた5x3行列
dtypeにlongを指定.
x = torch.zeros(5, 3, dtype=torch.long)
print(x)
tensor([[0, 0, 0],
[0, 0, 0],
[0, 0, 0],
[0, 0, 0],
[0, 0, 0]])
###データから作成
x = torch.tensor([5.5, 3])
print(x)
tensor([5.5000, 3.0000])
###既存のTensorから作成
# 行列xを1で埋める(double型)
x = x.new_ones(5, 3, dtype=torch.double)
print(x)
# 行列xを平均0,分散1の正規分布で埋める(float型)
# このように型の上書きもできる
x = torch.randn_like(x, dtype=torch.float)
print(x)
tensor([[1., 1., 1.],
[1., 1., 1.],
[1., 1., 1.],
[1., 1., 1.],
[1., 1., 1.]], dtype=torch.float64)
tensor([[-1.0114, 0.9043, -0.0096],
[ 0.7027, -0.0650, 0.3233],
[ 0.4848, -0.7181, 0.1159],
[-2.1770, 1.1517, -1.4411],
[-0.5862, 1.0985, -0.7677]])
Tensorサイズの取得
print(x.size())
torch.Size([5, 3])
Tensorの操作
加算
加算にはいくつかの方法があります.
x = torch.rand(5, 3)
y = torch.rand(5, 3)
print(x)
print(y)
tensor([[0.8883, 0.6499, 0.7337],
[0.4430, 0.2177, 0.8254],
[0.3867, 0.5194, 0.7142],
[0.0081, 0.0794, 0.0565],
[0.3625, 0.7039, 0.0115]])
tensor([[0.4755, 0.9994, 0.6331],
[0.3408, 0.7533, 0.4965],
[0.7359, 0.4444, 0.8851],
[0.3004, 0.0765, 0.7828],
[0.3236, 0.1944, 0.2417]])
方法1:
print(x + y)
tensor([[1.3638, 1.6493, 1.3668],
[0.7839, 0.9710, 1.3218],
[1.1226, 0.9638, 1.5993],
[0.3084, 0.1559, 0.8393],
[0.6861, 0.8983, 0.2532]])
方法2:
print(torch.add(x, y))
tensor([[1.3638, 1.6493, 1.3668],
[0.7839, 0.9710, 1.3218],
[1.1226, 0.9638, 1.5993],
[0.3084, 0.1559, 0.8393],
[0.6861, 0.8983, 0.2532]])
方法3:引数として出力Tensorを提供
result = torch.empty(5, 3) # 出力Tensorの作成
torch.add(x, y, out=result)
print(result)
tensor([[1.3638, 1.6493, 1.3668],
[0.7839, 0.9710, 1.3218],
[1.1226, 0.9638, 1.5993],
[0.3084, 0.1559, 0.8393],
[0.6861, 0.8983, 0.2532]])
方法4:入力Tensorを直接書き換える
y.add_(x) # y=x+y
print(y)
tensor([[1.3638, 1.6493, 1.3668],
[0.7839, 0.9710, 1.3218],
[1.1226, 0.9638, 1.5993],
[0.3084, 0.1559, 0.8393],
[0.6861, 0.8983, 0.2532]])
リサイズ
Tensorをリサイズするときはview()
を使います.
同じ要素を持った,違う形の行列を作成します.
x = torch.randn(4, 4) # 4x4の乱数行列
y = x.view(16) # 16次元の行列
z = x.view(-1, 8) # -1を使うと,自動で調整してくれる
print(x.size(), y.size(), z.size())
torch.Size([4, 4]) torch.Size([16]) torch.Size([2, 8])
要素数1のTensor
要素数1のTensorに対してitem()
を使うと,値をpythonの値として取得するとこができます.
x = torch.randn(1)
print(x)
print(x.item())
tensor([1.6671])
1.6670634746551514
Torch Tensor から Numpy Array への変化
Torch Tensor → Numpy Array
a = torch.ones(5)
b = a.numpy()
print(a)
print(b)
tensor([1., 1., 1., 1., 1.])
[1. 1. 1. 1. 1.]
Torch Tensor とNumpy Array は同じメモリアドレスを共有しています.そのため,一方を変更するとも一方も変更されます.
a.add_(1)
print(a)
print(b)
tensor([2., 2., 2., 2., 2.])
[2. 2. 2. 2. 2.]
Numpy Array → Torch Tensor
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)