4
3

More than 1 year has passed since last update.

Pytorch を久しぶりにさわる前に見るやつ(途中)

Last updated at Posted at 2020-05-15

import

.py
import torch

最低これは必要。むしろこんなレベルで忘れるとか、どうなってるのかと。

import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
from torchvision import datasets, transforms

多分、これくらいないと最低限も使えない。

tensor の作成

参考:

要素を指定して作成

次元数はいくつでも作れる。2次元以上の場合、要素の数が列と行であってないとエラーになる。

.py
>>> x = torch.tensor([1,2,3,4,5])
>>> x
tensor([1, 2, 3, 4, 5])

>>> x = torch.tensor([[1,2,3],[4,5,6]])
>>> x
tensor([[1, 2, 3],
        [4, 5, 6]])

>>> x = torch.tensor([[[1,2],[3,4]],[[5,6],[7,8]]])
>>> x
tensor([[[1, 2],
         [3, 4]],

        [[5, 6],
         [7, 8]]])

0 や 1 で初期化して作成

.py
>>> x = torch.zeros(2,3)
>>> x
tensor([[0., 0., 0.],
        [0., 0., 0.]])

>>> x = torch.ones(2,3)
>>> x
tensor([[1., 1., 1.],
        [1., 1., 1.]])

2 で初期化したければ、1 で初期化した上で2倍する。

.py
>>> x = torch.ones(2,3)
>>> x
tensor([[1., 1., 1.],
        [1., 1., 1.]])
>>> y = x * 2
>>> y
tensor([[2., 2., 2.],
        [2., 2., 2.]])

ランダムに作成

(0, 1) の一様にランダムな float 値で 4x5 の行列を生成する。

.py
>>> x = torch.rand(4,5)
>>> x
tensor([[0.5477, 0.8997, 0.3783, 0.0031, 0.6420],
        [0.2774, 0.3532, 0.9457, 0.5091, 0.3471],
        [0.3089, 0.0933, 0.8736, 0.7133, 0.2644],
        [0.8568, 0.8609, 0.2354, 0.2613, 0.8367]])

正規分布にするなら randn にする。

.py
>>> x = torch.randn(4,5)
>>> x
tensor([[ 1.0334, -0.3700, -0.4751, -0.1441,  0.7601],
        [-0.3379,  1.6306, -1.0848, -0.3700,  0.6873],
        [-1.0197, -0.3172, -0.7064,  0.0902, -0.1624],
        [-0.5472,  0.7175, -0.8284, -0.4853, -0.9506]])

連続した数値

0 から 9 までの連続した整数で行列を作る。

