PyTorchとは?概要と導入方法をチェックしよう!

Deep Learningのフレームワークについて、以前紹介記事を書きました。

Tensorflowだけじゃない?ディープラーニングフレームワーク8選!
更新日:2024年3月1日

この記事では、その記事でも紹介した深層学習フレームワークの一つ、PyTorchについて紹介します!

Deep Learning研究の分野で大活躍のPyTorch、書きやすさと実効速度のバランスが取れたすごいライブラリです。

※ この記事のコードはPython 3.6, PyTorch 1.0で動作確認しました。

目次

PyTorchとは

引用元:PyTorch https://pytorch.org/tutorials/

PyTorchの特徴

PyTorchは、Python向けのDeep Learningライブラリです。

Facebookが開発を主導し、その書きやすさと使いやすさから人気があります。

このライブラリは非常に柔軟なニューラルネットワークの記述ができ、今主流であるDeep Learningライブラリの中でもかなりの人気を誇ります。

公式ページ: https://pytorch.org/
Githubリポジトリ:https://github.com/pytorch/pytorch

公式ページのaboutによると

  • 強力なGPUアクセラレーションによるテンソル計算
  • (リバースモードの)自動微分を使いシンプルなニューラルネットワークの記述が可能


などの特徴を持ちます。

Deep Learningの世界ではGPUを使ったアクセラレーション(高速化)は必須です。これは有名なDeep Learningフレームワークならば殆どが備える機能です。

また、自動微分についても同様です。

このPyTorchはNumpy、Scipy、Cythonなどの、Pythonでの科学計算でよく使うライブラリによって拡張することができます。

そのため、細かいところまでPythonでカスタマイズする事ができます。最新のDeep Learningモデルを実装するにはうってつけのライブラリですね。

また、Chainerという国産ライブラリに非常に似た使い心地なので、Chainerを使ったことがあるユーザーならば簡単に習得することができるでしょう。

PyTorchは人気のフレームワーク

Githubでの注目具合を見てみましょう。

このグラフは、「Deep Learningの主要フレームワーク」のGithub Star数です。

Tensorflow、Kerasに続き第三位の位置にあります。PyTorchはTensorflowに比べてやや後発なのですが、健闘していますね。

TensorflowがGoogleの強力なバックアップで開発と宣伝が進められている点を考慮すると、PyTorchの人気具合がわかるかと思います。

教材の豊富さ

PyTorchの解説動画も大量にあるので、勉強も比較的容易です。

また、書籍も数多く発表されています。

[つくりながら学ぶ! 深層強化学習 ~PyTorchによる実践プログラミング~ 単行本(ソフトカバー) – 2018/6/28 株式会社電通国際情報サービス 小川雄太郎 (著)]

[PyTorchで始める深層学習 ――数式なしで基礎から実装まで 単行本(ソフトカバー) – 2018/5/21 小泉 訓 (著)]

PyTorchはその習得のしやすさや、研究開発との親和性の高さから、発表されてすぐに世界中で人気になりました。

PyTorchのインストール

PyTorchのインストール方法は、公式ページにかかれています。

引用元:PyTorch https://pytorch.org/

Get Started.の右側にあるボタンは以下の手順で選択しましょう。

  1. PyTorch Build
    1. 安定版かプレビュー版かを選びます。
    2. 普通は安定版でOKです。
  2. Your  OS
    1. PyTorchをインストールしたいPCのOSを指定しましょう。
  3. Package
    1. 普通はpip、Anacondaを使っている場合はcondaを選択しましょう。
  4. Language
    1. PyTorchを使うプログラミング言語を選びます。以前はPythonだけでしたが、C++が追加されました。
    2. Pythonを使う場合は端末エミュレータで「Python -V」と打つとバージョンが確認できます。
  5. CUDA
    1. NVIDIAのGPUを使っている人はCUDAのバージョンを指定します。
    2. GPUがない場合はNoneを選択します。

