Pythonスキルの習得

【 入門 】初めてのPyTorch – 実際にコードを書いて、体験してみる –

【 入門 】初めてのPyTorch - 実際にコードを書いて、体験してみる -

本記事は、

  • Python初心者以上の方で
  • ディープラーニングに興味はあるが、まだコードを書いた事の無い方
  • もしくは、「PyTorch」初めての方

を対象に

  • ディープラーニングのフレームワークである、「PyTorch」を実際に体験してみる

という内容になっています。

実際に体験してみる事で、PyTorchの特徴や、自分に合う・合わないが、判断できるようになると思います。

本記事では、分かりやすさ優先で解説をしており、厳密には異なる部分があります。

ご了承ください。

最初に、本記事で作る物のご紹介

Fasion-MNISTというデータセットを使って、画像判定させてみます。

Fashion-MNIST データセットとは?

10種類の、「ファッション商品」の画像と、正解ラベルの組合わせデータです。

  • 訓練データとして、6万枚
  • テストデータとして、1万枚

無料で、入手する事が可能です。

データセットの中身は、以下の通りです。

各画像のサイズは、28×28 ピクセル になっています。

Fashion-MNIST 詳細情報

The MIT License (MIT) Copyright © [2017] Zalando SE, https://tech.zalando.com

PyTochを使用するための準備

Googleが提供する、Colaboratoryの準備

環境構築が不要な、Googleが提供する、Colaboratoryを使ってご紹介します。

既にご存知の方は、この章をスキップして頂ければと思います。

今まで、使用した事のない方でも、大丈夫です。

本記事にて、簡単に解説します。

Colaboratoryとは

  • ブラウザ上でPythonを記述・実行が可能
  • 無料で利用可能
  • GPUも無料で利用可能なため、機械学習、データ分析に適している

といった特徴があります。

使用するためには、Googleのアカウントが、必要になります。

下記の順番で、Colaboratoryにアクセスします。

まずは、Googleのトップページに遷移します。

そうすると、下記画面が出現いたします。

これで準備完了です。

Colaboratoryの使い方

GPU環境にしてみる

メニューから、「ランタイム → ランタイムのタイプを変更」を選択します。

ポップアップする、ノートブックの設定で、ハードウェアアクセラレータをGPUに選択します。

その後、保存をクリックします。

コードを実行してみる

下記、①、②のように

  • コードを記載しては、その都度、実行していく

というスタイルになっています。

① コードを記載
② 「SHIFT + ENTER」 で、記載した部分を実行

本記事では割愛しますが、Googleドライブに接続して、保存する事も可能です。

PyTochのコード紹介

以下で紹介するコードは、

  • 順次、Colaboratoryに記載して
  • 「Shift+Enter」で実行

していって下さい。

importする「パッケージ」

まずは必要なパッケージをimportします。

import torch
import torch.nn as nn
import torch.nn.functional as F
import torchvision

importする、パッケージ等に関して:

  • torch:「PyTorch」本体
  • torch.nn: 「ニューラルネットワーク」を提供するもの
  • functional:「PyTorch」が用意している、活性化関数、損失関数等を提供
  • torchvision:「 PyTorch」で、コンピュータヴィジョンを扱うための、データセットとか、画像変換処理等を提供しているパッケージ

活性化関数、損失関数の説明は、長くなるので、本記事では割愛しています。

学習データを、ダウンロードする。

「torchvision」を利用して、データセットをダウンロードします。

以下のデータをダウンロードします。

  • 訓練用データ
  • テスト用データ

訓練用データのダウンロード

train_data = torchvision.datasets.FashionMNIST(
              './datasets', train=True, download=True,
              transform=torchvision.transforms.ToTensor())

FashionMNISTのデータセットを使うため、「FashionMNIST」 クラスをインスタンス化しています。

