Google ColaboratoryでPytorch tutorialを試してみる

本サイトは広告収入およびアフィリエイト収益を受けております。

スポンサーリンク
スポンサーリンク

お疲れ様です。きざきまるおです。

今回はGoogle ColaboratoryでPytorch tutorialを実行していきます。

それではどうぞ。

手順

基本的には以下URLの手順に沿って実行していこうかと思います。
ただ、すべて英語なので簡単にかいつまんで説明しながら実施させていただきます。

必要なライブラリをインストール

pipコマンドで今回利用するライブラリをインストールしましょう。コマンドは以下になります。

import torch
from torch import nn
from torch.utils.data import DataLoader
from torchvision import datasets
from torchvision.transforms import ToTensor

Pytorchには解析するデータごとのサンプルデータが用意されているようですが、tutorialではTorchVisionのFashionMNISTデータセットを利用するようです。

FashionMNIST — Torchvision 0.17 documentation

FashionMNISTの訓練データとテストデータをダウンロードしましょう。

training_data = datasets.FashionMNIST(
    root="data",
    train=True,
    download=True,
    transform=ToTensor(),
)

test_data = datasets.FashionMNIST(
    root="data",
    train=False,
    download=True,
    transform=ToTensor(),
)

次にDataLoaderに先ほどダウンロードしたデータセットを渡しましょう。
※DataLoader:データセットを用いてミニバッチを作成するクラス
 ミニバッチ学習:渡されたデータをミニバッチという小さなグループに分割して学習する

batch_size = 64


train_dataloader = DataLoader(training_data, batch_size=batch_size)
test_dataloader = DataLoader(test_data, batch_size=batch_size)

for X, y in test_dataloader:
    print("Shape of X [N, C, H, W]: ", X.shape)
    print("Shape of y: ", y.shape, y.dtype)
    break

これでデータを準備する段階場で完了しました。
次からはいよいよモデル構築になります。

device = "cuda" if torch.cuda.is_available() else "cpu"
print("Using {} device".format(device))

class NeuralNetwork(nn.Module):
    def __init__(self):
        super(NeuralNetwork, self).__init__()
        self.flatten = nn.Flatten()
        self.linear_relu_stack = nn.Sequential(
            nn.Linear(28*28, 512),
            nn.ReLU(),
            nn.Linear(512, 512),
            nn.ReLU(),
            nn.Linear(512, 10),
            nn.ReLU()
        )

    def forward(self, x):
        x = self.flatten(x)
        logits = self.linear_relu_stack(x)
        return logits

model = NeuralNetwork().to(device)
print(model)

deviceにGPUを定義してto(device)でGPUを使うようにしてます。
また、tutorialでは3層構造になってますね。

次に損失関数と最適化手法を定義します。
tutorialでは「損失関数:交差エントロピー」、「最適化手法:SDG」を利用するようですね。
交差エントロピー:正解の値に近づくほど誤差が0に近づく関数
SDG:与えられたデータからランダムに値を取り出し、重みを更新していく勾配降下法

loss_fn = nn.CrossEntropyLoss()
optimizer = torch.optim.SGD(model.parameters(), lr=1e-3)

定義が完了したらモデルを作成します。
訓練データのミニバッチに対する推論での損失誤差を計算し、損失誤差を各層へ伝達します。

def train(dataloader, model, loss_fn, optimizer):
    size = len(dataloader.dataset)
    for batch, (X, y) in enumerate(dataloader):
        X, y = X.to(device), y.to(device)
        
        # 損失誤差を計算
        pred = model(X)
        loss = loss_fn(pred, y)
        
        # バックプロパゲーション
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()

        if batch % 100 == 0:
            loss, current = loss.item(), batch * len(X)
            print(f"loss: {loss:>7f}  [{current:>5d}/{size:>5d}]")

次にテスト側のモデルを作成しましょう。

def test(dataloader, model):
    size = len(dataloader.dataset)
    model.eval()
    test_loss, correct = 0, 0
    with torch.no_grad():
        for X, y in dataloader:
            X, y = X.to(device), y.to(device)
            pred = model(X)
            test_loss += loss_fn(pred, y).item()
            correct += (pred.argmax(1) == y).type(torch.float).sum().item()
    test_loss /= size
    correct /= size
    print(f"Test Error: \n Accuracy: {(100*correct):>0.1f}%, Avg loss: {test_loss:>8f} \n")

上記のモデルを5回繰り返して精度を上げます。

epochs = 5
for t in range(epochs):
    print(f"Epoch {t+1}\n-------------------------------")
    train(train_dataloader, model, loss_fn, optimizer)
    test(test_dataloader, model)
print("Done!")

ここまででモデルの作成が完了です。
作成したモデルを保存しましょう。

torch.save(model.state_dict(), "model.pth")
print("Saved PyTorch Model State to model.pth")

これで一通りの流れが完了しました。
もし、作成したモデルを流用したい場合は以下のようにしましょう。

model = NeuralNetwork()
model.load_state_dict(torch.load("model.pth"))

classes = [
    "T-shirt/top",
    "Trouser",
    "Pullover",
    "Dress",
    "Coat",
    "Sandal",
    "Shirt",
    "Sneaker",
    "Bag",
    "Ankle boot",
]

model.eval()
x, y = test_data[0][0], test_data[0][1]
with torch.no_grad():
    pred = model(x)
    predicted, actual = classes[pred[0].argmax(0)], classes[y]
    print(f'Predicted: "{predicted}", Actual: "{actual}"')

以上でPytorch tutorialは完了です。
流れにそれば簡単にできるかと思いますが、これをどのように応用させていくかが難しいのでいずれ説明できれば良いなと思います。

それではまた。

タイトルとURLをコピーしました