自分の開発環境にあったボタンを押すと、その条件にあったインストールコマンドが「Run this command:」の横に表示されます。コピーして端末エミュレータで実行するとインストール作業が始まります。

PyTorchのコード

Define by Run

PyTorchはDefine by Run式のライブラリです。

簡単に言うと、「Pythonコードをそのまま書くだけでDeep Learningモデルが実装できる」タイプのライブラリになります。また、Deep Learningの実装では、多くの場合モデルの訓練に偏微分が必要になります。

微分の計算も、ニューラルネットワークモデルが複雑になると大変になります。それこそ人の手でいちいち微分をしていては追いつかない程に。

PyTorchでは、他の多くのDeep Learningフレームワークと同様に、自動微分機能がついています。PyTorchの関数を使って実装している限り、ニューラルネットワークのバックプロパゲーションについて実装する必要はありません。

モデルの実装と、損失関数の定義までを行ってしまえば、バックプロパゲーションの計算を自動で行ってくれます。

引用元:PyTorch https://pytorch.org/about/

上のgifを見ると、変数lossに損失関数が入っていて、その損失関数をloss.backward()するだけで勾配が計算できるとあります。

実際のコード

PyTorchで実際に、簡単な三層のニューラルネットワークを実装してみました。

Jupyter上で実行して見てください。

ライブラリのimport

import torch
import torch.nn as nn
from torchvision import datasets
import torchvision.transforms as transforms
from torch.autograd import Variable

import matplotlib.pyplot as plt
% matplotlib inline

ハイパーパラメータの設定

# Hyper Parameters 
input_size = 784
hidden_size = 500
num_classes = 10
num_epochs = 5
batch_size = 100
learning_rate = 0.001

データセットの用意

torchvision.datasetsからMNISTという手書き文字認識のデータセットを利用します。

# MNIST Dataset 
train_dataset = datasets.MNIST(root='../data', 
                            train=True, 
                            transform=transforms.ToTensor(),  
                            download=True)

test_dataset = datasets.MNIST(root='../data', 
                              train=False, 
                              transform=transforms.ToTensor())

Output:

Downloading http://yann.lecun.com/exdb/mnist/train-images-idx3-ubyte.gz
Downloading http://yann.lecun.com/exdb/mnist/train-labels-idx1-ubyte.gz
Downloading http://yann.lecun.com/exdb/mnist/t10k-images-idx3-ubyte.gz
Downloading http://yann.lecun.com/exdb/mnist/t10k-labels-idx1-ubyte.gz
Processing...
Done!

minibatch学習の準備

学習は通常、minibatch単位で行います。

学習の際にminibatchをデータ全体から切り出してくれるクラスを定義しておきましょう。

# Data Loader (Input Pipeline)
train_loader = torch.utils.data.DataLoader(dataset=train_dataset, 
                                           batch_size=batch_size, 
                                           shuffle=True)

test_loader = torch.utils.data.DataLoader(dataset=test_dataset, 
                                          batch_size=batch_size, 
                                          shuffle=False)

ニューラルネットワークの定義

PyTorchを使ったニューラルネットワークの定義は非常に見やすいものになります。

Chainerを使ったことがある方には、わかりやすいのではないでしょうか。

# Neural Network Model (1 hidden layer)
class Net(nn.Module):
        def __init__(self, input_size, hidden_size, num_classes):
                super().__init__()
                self.fc1 = nn.Linear(input_size, hidden_size) 
                self.relu = nn.ReLU()
                self.fc2 = nn.Linear(hidden_size, num_classes)  

        def forward(self, x):
                out = self.fc1(x)
                out = self.relu(out)
                out = self.fc2(out)
                return out

モデルインスタンスの作成

ニューラルネットワーククラスからインスタンスを作ります。

この際にGPUを使うのであれば、ネットワークインスタンス.cuda()としてGPUで実行できる形にしておきましょう。

net = Net(input_size, hidden_size, num_classes)
net.cuda()

Output:

Net(
  (fc1): Linear(in_features=784, out_features=500, bias=True)
  (relu): ReLU()
  (fc2): Linear(in_features=500, out_features=10, bias=True)
)