引数の意味は、以下の通りです。

  • 第一引数:データセットをダウンロードした際の保存場所
  • train引数:訓練データの場合は、True
  • download引数:データセットを、ダウンロードして保存する場合は、True(2回目以降の実行の際、保存したデータを使用します。)
  • transform引数:データセットのデータを変換する場合、この引数に記載する。ここでは、データをPyTorchで扱うための、「テンソル」に変換している。

PyTorchでは、データを、「テンソル」という形に変換して処理します。

多次元配列みたいなものです。

Numpyをご存知の方は、ndarrayみたいなモノと、考えて頂いて大丈夫です。

このコードを実行すると、6万枚の訓練用 画像データが、ダウンロードされます。

テスト用データのダウンロード

test_data = torchvision.datasets.FashionMNIST(
              './datasets', train=False, download=True,
              transform=torchvision.transforms.ToTensor())

「訓練用データのダウンロード」で紹介したコードに対して、

  • train引数をFalse

にすると、テストデータがダウンロードされます。

このコードを実行すると、1万枚のテスト用 画像データが、ダウンロードされます。

学習データを、複数個ずつ、取り出すコード

一般的に、大量のデータセットを一度に学習させると、メモリがパンクする可能性があります。(メモリ容量次第ですが・・・)

通常、学習はGPUを使用します。

GPUのメモリ容量は、メインメモリに比べ容量が少なく、データを少しずつ読み込んで、学習させる必要があります。

そこで以下のクラスを使用すると、少しずつデータを読み込む事が、可能になります。

train_dataloader = torch.utils.data.DataLoader(train_data, batch_size=100, shuffle=True) 

引数の解説:

  • 第一引数: データセットを指定
  • batch_size引数: 何枚ずつ、データを読み込むか
  • shuffle引数:Trueの場合、データをシャッフルして、順不同にして、取り出す

テストデータに対しても、同様のコードを記載します。

test_dataloader = torch.utils.data.DataLoader(test_data, batch_size=100, shuffle=False) 

この方法は、「ミニバッチ学習」と呼ばれます。

「ミニバッチ学習」は、ここで記載した以上の意味がありますが、長くなるため、詳細を割愛しております。

ニューラルネットワークを組んでみる

ニューラルネットワークの、概念的な解説は省略します。

興味のある方は、下記の記事が参考になります。

ディープラーニングとは ? イメージでわかりやすく仕組みを解説
ディープラーニングとは ? イメージでわかりやすく仕組みを解説 世間で騒がれているけど、ディープラーニングって何? AI(人工知能)とどう違うの!? 筆者 今回は、「とある女性がプロ...

下記のニューラルネットワークを、組んでみます。

その際のコードは、以下の通りになります。

# ニューラルネットワークモデルの定義
class NeuralNet(nn.Module):
    def __init__(self):
        super().__init__()

        self.fc1 = nn.Linear(784, 100)
        self.fc2 = nn.Linear(100, 10)
        self.relu = nn.ReLU() # 活性化関数 (説明省略)

    def forward(self, x):
        # 順伝播の設定
        # 入力層 → 中間層の全結合
        x = self.fc1(x)
        # 活性化関数 (説明省略)
        x = self.relu(x)
        # 中間層 → 出力層の全結合
        x = self.fc2(x)
        return F.log_softmax(x, dim=1)

学習してみる。

まずは、ハイパーパラメータという、学習にあたって、各種設定をします。

num_epochs = 10         # 学習を何回、繰り返すか (エポックと呼ばれる。)
num_batch = 100         # 1度に、何枚の画像を取出すか
learning_rate = 0.001   # 学習率
image_size = 28*28      # 画像の画素数(幅x高さ)

下記コードの、損失関数を小さくするように、訓練します。

損失関数というのは、実際の結果と、AIが予測した結果の違いを、数値化するための関数です。(色々な関数があります。)

