PyTorch チュートリアル: 回帰、画像分類の例

Pytorch チュートリアルの概要

この pytorch チュートリアルでは、すべてのことを学びます。 concepts ゼロから。このチュートリアルでは、pytorch の定義、pytorch の利点と欠点、比較、インストール、pytorch フレームワーク、回帰、画像分類などの基本的なトピックから高度なトピックまでを取り上げます。この pytorch チュートリアルは完全に無料です。

PyTorch とは何ですか?

パイトーチ は、Python を使用した自然言語処理のためのオープンソースの Torch ベースの機械学習ライブラリです。 NumPy に似ていますが、強力な GPU サポートを備えています。 autograd を使用して外出先で変更できる動的計算グラフを提供します。 PyTorch は他のフレームワークよりも高速です。 2016 年に Facebook の AI 研究グループによって開発されました。

PyTorch の長所と短所

Following PyTorch の長所と短所は次のとおりです。

PyTorch の利点

  1. 簡易ライブラリ
    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

前述したように、ネットワーク モデルは簡単に定義でき、あまりトレーニングしなくてもコードをすぐに理解できます。

  1. 動的計算グラフ

動的計算グラフ

画像ソース: PyTorch を使用したディープ ラーニングの探索

Pytorch は動的計算グラフ (DAG) を提供します。計算グラフは、ノードやエッジなどのグラフ モデルまたは理論で数式を表現する方法です。ノードは数学的な処理を行います operaエッジはノードに供給される Tensor であり、Tensor でノードの出力を伝送します。

DAGは任意の形状を保持し、次のことができるグラフです。 opera異なる入力グラフ間の関係。反復ごとに、新しいグラフが作成されます。したがって、同じグラフ構造を持つことも、異なるグラフ構造で新しいグラフを作成することも可能です。 operaまたは、動的グラフと呼ぶこともできます。

  1. パフォーマンスの向上

コミュニティと研究者は、フレームワークのベンチマークと比較を行い、どちらが速いかを確認します。 GitHub リポジトリ 深層学習フレームワークと GPU のベンチマーク XNUMX 秒あたりに処理される画像の点で、PyTorch は他のフレームワークよりも高速であると報告されました。

以下に示すように、vgg16 と resnet152 の比較グラフは次のとおりです。

PyTorch の利点

PyTorch の利点

  1. ネイティブ Python

PyTorch はより Python ベースです。 たとえば、モデルをトレーニングする場合、実行するために特別な変数やセッションを追加する必要がなく、ループや再帰などのネイティブ制御フローを使用できます。 これはトレーニングプロセスに非常に役立ちます。

Pytorch は命令型プログラミングも実装しており、間違いなくより柔軟です。 したがって、計算プロセスの途中でテンソル値を出力することが可能です。

PyTorchの欠点

PyTorch には視覚化用のサードパーティ アプリケーションが必要です。 実稼働用の API サーバーも必要です。

次に、この PyTorch チュートリアルでは、PyTorch と TensorFlow の違いについて学びます。

PyTorch とテンソルフロー

パイトーチ テンソルフロー
モデル定義 モデルはサブクラスで定義され、使いやすいパッケージを提供します モデルは多くの要素で定義されており、構文を理解する必要があります
GPUのサポート はい はい
グラフタイプ ダイナミック 静的
ツール 視覚化ツールがない Tensorboard視覚化ツールを使用できます
通信unity 通信unity まだグロwing 大規模なアクティブなコミュニティ

PyTorch のインストール

Linux

Linux にインストールするのは簡単です。 仮想環境を使用するか、root アクセスで直接インストールするかを選択できます。 ターミナルにこのコマンドを入力します

pip3 install --upgrade torch torchvision

AWS セージメーカー

Sagemaker は、 Amazon ウェブサービス これは、データ サイエンティストや開発者があらゆる規模でモデルを構築、トレーニング、デプロイできるように、プリインストールされた深層学習構成を備えた強力な機械学習エンジンを提供します。

最初に開きます Amazon セージメーカー コンソールで [ノートブック インスタンスの作成] をクリックし、すべての情報を入力します。tails あなたのノートのために。

AWS セージメーカー

次のステップでは、「開く」をクリックしてノートブック インスタンスを起動します。

AWS セージメーカー

最後に、 Jupyter, [新規] をクリックして conda_pytorch_p36 を選択すると、Pytorch がインストールされたノートブック インスタンスを使用する準備が整います。

次に、この PyTorch チュートリアルでは、PyTorch フレームワークの基本について学びます。

PyTorch フレームワークの基本

基本を学びましょう concepts 深く掘り下げる前に、PyTorch について説明します。 PyTorch は、numpy の ndarray と同様に、すべての変数に Tensor を使用しますが、GPU 計算をサポートします。ここではネットワークモデル、損失関数、Backprop、Optimizerについて説明します。

ネットワークモデル

torch.nn をサブクラス化することでネットワークを構築できます。 主要な部分は 2 つあり、

  1. 最初の部分は、使用するパラメータとレイヤーを定義することです。
  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 は共通の最適化を提供します algorithms。オプティマイザは次の簡単な手順で定義できます。

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 を使用した単回帰の散布図

トレーニング プロセスを開始する前に、以下の 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」です。データセットには手書きが含まれています numbers 0 ~ 9 で、合計 60,000 個のトレーニング サンプルと 10,000 個のテスト サンプルがすでに 28×28 ピクセルのサイズでラベル付けされています。

PyTorch による画像分類

ステップ 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 を使用して、これらのイメージとその適切なラベルをプロットします。 以下に示すように、画像とそのラベルが表示されます。

PyTorch を使用した画像分類の例

ステップ 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()
)

ネットワークの説明

  1. このシーケンスでは、最初の層は入力形状 2、出力形状 1、カーネル サイズ 10 の Conv5D 層です。
  2. 次に、MaxPool2D レイヤーを作成します。
  3. ReLU活性化関数
  4. 確率の低い値をドロップするドロップアウト層。
  5. 次に、最後の層からの入力形状 2、出力形状 10、カーネル サイズ 20 を持つ 5 番目の ConvXNUMXd
  6. 次は MaxPool2d レイヤーです
  7. ReLUアクティベーション機能。
  8. その後、テンソルを線形レイヤーにフィードする前に平坦化します。
  9. Linear Layer は、softmax アクティベーション関数を使用して XNUMX 番目の Linear Layer で出力をマッピングします。

ステップ 3) モデルをトレーニングする

トレーニング プロセスを開始する前に、基準とオプティマイザー関数を設定する必要があります。

基準には、CrossEntropyLoss を使用します。オプティマイザーの場合、学習率 0.001 の SGD を使用します。 momentum 以下の PyTorch の例に示すように、0.9 です。

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 のイテレータを使用し、トレーニングされたモデルに渡される画像とラベルのバッチを生成します。予測される出力は次のようになります。yed 予想される出力と比較します。

#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 を使用した画像分類の例

まとめ

  • PyTorch はオープンソースのトーチベースです 機械学習 ライブラリ 自然言語処理 Pythonを使用します。
  • PyTorch の利点: 1) シンプルなライブラリ、2) 動的計算グラフ、3) パフォーマンスの向上、4) ネイティブ Python
  • PyTorch は、numpy の ndarray と同様に、すべての変数に Tensor を使用しますが、GPU 計算をサポートします。
  • 深層学習の基礎を学ぶ一般的な方法の XNUMX つは、MNIST データセットを使用することです。