PyTorchを使ったDeep Learningのお勉強 基礎編
ディープラーニング界隈では流行っていると噂のPyTorchを使ってディープラーニングの実装をやってみる
Pythonの機械学習ライブラリになるわけですが、ようやくここまで追いついてきたって感じ
それにしても、独学での道のりは長いな~~
PyTorch お勉強シリーズ
第1回 PyTorchを使ったDeep Learningのお勉強 基礎編(イマココ)
第2回 PyTorchを使ったDeep Learningのお勉強 PyTorch Lightning編
第3回 PyTorchを使ってDeep Learningのお勉強 TensorBoard編
第4回 PyTorchを使ったDeep Learningのお勉強 画像認識編(MNIST)
第5回 PyTorchを使ったDeep Learningのお勉強 画像認識編(CIFAR-10)
ということではじめてのPyTorch
PyTorch インストール
anaconda環境を使っている場合はインストールは至って簡単
anaconda上でPyTorch用にPythonの仮想環境を作って、検索してインストールするだけ
(なんとなく TesorFlow環境とは分けておきたかった)
Google Colab上では、デフォルトでPyTorchインストールされているので、超簡単にお試しができてよいですね
colab.research.google.com
バージョン確認
ちゃんとインストールできていればこんな感じでバージョンが出力されることでしょう
import torch torch.__version__ >>> 出力: '1.4.0'
PyTorch とりあえずの基礎
PyTorchの行列
numpy.ndarrayと同等な感じで扱います
torch.zeros(2,4) >>> 出力: tensor([[0., 0., 0., 0.], [0., 0., 0., 0.]])
torch.randn(2,4) >>> 出力: tensor([[ 1.2333, -0.1832, -1.3140, -1.6894], [ 1.2525, -0.5545, 0.3019, 1.1295]])
層の定義
PyTorchでは、一気に層の重みとバイアスを定義してしまえる
こんな風に書くと
import torch.nn as nn # 乱数シードの固定 torch.manual_seed(1) # 全結合層の定義 fc = nn.Linear(3, 2) # 入力と出力の数
この重み(W)とバイアス(b)の初期値を一気に定義してくれます
中身を確認
print(fc.weight) print(fc.bias) >>> 出力: Parameter containing: tensor([[ 0.2975, -0.2548, -0.1119], [ 0.2710, -0.5435, 0.3462]], requires_grad=True) Parameter containing: tensor([-0.1188, 0.2937], requires_grad=True)
入力値の定義
次に入力にあたるXを3個定義してやります
# リストから PyTorch の Tensor に変換、データ型に注意 X = torch.tensor([[1,2,3]], dtype=torch.float32) print(X.shape) X.dtype >>>出力: torch.Size([1, 3]) torch.float32
線形変換
では、早速計算をしてやります
事前に定義した fc に X を与えてやるだけで
y = fc(X) y >>> 出力: tensor([[ 0.9894, -2.0327]], grad_fn=<AddmmBackward>)
つまりこの計算を一行でやってくれてます、ラクチン
非線形変換
次に活性化関数のReLuを試してみます(0以下を0に変換しちゃう関数)
#非線形変換 import torch.nn.functional as F # ReLU 関数 z = F.relu(y) z >>> 出力: tensor([[0.9894, 0.0000]], grad_fn=<ReluBackward0>)
多層化
階層をこんな感じで多層化する場合
定義も複数してやります
# 全結合層の定義 fc1 = nn.Linear(3, 2) #一層目を定義 fc2 = nn.Linear(2, 1) #二層目を定義 X = torch.tensor([[1,2,3]], dtype=torch.float32) #入力Xを定義 # 一層目の計算 h1 = fc1(x) z1 = F.relu(h1) #ReLu # 二層目の計算 u2 = fc2(z1) u2
PyTorchのコスト関数(損失関数)
予測した数値と正解データの間の差を定量化したコスト関数(損失関数)ですが、
Pytorchであらかじめ定義してくれているので、これまたラクチン
計算式を都度都度思い出さなくてもよいのです
問題 | PyTorch定義 | 損失関関数 |
---|---|---|
回帰 | nn.MSELoss | 平均二乗誤差 |
多クラス分類 | nn.CrossEntropyLoss | ソフトマックス交差エントロピ誤差 |
nn.MSELoss - PyTorch 1.4
https://pytorch.org/docs/stable/nn.html#torch.nn.MSELoss
nn.CrossEntropyLoss - PyTorch 1.4
https://pytorch.org/docs/stable/nn.html#crossentropyloss
簡単に実装してみるとこんな感じ
import torch import torch.nn as nn # MSELoss 平均二乗誤差 x = torch.randn(4) y = torch.randn(4) print("x: ",x) print("y: ",y) criterion = nn.MSELoss() loss = criterion(x, y) print("MSELoss: ",loss) # CrossEntropyLoss ソフトマックス交差エントロピ誤差 x = torch.randn(1, 4) y = torch.LongTensor([1]).random_(4) criterion = nn.CrossEntropyLoss() loss = criterion(x, y) print("CrossEntropyLoss: ",loss)
>>> 出力:
x: tensor([0.7670, 0.6899, 0.3282, 0.5085]) y: tensor([-0.0515, -0.6248, 0.2844, -0.9130]) MSELoss: tensor(1.1053) CrossEntropyLoss: tensor(1.2331)
コードの中では、こんな風に使うみたいです
# コスト関数の設定 criterion = nn.CrossEntropyLoss() # ロスの計算(y:計算結果、t:正解ラベル) loss = criterion(y, t) # 勾配の計算 loss.backward()
PyTorchの重みの更新(最適化)
コスト関数で導いたロスから、パラメータ(重みとバイアス)の学習する方法
どの最適化手法を使うかは、こんな感じで
あらかじめ用意されているので、計算式を覚えておく必要ないですね
import torch import torch.optim as optim # 最適化手法をどれか選択 optimizer = optim.SGD(net.parameters(), lr=0.1) optimizer = optim.Adagrad(net.parameters()) optimizer = optim.RMSprop(net.parameters()) optimizer = optim.Adam(net.parameters(), lr=1e-1, betas=(0.9, 0.99), eps=1e-09)
パラメータ更新はロスの計算、勾配計算の後に実行
optimizer.step()
GPUを使った計算処理
PyTorchでGPUを使った処理をする場合
まずはGPUが使える環境なのかチェック
# GPU の設定状況に基づいたデバイスの選択 device = torch.device('cuda:0' if torch.cuda.is_available() else 'cpu') device >>> 出力: device(type='cuda', index=0)
GPUが使える環境であるならば、データGPUへ転送してやることで
GPUを使った計算が行えます
x = torch.randn(4) x = x.to(device) >>>出力: tensor([-0.5593, -0.1197, -0.1635, -0.2505], device='cuda:0')
device='cuda:x'ってついてればOK
PyTorchを使った順伝播の実装
というわけで、早速PyTorchの実装実験してみる
scikit-learn に用意されている Iris という「アヤメの品種」を分類する問題を2層で定義して、学習から検証までを一つにまとめて書いてみた
とりあえずの基礎はここまで