.py
>>> x = torch.arange(0,10)
>>> x
tensor([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

等差数列の差を指定する。

.py
>>> x = torch.arange(0,5,0.5)
>>> x
tensor([0.0000, 0.5000, 1.0000, 1.5000, 2.0000, 2.5000, 
        3.0000, 3.5000, 4.0000, 4.5000])

dataloader を使う

MNIST のデータを使う場合。

.py
from torch.utils.data import DataLoader
from torchvision import transforms
from torchvision.datasets import MNIST


data = MNIST(root='../data', 
       train=False, 
       download=True, 
       transform=transforms.ToTensor())

data_loader = DataLoader(data, batch_size=2, shuffle=True)

for i, data in enumerate(data_loader):
    x, y = data

x,y を表示させると下記のようになる。

.py
>>> x
tensor([[[[0., 0., 0.,  ..., 0., 0., 0.],
          [0., 0., 0.,  ..., 0., 0., 0.],
          [0., 0., 0.,  ..., 0., 0., 0.],
          ...,
          [0., 0., 0.,  ..., 0., 0., 0.],
          [0., 0., 0.,  ..., 0., 0., 0.],
          [0., 0., 0.,  ..., 0., 0., 0.]]],


        [[[0., 0., 0.,  ..., 0., 0., 0.],
          [0., 0., 0.,  ..., 0., 0., 0.],
          [0., 0., 0.,  ..., 0., 0., 0.],
          ...,
          [0., 0., 0.,  ..., 0., 0., 0.],
          [0., 0., 0.,  ..., 0., 0., 0.],
          [0., 0., 0.,  ..., 0., 0., 0.]]]])
>>> y
tensor([7, 1])

batch を 2 にしているので、モノクロ画像(28x28 pixel の 0-1 の間の数値)と、画像に対するラベル(0-9の数値)のデータがそれぞれ x, y に 2 つずつ入る。画素のデータは、0-255 の値を 0-1 になるように正規化されたものらしい。

上の表示例では、行列の途中の値が省略されて表示されているため、すべての画素の値が 0 になっているように見えるが、行列の要素をすべて表示させてみると、0 でないデータも入っていることが確認できる。

MNIST関数

  • 公式ドキュメント
  • root: データをダウンロードするディレクトリ。なければ作成される。
  • train: True なら training.pt から作成。False なら test.pt から作成。
  • download: ローカルにデータが無い場合にダウンロードするなら True、しないなら False
  • transform: データに行なう前処理。デフォルトでは None。Compose を使って作成する。変換しない場合でも、演算するなら transform.ToTensor() を指定する必要あり。

dataloader

  • 公式ドキュメント
  • batch_size: 読み込むデータの個数。デフォルトは 1。
  • shuffle: True ならデータをシャッフルしてから読み込む。False なら元データの順序通りに読み込む。

参考

行列操作

index 操作

index.py
>>> y
tensor([[ 0,  1,  2,  3,  4,  5],
        [ 6,  7,  8,  9, 10, 11],
        [12, 13, 14, 15, 16, 17],
        [18, 19, 20, 21, 22, 23]])

>>> y[0,0]
tensor(0)

>>> y[:,0]
tensor([ 0,  6, 12, 18])

>>> y[1,:]
tensor([ 6,  7,  8,  9, 10, 11])


転置

y = tensor.t(x)

次元を減らす

y = torch.flatten(x)

item

Tensor 型から、python の数値型の値を取り出す。

>>> x = torch.tensor([1])
>>> x
tensor([1])

>>> x.item()
1

>>> x[0]
tensor(1)

演算

加減算

そのまま書ける。行列のサイズがあっている必要あり。

.py
>>> x
tensor([[1., 1., 1.],
        [1., 1., 1.]])

>>> y
tensor([[2., 2., 2.],
        [2., 2., 2.]])

>>> z = x + y
>>> z
tensor([[3., 3., 3.],
        [3., 3., 3.]])

>>> w = z - y
>>> w
tensor([[1., 1., 1.],
        [1., 1., 1.]])
>>> 

積算

行列積は torch.mm を使う。

.py
>>> x
tensor([[1, 1, 1],
        [2, 2, 2],
        [3, 3, 3]])

>>> y
tensor([[1, 2, 3],
        [2, 3, 4],
        [5, 6, 7]])

>>> a = torch.mm(x,y)
>>> a
tensor([[ 8, 11, 14],
        [16, 22, 28],
        [24, 33, 42]])

アスタリスク * を使うと、行列の要素間の積になる。

.py
>>> x
tensor([[1, 1, 1],
        [2, 2, 2],
        [3, 3, 3]])

>>> y
tensor([[1, 2, 3],
        [2, 3, 4],
        [5, 6, 7]])

>>> z = x * y
>>> z
tensor([[ 1,  2,  3],
        [ 4,  6,  8],
        [15, 18, 21]])

>>> w = y * z
>>> w
tensor([[  1,   4,   9],
        [  8,  18,  32],
        [ 75, 108, 147]])

内積

torch.dot を使う。

.py
>>> x = torch.tensor([1,2,3])
>>> y = torch.tensor([4,5,6])
>>> z = torch.dot(x,y)
>>> z
tensor(32)

ベクトルと行列の積

torch.mv を使う。

.py
>>> x = torch.tensor([1,2,3])
>>> y = torch.tensor([[1,2,3],[3,4,5],[5,6,7]])
>>> z = torch.mv(y,x)
>>> z
tensor([14, 26, 38])

matmul

引数を見て、mm, dot, mv のうち適切なものを使う。しかし、適切というのが結構あやしい。

sum

オプションなしなら、行列の中身をすべて加算した結果を返す。dim で和を取る次元を指定できる。二次元配列の場合、0なら列、1なら行の和を取る。keepdim=True で行列の次元数を減らさないまま結果を返す。

z.sum() という書き方も受け付けられる。

sum.py
>>> z = torch.ones(4,6)
>>> z
tensor([[1., 1., 1., 1., 1., 1.],
        [1., 1., 1., 1., 1., 1.],
        [1., 1., 1., 1., 1., 1.],
        [1., 1., 1., 1., 1., 1.]])

>>> torch.sum(z)
tensor(24.)

>>> torch.sum(z,dim=0)
tensor([4., 4., 4., 4., 4., 4.])

>>> torch.sum(z,dim=1)
tensor([6., 6., 6., 6.])

>>> z.sum()
tensor(24.)

>>> z.sum(dim=0)
tensor([4., 4., 4., 4., 4., 4.])

>>> torch.sum(z,dim=1,keepdim=True)
tensor([[6.],
        [6.],
        [6.],
        [6.]])
4
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
3