どん底から這い上がるまでの記録

どん底から這い上がりたいけど這い上がれない人がいろいろ書くブログ(主にプログラミング)

Introduction to PyTorch

 

PyTorchのTutorialのページにあるIntroduction to PyTorchについて勉強してみました。Tutorialを通して自分が学んだことを書いていきます。

 

 

Tutorial Page

Introduction to PyTorch — PyTorch Tutorials 0.4.1 documentation

Introduction to Torch's tensor library

Deep learningテンソルを使って計算します。テンソルとは多次元の数値表現のことで、数値が1つだけならスカラー、数値が1次元に並んでいるのはベクトル、数値が2次元に並んでいるのは行列と呼ばれています。

この記事で出てくるテンソルとはtorch.tensor()のオブジェクトのことを意味し、その次元が1次元でも2次元の場合でもテンソルと呼ぶことにします。

まずはテンソルの扱い方について見ていきます。

import torch

Creating Tensors

テンソルはlistからtorch.tensor()で作ることができます。

V_data = [1, 2, 3]
V = torch.tensor(V_data)
print(V, V.dtype)
"""out:
tensor([ 1,  2,  3]) torch.int64
"""

torch.tensorは与えられたデータの型を推論して自動的に型を決定してくれます。上の例では、整数が入ったリストを渡しているのでデータ型はtorch.LongTensorになっています。(※torch.int64はCPUではtorch.LongTensorに、GPUではtorch.cuda.LongTensorになります。)

型についての詳細はこちら

 

2次元のテンソルを作ってみます。

M_data = [[1, 2, 3], [4, 5, 6]]
M = torch.Tensor(M_data)
print(M, M.dtype)

torch.set_default_tensor_type(torch.DoubleTensor)
M = torch.Tensor(M_data)
print(M, M.dtype)
"""out:
tensor([[ 1.,  2.,  3.],
        [ 4.,  5.,  6.]]) torch.float32
tensor([[ 1.,  2.,  3.],
        [ 4.,  5.,  6.]]) torch.float64
"""

torch.Tensor()はデフォルトでtorch.FloatTensorエイリアスとして設定されている。torch.set_default_tensor_type()により型を変更することはできるが型が浮動小数点のみとなっている。そのため、torch.LongTensortorch.set_default_tensor_type()に渡すとエラーが出る。

型についての詳細はこちら

 

次に、2x2x2の3次元のテンソルを作ってみます。

T_data = [[[1., 2.], [3., 4.]],
          [[5., 6.], [7., 8.]]]
T = torch.tensor(T_data)
print(T, T.shape)
"""out:
tensor([[[ 1.,  2.],
         [ 3.,  4.]],

        [[ 5.,  6.],
         [ 7.,  8.]]]) torch.Size([2, 2, 2])
"""

 

