横浜国立大学理工学部建築都市環境系学科卒
一級鉄筋技能士
今回はpytorchについて、習得をしていきます。
pytorchは画像や自然言語などの機械学習開発ができるライブラリです。
他にも、Tensorflow、Kerasなどがありますが、最近はpytorchが人気です。
本記事のサンプルコード
目次
pytorchとは?
pytorchはFacebookに開発されたライブラリで、画像や自然言語などの機械学習開発ができます。
TensorflowはGoogleに開発されています。
どちらを使っても、開発ができますが、最近はpytorchが人気です。
Googleトレンド見ても、その傾向がわかりますね。
ちなみに、KerasはベースにTensorflowを使っていて、より開発がしやすくされているものです。
どれも、numpyのような行列演算をするもので、行列データ(配列)をTensor(テンソル)と言います。
どちらも、人気のライブラリなので、情報に不足することがありません。
違いは、pytorchはnumpyと同じ感覚で使えるという点です。
Tensorflowはモデルを決めたら、そのモデルが実行されるのですが、計算処理をデバッグしながら追いにくいなど初学者には使い方がわかりにくいです。
pytorchはnumpyと同じように、実行したら、その結果を受け取って、また次の計算と進んでいくので、感覚的にも馴染みやすいです。
インストール
pytorchは下記の公式より、OSなどを選択して、インストールします。
NVIDIAのGPUを搭載してないパソコンで使う方は、CUDAをNoneとします。
Run this Commandをコピーして、インストールしましょう。
pytorchの使い方
pytorchはnumpyと似ているのが特徴ですが、pytorchのTensorからnumpy(ndarray)に変換することも多いです。
機械学習のモデルは自分で作らなくても、すでに作ってあるものを読み込むことが多いですが、最終的に出力された結果はTensorで出てくるので、このTensorが操作ができなければいけません。
そのためにも、ここでTensorの使い方を理解していきましょう。
ライブラリの読み込み
ライブラリの読み込みは次のようになります。
1 |
import torch |
numpyも使うので、numpyも一緒に読み込みます。
1 2 |
import torch import numpy as np |
テンソルの作成
基本的に、numpyと同じような方法になります。
乱数,0,1,の作成
まず、乱数、0、1のテンソルを作っていきます。
メソッド | 機能 |
rand | 0以上、1未満の乱数のテンソル |
ones | 1のテンソル |
zeros | 0のテンソル |
引数に次元数やデータ数を決めます。
今回は、2次元の2×3のデータを作ります。
1 2 3 4 |
shape = (2,3) rand_tensor = torch.rand(shape) ones_tensor = torch.ones(shape) zeros_tensor = torch.zeros(shape) |
乱数の結果を見てみます。
1 |
print(rand_tensor) |
1 2 |
tensor([[0.0263, 0.9624, 0.6261], [0.6330, 0.5714, 0.0918]]) |
0-1の乱数ができています。
最初の方にtensorとありますね。tensorでできていることとがわかります。
他の、ones_tensorもzeros_tensorもそれぞれ1と0が入っています。
listから作成
listからテンソルを作成します。
作成するデータは、1から6の2次元の2×3とします。
1 2 3 |
data = [[1, 2, 3],[4, 5, 6]] x_data = torch.tensor(data) print(x_data) |
1 2 |
tensor([[1, 2, 3], [4, 5, 6]]) |
numpyから作成
listだけでなく、numpyからもテンソルが作成できます。
1 2 3 4 |
data = [[1, 2, 3],[4, 5, 6]] np_array = np.array(data) x_data = torch.tensor(np_array) print(x_data) |
1 2 |
tensor([[1, 2], [3, 4]], dtype=torch.int32) |
dtype=torch.int32となっているのは、pytorchの型になります。
int32は整数型で、32は32ビットを表していて、この数字で表現できる数値の大きさが決まります。
tensorからnumpyの変換
numpyからtensorを作る方法を見ましたが、逆の方法です。
1 2 3 4 |
x_data = torch.tensor([[1, 2, 3],[4, 5, 6]]) print('変換前', x_data) np_array = x_data.to('cpu').detach().numpy().copy() print('変換後', np_array) |
1 2 3 4 |
変換前 tensor([[1, 2, 3], [4, 5, 6]]) 変換後 [[1 2 3] [4 5 6]] |
機械学習で推論したあとは、numpyに取り出して、処理することがあります。
to(‘cpu’)となっているところは、次で紹介しますが、numpyにするときは必ず入れておきましょう。
デバイスの設定
テンソルにはデバイスの設定があります。
簡単に言えば、テンソルがCPUとGPUどちらを使って計算するかの設定です。
GPUが使えるかはtorch.cuda.is_available()がTrue /Falseで返してくるので、次のようなコードで設定するデバイスを決めます。
1 2 |
device = "cuda" if torch.cuda.is_available() else "cpu" print(device) |
1 |
cuda |
NVIDIAのGPUのパソコンで、cudaやcudnnの設定がしてあれば、cudaとなります。
それ以外は、cpuとなります。
設定する場合はtoを使います。
1 |
x_data = x_data.to(device) |
意図的にCPUを使いたい場合は、to(‘cpu’)とすればOKです。
GPUが複数使える場合、’cuda’としていますが、’cuda:デバイスNo’とすることで、GPUのデバイスを指定することができます。
デバイスNoは0から始まる数字です。
テンソルの確認
次にテンソルの情報についてみていきます。
次のデータについてみていきます。
1 2 |
data = [[1, 2, 3],[4, 5, 6]] x_data = torch.tensor(data) |
属性 | 機能 |
shape | 次元とデータ数を確認 |
dtype | 型の確認 |
device | デバイスの確認 |
形
形は次元数、データ数です。
1 |
print(x_data.shape) |
1 |
torch.Size([2, 3]) |
型のタイプ
テンソルのデータの型のタイプを確認します。
1 |
print(x_data.dtype) |
1 |
torch.int64 |
デバイス
テンソルに設定されているデバイスを確認します。
1 |
print(x_data.device) |
1 |
cpu |
テンソルからデータを取り出す
tensorはnumpyと同じように座標を指定したり、開始No:終了Noを使って範囲を指定した取得もできます。
numpyと同じなので、簡単にいくつか紹介します。
1から9の3×3のデータを使います。
1 2 3 4 5 6 7 8 9 |
data = [[1, 2, 3], [4, 5, 6], [7, 8, 9]] x_data = torch.tensor(data) print('座標指定 ', x_data[1,2]) print('範囲指定(全行,2-3列) ', x_data[:, 1:3]) print('範囲指定(1-2行:全列) ', x_data[0:2, :]) print('範囲指定(1-2行,2-3列)', x_data[0:2, 1:3]) |
1 2 3 4 5 6 7 8 |
座標指定 tensor(6) 範囲指定(全行,2-3列) tensor([[2, 3], [5, 6], [8, 9]]) 範囲指定(1-2行:全列) tensor([[1, 2, 3], [4, 5, 6]]) 範囲指定(1-2行,2-3列) tensor([[2, 3], [5, 6]]) |
テンソルの計算
次はテンソル同士の計算を紹介します。
四則演算
まず、四則演算を計算します。
使うのは次の2つのデータを使います。
1 2 3 4 5 6 |
data1 = [[2, 4, 6], [8, 10, 12]] x_data1 = torch.tensor(data1) data2 = [[1, 2, 3], [4, 5, 6]] x_data2 = torch.tensor(data2) |
計算してみます。
1 2 3 4 |
print('足し算', x_data1+x_data2) print('引き算', x_data1-x_data2) print('掛け算', x_data1*x_data2) print('割り算', x_data1//x_data2) |
1 2 3 4 5 6 7 8 |
足し算 tensor([[ 3, 6, 9], [12, 15, 18]]) 引き算 tensor([[1, 2, 3], [4, 5, 6]]) 掛け算 tensor([[ 2, 8, 18], [32, 50, 72]]) 割り算 tensor([[2, 2, 2], [2, 2, 2]]) |
pytorchでもブロードキャストが使えます。
1 |
print('足し算+ブロードキャスト', x_data1+2) |
1 2 |
足し算+ブロードキャスト tensor([[ 4, 6, 8], [10, 12, 14]]) |
足したのは2を1つだけですが、x_dataの全てに足されます。
行列の積
行列の積にはmatmulを使います。
次の2×3と3×2の積を計算します。
1 2 3 4 5 6 7 8 |
data1 = [[2, 4, 6], [8, 10, 12]] x_data1 = torch.tensor(data1) data2 = [[1, 2], [3, 4], [5, 6]] x_data2 = torch.tensor(data2) print(torch.matmul(x_data1, x_data2)) |
1 2 |
tensor([[ 44, 56], [ 98, 128]]) |
転置
テンソルの転置はtを使います。
1 2 3 4 |
data1 = [[2, 4, 6], [8, 10, 12]] x_data1 = torch.tensor(data1) print(x_data1.t()) |
1 2 3 |
tensor([[ 2, 8], [ 4, 10], [ 6, 12]]) |
転置はWikiにわかりやすい図があります。
次元データ数の入れ替え
画像データを取り扱うと、高さ×幅×chの3次元で取得できます。
これをch×高さ×幅と入れ替る時があります。
その時はtranspose(次元No, 次元No)を使います。
次元Noには、入れ替える次元を2つ入れます。
64×32×3のデータで確認します。
1 2 3 4 5 6 7 8 9 |
x_data = torch.rand(64, 32, 3) print('変更前', x_data.shape) # 1次元と3次元目を入れ替え x_data = x_data.transpose(0, 2) print('変更後1', x_data.shape) # 2次元と3次元目を入れ替え x_data = x_data.transpose(1, 2) print('変更後2', x_data.shape) |
1 2 3 |
変更前 torch.Size([64, 32, 3]) 変更後1 torch.Size([3, 32, 64]) 変更後2 torch.Size([3, 64, 32]) |
まとめ
以上がpytorchの使い方です。
numpyとほとんど同じだったと思います。
最初の方は、pytorchのライブラリに入っているモデルをそのまま使っていきます。
最初の教師データの読み込みと推論結果の処理をすることが多いので、ここら辺の知識をしっかり抑えておくとよいです。