損失関数とオプティマイザの設定

ここでは例としてMNISTの分類を行うので、損失関数としてクロスエントロピーを使います。

オプティマイザは様々ありますが、Adamを使ってみます。

# Loss and Optimizer
criterion = nn.CrossEntropyLoss()  
optimizer = torch.optim.Adam(net.parameters(), lr=learning_rate)  

トレーニング

ネットワークの訓練を行う関数を定義して、これを走らせてみましょう。

ここについてはもっとスマートな書き方がありますが、今はシンプルに一般的なネットワークのfit関数を書いてみます。

def fit(net, train_loader, num_epochs=num_epochs, t= 200):
    # モデルのトレーニング
    for epoch in range(num_epochs):
        for i, (images, labels) in enumerate(train_loader):  
            # pytorchのtensorをVariableに変換
            images = Variable(images.view(-1, 28*28)).cuda()
            labels = Variable(labels).cuda()

            # フォワードプロパゲーション/ バックプロパゲーション/ 最適化
            optimizer.zero_grad()  # 勾配を0初期化
            outputs = net(images)
            loss = criterion(outputs, labels)
            loss.backward()
            optimizer.step()
            
            # t回毎にログを表示
            if (i+1) % t == 0:
                print ('Epoch [%d/%d], Step [%d/%d], Loss: %.4f' 
                        %(epoch+1, num_epochs, i+1, len(train_dataset)//batch_size, loss.data.item()))
    return net

net = fit(net, train_loader)

Output:

Epoch [1/5], Step [200/600], Loss: 0.3556
Epoch [1/5], Step [400/600], Loss: 0.1908
Epoch [1/5], Step [600/600], Loss: 0.1428
Epoch [2/5], Step [200/600], Loss: 0.1996
Epoch [2/5], Step [400/600], Loss: 0.1316
Epoch [2/5], Step [600/600], Loss: 0.0717
Epoch [3/5], Step [200/600], Loss: 0.0298
Epoch [3/5], Step [400/600], Loss: 0.0345
Epoch [3/5], Step [600/600], Loss: 0.0895
Epoch [4/5], Step [200/600], Loss: 0.0205
Epoch [4/5], Step [400/600], Loss: 0.0703
Epoch [4/5], Step [600/600], Loss: 0.0191
Epoch [5/5], Step [200/600], Loss: 0.0310
Epoch [5/5], Step [400/600], Loss: 0.0349
Epoch [5/5], Step [600/600], Loss: 0.0399

評価

モデルを評価してみます。

訓練に使ったデータとは別のデータ(テストデータ)を使って、未知のデータをどのくらい正確にクラス分類できるのか確かめます。

def evaluate(net, test_loader=test_loader):
    # Test the Model
    correct = 0
    total = 0
    for images, labels in test_loader:
        images = Variable(images.view(-1, 28*28)).cuda()
        outputs = net(images)
        _, predicted = torch.max(outputs.data, 1)
        total += labels.size(0)
        correct += (predicted.cpu() == labels).sum()

    print('Accuracy of the network on the 10000 test images: %d %%' % (100 * correct / total))

evaluate(net)

Output:

Accuracy of the network on the 10000 test images: 97 %

もっと複雑なDeep Learningモデルの実装も、PyTorchならば美しく実装できるでしょう。

本腰を入れてPyTorchとDeep Learningを勉強したいならば、侍エンジニアのマンツーマンレッスンを受講してみてください。

深層学習に詳しいエンジニアがインストラクターになって、あなたの勉強をサポートします!

まとめ

この記事では、PyTorchについてまとめました。

PyTorchは近年の複雑なDeep Learningモデルの実装に適した、非常に柔軟なDeep Learningフレームワークです。

速度もあり、GPUへの対応も簡単です。Deep Learningの勉強を始めるには最適のフレームワークなので、是非とも使ってみてくださいね。

この記事を書いた人

第一言語はPythonです。
皆さんRustやりましょう。

目次