PyTorch チュートリアル: 回帰、画像分類の例
Pytorch チュートリアルの概要
この PyTorch チュートリアルでは、すべての概念を最初から学習します。このチュートリアルでは、PyTorch の定義、PyTorch の長所と短所、比較、インストール、PyTorch フレームワーク、回帰、画像分類など、基本から高度なトピックまでをカバーしています。この PyTorch チュートリアルは完全に無料です。
PyTorch とは何ですか?
パイトーチ は、オープンソースのTorchベースの自然言語処理用機械学習ライブラリです。 PythonNumPy に似ていますが、強力な GPU サポートを備えています。autograd の助けを借りて、いつでも変更できる動的計算グラフを提供します。PyTorch は他のフレームワークよりも高速です。2016 年に Facebook の AI 研究グループによって開発されました。
PyTorch の長所と短所
PyTorch の利点と欠点は次のとおりです。
PyTorch の利点
- 簡易ライブラリ
PyTorchのコードはシンプルです。 分かりやすく、すぐにライブラリを利用できます。 たとえば、以下のコード スニペットを見てください。
class Net(torch.nn.Module): def __init__(self): super(Net, self).__init__() self.layer = torch.nn.Linear(1, 1) def forward(self, x): x = self.layer(x) return x
前述したように、ネットワーク モデルは簡単に定義でき、あまりトレーニングしなくてもコードをすぐに理解できます。
- 動的計算グラフ
画像ソース: PyTorch を使用したディープ ラーニングの探索
Pytorch は動的計算グラフ (DAG) を提供します。計算グラフは、ノードやエッジなどのグラフ モデルまたは理論で数式を表現する方法です。ノードは数学演算を実行し、エッジはノードに入力されてノードの出力をテンソルで運ぶテンソルです。
DAG は、任意の形状を保持し、異なる入力グラフ間で操作を実行できるグラフです。反復ごとに新しいグラフが作成されます。したがって、同じグラフ構造を持つことも、異なる操作で新しいグラフを作成することもできます。これを動的グラフと呼ぶこともできます。
- 性能向上
コミュニティと研究者は、フレームワークのベンチマークと比較を行い、どちらが速いかを確認します。 GitHub リポジトリ 深層学習フレームワークと GPU のベンチマーク XNUMX 秒あたりに処理される画像の点で、PyTorch は他のフレームワークよりも高速であると報告されました。
以下に示すように、vgg16 と resnet152 の比較グラフは次のとおりです。
- ネイティブ Python
PyTorch はより Python ベースです。 たとえば、モデルをトレーニングする場合、実行するために特別な変数やセッションを追加する必要がなく、ループや再帰などのネイティブ制御フローを使用できます。 これはトレーニングプロセスに非常に役立ちます。
Pytorch は命令型プログラミングも実装しており、間違いなくより柔軟です。 したがって、計算プロセスの途中でテンソル値を出力することが可能です。
PyTorchの欠点
PyTorch には視覚化用のサードパーティ アプリケーションが必要です。 実稼働用の API サーバーも必要です。
次に、この PyTorch チュートリアルでは、PyTorch と TensorFlow の違いについて学びます。
PyTorch とテンソルフロー
パイトーチ | テンソルフロー | |
---|---|---|
モデル定義 | モデルはサブクラスで定義され、使いやすいパッケージを提供します | モデルは多くの要素で定義されており、構文を理解する必要があります |
GPUのサポート | Yes | Yes |
グラフタイプ | ダイナミック | 静的 |
ツール | 視覚化ツールがない | Tensorboard視覚化ツールを使用できます |
コミュニティ | コミュニティは成長し続けています | 大規模なアクティブなコミュニティ |
PyTorch のインストール
Linux
Linux にインストールするのは簡単です。 仮想環境を使用するか、root アクセスで直接インストールするかを選択できます。 ターミナルにこのコマンドを入力します
pip3 install --upgrade torch torchvision
AWS セージメーカー
Sagemaker は、 Amazon ウェブサービス これは、データ サイエンティストや開発者があらゆる規模でモデルを構築、トレーニング、デプロイできるように、プリインストールされた深層学習構成を備えた強力な機械学習エンジンを提供します。
最初に開きます Amazon セージメーカー コンソールで「ノートブックインスタンスの作成」をクリックし、ノートブックの詳細をすべて入力します。
次のステップでは、「開く」をクリックしてノートブック インスタンスを起動します。
最後に、 Jupyter, [新規] をクリックして conda_pytorch_p36 を選択すると、Pytorch がインストールされたノートブック インスタンスを使用する準備が整います。
次に、この PyTorch チュートリアルでは、PyTorch フレームワークの基本について学びます。
PyTorch フレームワークの基本
詳しく調べる前に、PyTorch の基本的な概念を学びましょう。PyTorch は、NumPy の ndarray に似た Tensor をすべての変数に使用しますが、GPU 計算をサポートしています。ここでは、ネットワーク モデル、損失関数、Backprop、および Optimizer について説明します。
ネットワークモデル
torch.nn をサブクラス化することでネットワークを構築できます。 主要な部分は 2 つあり、
- 最初の部分は、使用するパラメータとレイヤーを定義することです。
- XNUMX 番目の部分は、入力を受け取り、出力を予測するフォワード プロセスと呼ばれるメイン タスクです。
Import torch import torch.nn as nn import torch.nn.functional as F class Model(nn.Module): def __init__(self): super(Model, self).__init__() self.conv1 = nn.Conv2d(3, 20, 5) self.conv2 = nn.Conv2d(20, 40, 5) self.fc1 = nn.Linear(320, 10) def forward(self, x): x = F.relu(self.conv1(x)) x = F.relu(self.conv2(x)) x = x.view(-1, 320) x = F.relu(self.fc1(x)) return F.log_softmax(x) net = Model()
上でわかるように、Model という名前の nn.Module のクラスを作成します。 2 つの Conv2d レイヤーと 2 つの Linear レイヤーが含まれています。 最初の conv3d 層は入力 20 と出力形状 20 を受け取ります。40 番目の層は入力 320 を受け取り、出力形状 10 を生成します。最後の層は完全に接続された層で形状 XNUMX を生成し、出力はXNUMX。
フォワード プロセスは X の入力を受け取り、それを conv1 層に供給して ReLU 関数を実行します。
同様に、conv2 レイヤーにもフィードします。 その後、x は (-1, 320) に再形成され、最後の FC レイヤーに入力されます。 出力を送信する前に、softmax アクティベーション関数を使用します。
逆方向プロセスは autograd によって自動的に定義されるため、前方向プロセスを定義するだけで済みます。
損失関数
損失関数は、予測モデルが期待される結果をどの程度正確に予測できるかを測定するために使用されます。 PyTorch には、torch.nn モジュールにすでに多くの標準損失関数があります。 たとえば、クロスエントロピー損失を使用して、マルチクラス PyTorch 分類問題を解決できます。 損失関数を定義して損失を計算するのは簡単です。
loss_fn = nn.CrossEntropyLoss() #training process loss = loss_fn(out, target)
PyTorch を使用すると、独自の損失関数計算を簡単に使用できます。
バックプロップ
バックプロパゲーションを実行するには、単に los.backward() を呼び出すだけです。 誤差は計算されますが、zero_grad() を使用して既存の勾配をクリアすることを忘れないでください。
net.zero_grad() # to clear the existing gradient loss.backward() # to perform backpropragation
オプティマイザ
torch.optim は一般的な最適化アルゴリズムを提供します。簡単な手順でオプティマイザーを定義できます。
optimizer = torch.optim.SGD(net.parameters(), lr = 0.01, momentum=0.9)
バックプロップ プロセスの後に反復ごとにパラメーターが更新されるように、ネットワーク モデルのパラメーターと学習率を渡す必要があります。
PyTorch を使用した単純な回帰
PyTorch の例で単純な回帰を学びましょう:
ステップ 1) ネットワーク モデルの作成
私たちのネットワーク モデルは、入力形状と出力形状が 1 の単純な線形層です。
from __future__ import print_function import torch import torch.nn as nn import torch.nn.functional as F from torch.autograd import Variable class Net(nn.Module): def __init__(self): super(Net, self).__init__() self.layer = torch.nn.Linear(1, 1) def forward(self, x): x = self.layer(x) return x net = Net() print(net)
そして、ネットワーク出力は次のようになります
Net( (hidden): Linear(in_features=1, out_features=1, bias=True) )
ステップ 2) テストデータ
トレーニング プロセスを開始する前に、データを知る必要があります。 モデルをテストするためにランダム関数を作成します。 Y = x3 sin(x)+3x+0.8ランド(100)
# Visualize our data import matplotlib.pyplot as plt import numpy as np x = np.random.rand(100) y = np.sin(x) * np.power(x,3) + 3*x + np.random.rand(100)*0.8 plt.scatter(x, y) plt.show()
関数の散布図は次のとおりです。
トレーニング プロセスを開始する前に、以下の PyTorch 回帰例に示すように、numpy 配列を Torch および autograd でサポートされる変数に変換する必要があります。
# convert numpy array to tensor in shape of input size x = torch.from_numpy(x.reshape(-1,1)).float() y = torch.from_numpy(y.reshape(-1,1)).float() print(x, y)
ステップ 3) オプティマイザと損失
次に、トレーニング プロセス用のオプティマイザーと損失関数を定義する必要があります。
# Define Optimizer and Loss Function optimizer = torch.optim.SGD(net.parameters(), lr=0.2) loss_func = torch.nn.MSELoss()
ステップ4) トレーニング
それでは、トレーニングプロセスを開始しましょう。 エポックを 250 として、データを反復処理して、ハイパーパラメータの最適な値を見つけます。
inputs = Variable(x) outputs = Variable(y) for i in range(250): prediction = net(inputs) loss = loss_func(prediction, outputs) optimizer.zero_grad() loss.backward() optimizer.step() if i % 10 == 0: # plot and show learning process plt.cla() plt.scatter(x.data.numpy(), y.data.numpy()) plt.plot(x.data.numpy(), prediction.data.numpy(), 'r-', lw=2) plt.text(0.5, 0, 'Loss=%.4f' % loss.data.numpy(), fontdict={'size': 10, 'color': 'red'}) plt.pause(0.1) plt.show()
ステップ5) 結果
以下に示すように、ニューラル ネットワークを使用して PyTorch 回帰が正常に実行されました。 実際には、反復のたびに、プロット内の赤い線が更新され、データに合わせて位置が変更されます。 ただし、この図では、以下の PyTorch の例に示すように、最終結果のみが表示されます。
PyTorch を使用した画像分類の例
の基本を学ぶための人気のある方法の XNUMX つ 深い学習 MNIST データセットです。これはディープラーニングの「Hello World」です。データセットには、0 から 9 までの手書きの数字が含まれ、合計 60,000 個のトレーニング サンプルと、10,000×28 ピクセルのサイズでラベル付け済みの 28 個のテスト サンプルが含まれています。
ステップ 1) データの前処理
この PyTorch 分類例の最初のステップでは、torchvision モジュールを使用してデータセットを読み込みます。
トレーニング プロセスを開始する前に、データを理解する必要があります。 トーチビジョンはデータセットをロードし、画像の形状や正規化などのネットワークに適切な要件に従って画像を変換します。
import torch import torchvision import numpy as np from torchvision import datasets, models, transforms # This is used to transform the images to Tensor and normalize it transform = transforms.Compose( [transforms.ToTensor(), transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))]) training = torchvision.datasets.MNIST(root='./data', train=True, download=True, transform=transform) train_loader = torch.utils.data.DataLoader(training, batch_size=4, shuffle=True, num_workers=2) testing = torchvision.datasets.MNIST(root='./data', train=False, download=True, transform=transform) test_loader = torch.utils.data.DataLoader(testing, batch_size=4, shuffle=False, num_workers=2) classes = ('0', '1', '2', '3', '4', '5', '6', '7', '8', '9') import matplotlib.pyplot as plt import numpy as np #create an iterator for train_loader # get random training images data_iterator = iter(train_loader) images, labels = data_iterator.next() #plot 4 images to visualize the data rows = 2 columns = 2 fig=plt.figure() for i in range(4): fig.add_subplot(rows, columns, i+1) plt.title(classes[labels[i]]) img = images[i] / 2 + 0.5 # this is for unnormalize the image img = torchvision.transforms.ToPILImage()(img) plt.imshow(img) plt.show()
変換関数は画像をテンソルに変換し、値を正規化します。 torchvision.transforms.MNIST 関数は、データセット (利用できない場合) をディレクトリにダウンロードし、必要に応じてトレーニング用のデータセットを設定し、変換プロセスを実行します。
データセットを視覚化するには、data_iterator を使用して画像とラベルの次のバッチを取得します。 matplot を使用して、これらのイメージとその適切なラベルをプロットします。 以下に示すように、画像とそのラベルが表示されます。
ステップ 2) ネットワークモデルの構成
この PyTorch の例では、PyTorch 画像分類用の単純なニューラル ネットワークを作成します。
ここでは、PyTorch でネットワーク モデルを作成する別の方法を紹介します。 nn.Module のサブクラスを作成する代わりに、nn.Sequential を使用してシーケンス モデルを作成します。
import torch.nn as nn # flatten the tensor into class Flatten(nn.Module): def forward(self, input): return input.view(input.size(0), -1) #sequential based model seq_model = nn.Sequential( nn.Conv2d(1, 10, kernel_size=5), nn.MaxPool2d(2), nn.ReLU(), nn.Dropout2d(), nn.Conv2d(10, 20, kernel_size=5), nn.MaxPool2d(2), nn.ReLU(), Flatten(), nn.Linear(320, 50), nn.ReLU(), nn.Linear(50, 10), nn.Softmax(), ) net = seq_model print(net)
これがネットワーク モデルの出力です。
Sequential( (0): Conv2d(1, 10, kernel_size=(5, 5), stride=(1, 1)) (1): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False) (2): ReLU() (3): Dropout2d(p=0.5) (4): Conv2d(10, 20, kernel_size=(5, 5), stride=(1, 1)) (5): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False) (6): ReLU() (7): Flatten() (8): Linear(in_features=320, out_features=50, bias=True) (9): ReLU() (10): Linear(in_features=50, out_features=10, bias=True) (11): Softmax() )
ネットワークの説明
- このシーケンスでは、最初の層は入力形状 2、出力形状 1、カーネル サイズ 10 の Conv5D 層です。
- 次に、MaxPool2D レイヤーを作成します。
- ReLU活性化関数
- 確率の低い値をドロップするドロップアウト層。
- 次に、最後の層からの入力形状 2、出力形状 10、カーネル サイズ 20 を持つ 5 番目の ConvXNUMXd
- 次は MaxPool2d レイヤーです
- ReLUアクティベーション機能。
- その後、テンソルを線形レイヤーにフィードする前に平坦化します。
- Linear Layer は、softmax アクティベーション関数を使用して XNUMX 番目の Linear Layer で出力をマッピングします。
ステップ 3) モデルをトレーニングする
トレーニング プロセスを開始する前に、基準とオプティマイザー関数を設定する必要があります。
基準には、CrossEntropyLoss を使用します。オプティマイザーには、以下の PyTorch の例に示すように、学習率 0.001、モーメンタム 0.9 の SGD を使用します。
import torch.optim as optim criterion = nn.CrossEntropyLoss() optimizer = optim.SGD(net.parameters(), lr=0.001, momentum=0.9)
順方向プロセスは入力形状を取得し、それを最初の conv2d 層に渡します。 次に、そこから maxpool2d にフィードされ、最終的に ReLU アクティベーション関数に入力されます。 同じプロセスが 2 番目の conv1,320d 層でも発生します。 その後、入力は (-XNUMX) に再整形され、fc 層に入力されて出力が予測されます。
ここで、トレーニングプロセスを開始します。 データセットを 2 回またはエポック 2 で反復処理し、2000 バッチごとに現在の損失を出力します。
for epoch in range(2): #set the running loss at each epoch to zero running_loss = 0.0 # we will enumerate the train loader with starting index of 0 # for each iteration (i) and the data (tuple of input and labels) for i, data in enumerate(train_loader, 0): inputs, labels = data # clear the gradient optimizer.zero_grad() #feed the input and acquire the output from network outputs = net(inputs) #calculating the predicted and the expected loss loss = criterion(outputs, labels) #compute the gradient loss.backward() #update the parameters optimizer.step() # print statistics running_loss += loss.item() if i % 1000 == 0: print('[%d, %5d] loss: %.3f' % (epoch + 1, i + 1, running_loss / 1000)) running_loss = 0.0
各エポックで、列挙子は入力と対応するラベルの次のタプルを取得します。 入力をネットワーク モデルにフィードする前に、前の勾配をクリアする必要があります。 これが必要なのは、逆方向プロセス (バックプロパゲーション プロセス) の後、勾配が置き換えられずに蓄積されるためです。 次に、期待出力から予測出力からの損失を計算します。 その後、バックプロパゲーションを実行して勾配を計算し、最後にパラメーターを更新します。
トレーニングプロセスの出力は次のとおりです
[1, 1] loss: 0.002 [1, 1001] loss: 2.302 [1, 2001] loss: 2.295 [1, 3001] loss: 2.204 [1, 4001] loss: 1.930 [1, 5001] loss: 1.791 [1, 6001] loss: 1.756 [1, 7001] loss: 1.744 [1, 8001] loss: 1.696 [1, 9001] loss: 1.650 [1, 10001] loss: 1.640 [1, 11001] loss: 1.631 [1, 12001] loss: 1.631 [1, 13001] loss: 1.624 [1, 14001] loss: 1.616 [2, 1] loss: 0.001 [2, 1001] loss: 1.604 [2, 2001] loss: 1.607 [2, 3001] loss: 1.602 [2, 4001] loss: 1.596 [2, 5001] loss: 1.608 [2, 6001] loss: 1.589 [2, 7001] loss: 1.610 [2, 8001] loss: 1.596 [2, 9001] loss: 1.598 [2, 10001] loss: 1.603 [2, 11001] loss: 1.596 [2, 12001] loss: 1.587 [2, 13001] loss: 1.596 [2, 14001] loss: 1.603
ステップ 4) モデルをテストする
モデルをトレーニングした後、他の画像セットを使用してテストまたは評価する必要があります。
test_loader のイテレータを使用して、トレーニング済みモデルに渡される画像とラベルのバッチを生成します。予測された出力が表示され、期待される出力と比較されます。
#make an iterator from test_loader #Get a batch of training images test_iterator = iter(test_loader) images, labels = test_iterator.next() results = net(images) _, predicted = torch.max(results, 1) print('Predicted: ', ' '.join('%5s' % classes[predicted[j]] for j in range(4))) fig2 = plt.figure() for i in range(4): fig2.add_subplot(rows, columns, i+1) plt.title('truth ' + classes[labels[i]] + ': predict ' + classes[predicted[i]]) img = images[i] / 2 + 0.5 # this is to unnormalize the image img = torchvision.transforms.ToPILImage()(img) plt.imshow(img) plt.show()
製品概要
- PyTorch はオープンソースのトーチベースです 機械学習 ライブラリ 自然言語処理 Python.
- PyTorchの利点: 1) シンプルなライブラリ、2) 動的な計算グラフ、3) 優れたパフォーマンス、4) ネイティブ Python
- PyTorch は、numpy の ndarray と同様に、すべての変数に Tensor を使用しますが、GPU 計算をサポートします。
- 深層学習の基礎を学ぶ一般的な方法の XNUMX つは、MNIST データセットを使用することです。