# GPUが使える場合は、GPU使用モードにする。
device = torch.device('cuda') if torch.cuda.is_available() else torch.device('cpu')
# ニューラルネットワークの生成して、GPUにデータを送る
model = NeuralNet().to(device)
# モデルを訓練モードにする
model.train()  

# 損失関数の設定(説明省略)
criterion = nn.CrossEntropyLoss() 
# 最適化手法の設定(説明省略)
optimizer = torch.optim.Adam(model.parameters(), lr = learning_rate) 

# 設定したエポック数分、学習する。
for epoch in range(num_epochs): 
    loss_sum = 0

    for inputs, labels in train_dataloader:

        # GPUが使えるならGPUにデータを送る
        inputs = inputs.to(device)
        labels = labels.to(device)

        # optimizerを初期化
        optimizer.zero_grad()

        # ニューラルネットワークの処理を実施
        inputs = inputs.view(-1, image_size) # 画像データ部分を一次元へ並び変える
        outputs = model(inputs)

        # 損失(出力とラベルとの誤差)の計算
        loss = criterion(outputs, labels)
        loss_sum += loss

        # 学習
        loss.backward()
        optimizer.step()

    # 学習状況の表示
    print(f"Epoch: {epoch+1}/{num_epochs}, Loss: {loss_sum.item() / len(train_dataloader)}"

実行結果

以下のように、Loss(損失関数を使って導き出しもの。 小さい程OK)が減少してき、学習できている事が分かります。

学習が完了したのち、テストデータを使って評価してみる

訓練データとは別の、テストデータを使用して、どれ位の識別ができるか、評価してみます。

model.eval()  # モデルを評価モードにする

loss_sum = 0
correct = 0

with torch.no_grad():
    for inputs, labels in test_dataloader:

        # GPUが使えるならGPUにデータを送る
        inputs = inputs.to(device)
        labels = labels.to(device)

        # ニューラルネットワークの処理を実施
        inputs = inputs.view(-1, image_size) # 画像データ部分を一次元へ並び変える
        outputs = model(inputs)

        # 損失(出力とラベルとの誤差)の計算
        loss_sum += criterion(outputs, labels)

        # 正解の値を取得
        pred = outputs.argmax(1)
        # 正解数をカウント
        correct += pred.eq(labels.view_as(pred)).sum().item()

print(f"Loss: {loss_sum.item() / len(test_dataloader)}, Accuracy: {100*correct/len(test_dataset)}% ({correct}/{len(test_dataset)})")

このケースでは、全学習が終わった後に、テストデータを用いて、検証しています。

通常は、各エポック毎の学習後に、テストデータを用いた検証も実施するケースが、ほとんどです。

今回は、分かりやすさ優先で、学習と評価、分けて記載してみました。

実行結果

補足情報

学習環境に関して

上記のGoogleColaboratoryでは、使用時間に制限があります。

  • 90分で切断される(回避策あり 90分に1回、操作すればOK)
  • 12時間で切断される(回避策なし)

少し本格的になると、12時間以上の学習は、当たり前のようになってきます。

会社の場合、クラウド(AWS等)を利用するという手もありますが、個人の場合、金銭的に厳しいです・・

思う存分、学習したい方は、自分PCを作ってしまうのが、オススメです。

自作PCを組むのは、それほど、難しくはありません。

また、好きなパーツが選べるのもメリットですし、必要なスペックに応じて、将来、グレードアップも可能です!

下記リンク記事にて、詳細を解説しています。

【入門】PyTorchのインストール方法 - Mac, Windows, Ubuntu - GPU版インストールも、あわせて紹介
【入門】PyTorchのインストール方法 - Mac, Windows, Ubuntu - GPU版インストールも、あわせて紹介PyTorchのインストール方法を解説した記事です。紹介したOSは、Windows、Mac、Ubuntuです。GPUを使用するための、注意点も併せて、ご紹介しました。...

今回も、最後までお付き合い頂き、ありがとうございました。

また、お会いしましょう!