本記事は、
- Python初心者以上の方で
- ディープラーニングに興味はあるが、まだコードを書いた事の無い方
- もしくは、「PyTorch」初めての方
を対象に
- ディープラーニングのフレームワークである、「PyTorch」を実際に体験してみる
という内容になっています。
実際に体験してみる事で、PyTorchの特徴や、自分に合う・合わないが、判断できるようになると思います。
本記事では、分かりやすさ優先で解説をしており、厳密には異なる部分があります。
ご了承ください。
最初に、本記事で作る物のご紹介
Fasion-MNISTというデータセットを使って、画像判定させてみます。
Fashion-MNIST データセットとは?
10種類の、「ファッション商品」の画像と、正解ラベルの組合わせデータです。
- 訓練データとして、6万枚
- テストデータとして、1万枚
無料で、入手する事が可能です。
データセットの中身は、以下の通りです。
各画像のサイズは、28×28 ピクセル になっています。
Fashion-MNIST 詳細情報
- 作成者: Han Xiao, Kashif Rasul, and Roland Vollgraf.
- タイトル: Fashion-MNIST: a Novel Image Dataset for Benchmarking Machine Learning Algorithms
- 公開日: Aug 28, 2017
- 論文: arXiv:1708.07747 [cs.LG]
- URL: https://github.com/zalandoresearch/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)
この方法は、「ミニバッチ学習」と呼ばれます。
「ミニバッチ学習」は、ここで記載した以上の意味がありますが、長くなるため、詳細を割愛しております。
ニューラルネットワークを組んでみる
ニューラルネットワークの、概念的な解説は省略します。
興味のある方は、下記の記事が参考になります。
下記のニューラルネットワークを、組んでみます。
その際のコードは、以下の通りになります。
# ニューラルネットワークモデルの定義
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を組むのは、それほど、難しくはありません。
また、好きなパーツが選べるのもメリットですし、必要なスペックに応じて、将来、グレードアップも可能です!
下記リンク記事にて、詳細を解説しています。
今回も、最後までお付き合い頂き、ありがとうございました。
また、お会いしましょう!