インデックスをVに与えて、スカラーを得る(0次元のテンソル

print(V[0])
"""out:
tensor(1)
"""

.item()pythonでの値を取り出せる。

print(V[0].item())
"""out:
1
"""

インデックスをMに与えて、ベクトルを得る。

print(M[0])
"""out:
tensor([ 1.,  2.,  3.])
"""

インデックスをTに与えて、行列を得る。

print(T[0])
"""out:
tensor([[ 1.,  2.],
        [ 3.,  4.]])
"""

 

指定された次元を標準正規分布から生成されたランダムな値で埋める。

x = torch.randn((3, 4, 5))
print(x, x.shape)
print(x[0])
"""out:
tensor([[[ 0.4171, -1.4165,  0.4129,  0.8128, -0.2526],
         [-0.3155,  1.0979,  1.0506,  0.4743, -1.5041],
         [ 0.8794,  0.6606, -0.2447, -0.3222, -0.0621],
         [-0.6113,  0.0459,  0.5048, -0.4934, -0.1894]],

        [[ 1.2198, -0.0486,  0.7563,  0.4156,  1.7642],
         [ 1.3720, -0.4197,  0.9473,  0.9977,  0.4771],
         [ 0.0384,  2.0235, -0.3794,  0.5744,  0.0715],
         [-0.0788,  1.6886, -0.9615,  1.6609, -0.1665]],

        [[-0.1952,  0.0457,  0.1129, -1.3878,  0.6242],
         [ 1.2657, -0.0036,  0.5335, -0.3653,  0.0705],
         [ 2.3522,  0.0742, -0.8491, -0.2348,  0.7753],
         [-0.8914, -1.5682, -1.0056, -0.1849,  0.4762]]]) torch.Size([3, 4, 5])
tensor([[ 0.4171, -1.4165,  0.4129,  0.8128, -0.2526],
        [-0.3155,  1.0979,  1.0506,  0.4743, -1.5041],
        [ 0.8794,  0.6606, -0.2447, -0.3222, -0.0621],
        [-0.6113,  0.0459,  0.5048, -0.4934, -0.1894]])
"""

Operations with Tensors

演算子を使うことができる。

x = torch.tensor([1, 2, 3])
y = torch.tensor([4, 5, 6])
z = x + y
print(z)
"""out:
tensor([ 5,  7,  9])
"""

 

cat()テンソルの連結ができる。デフォルトでは行(横軸)で連結する。

x_1 = torch.randn(2, 3)
y_1 = torch.randn(1, 3)
z_1 = torch.cat([x_1, y_1])
print(x_1)
print(y_1)
print(z_1)
"""out:
tensor([[ 0.6672,  1.7063, -0.9040],
        [-0.0381, -0.7408,  0.4551]])
tensor([[ 0.3441,  0.1518,  1.1964]])
tensor([[ 0.6672,  1.7063, -0.9040],
        [-0.0381, -0.7408,  0.4551],
        [ 0.3441,  0.1518,  1.1964]])
"""

列での連結。

x_2 = torch.randn(2, 2)
y_2 = torch.randn(2, 3)
z_2 = torch.cat([x_2, y_2], dim=1)
print(x_2)
print(y_2)
print(z_2)
"""out:
tensor([[-0.5087,  0.3223],
        [ 0.2652, -0.8668]])
tensor([[-1.6814,  0.2035,  1.1120],
        [-0.0943, -0.0358,  0.8498]])
tensor([[-0.5087,  0.3223, -1.6814,  0.2035,  1.1120],
        [ 0.2652, -0.8668, -0.0943, -0.0358,  0.8498]])
"""

Reshaping Tensors

テンソルの形状を変更します。.view()テンソルの形状変換ができます。

x = torch.randn(2, 3, 4)
print(x)
print(x.view(2, 12))
"""out:
tensor([[[-1.0790,  0.6420,  0.0727, -1.8011],
         [-0.8469, -0.9400,  0.4188,  0.9641],
         [ 0.3636, -1.1892,  1.8733,  0.3989]],

        [[-0.7389,  0.3171,  2.2065, -1.1100],
         [ 0.5412, -0.2493, -2.0283, -0.4604],
         [-0.2777, -2.0034, -0.2581, -1.1070]]])
tensor([[-1.0790,  0.6420,  0.0727, -1.8011, -0.8469, -0.9400,  0.4188,
          0.9641,  0.3636, -1.1892,  1.8733,  0.3989],
        [-0.7389,  0.3171,  2.2065, -1.1100,  0.5412, -0.2493, -2.0283,
         -0.4604, -0.2777, -2.0034, -0.2581, -1.1070]])
"""

2行12列に形状変換をしています。

下でやっていることは上でやっていることと同じです。

もしある次元に-1を渡すと次元が推論され自動的に次元が決定します。

print(x.view(2, -1))
"""out:
tensor([[-1.0790,  0.6420,  0.0727, -1.8011, -0.8469, -0.9400,  0.4188,
          0.9641,  0.3636, -1.1892,  1.8733,  0.3989],
        [-0.7389,  0.3171,  2.2065, -1.1100,  0.5412, -0.2493, -2.0283,
         -0.4604, -0.2777, -2.0034, -0.2581, -1.1070]])
"""

Computation Graphs and Automatic Differentiation

この部分は自分の今の英語力ではいまいち理解ができなかったので、飛ばします。