AIプログラミング初心者がChatGPTにpytorchで簡単なAIを実装させてみた。モデル編

pytorch

はじめに

前回はChatGPTにpytorchで簡単なAIを実装させ、前処理について簡単に調査しました。

今回は前回のコードの中でモデル部分について調査してみたいと思います。

pytorchのモデルについて調べてみた

ChatGPTに聞いたコード全体

まずは前回のコードの全体から

import torch
import torch.nn as nn
import torch.optim as optim
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from torch.utils.data import DataLoader, TensorDataset

# Iris データセットの読み込み
iris = load_iris()
X, y = iris.data, iris.target

# データの前処理
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0)
scaler = StandardScaler()
X_train = scaler.fit_transform(X_train)
X_test = scaler.transform(X_test)

# PyTorchのテンソルに変換
X_train = torch.tensor(X_train, dtype=torch.float32)
y_train = torch.tensor(y_train, dtype=torch.long)
X_test = torch.tensor(X_test, dtype=torch.float32)
y_test = torch.tensor(y_test, dtype=torch.long)

# データローダーの作成
train_dataset = TensorDataset(X_train, y_train)
train_loader = DataLoader(train_dataset, batch_size=16, shuffle=True)

# ニューラルネットワークの定義
class IrisNet(nn.Module):
    def __init__(self):
        super(IrisNet, self).__init__()
        self.fc1 = nn.Linear(4, 64)
        self.fc2 = nn.Linear(64, 64)
        self.fc3 = nn.Linear(64, 3)

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

model = IrisNet()

# 損失関数とオプティマイザ
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=0.001)

# トレーニングプロセス
def train(model, criterion, optimizer, train_loader, epochs=100):
    for epoch in range(epochs):
        for inputs, targets in train_loader:
            optimizer.zero_grad()
            outputs = model(inputs)
            loss = criterion(outputs, targets)
            loss.backward()
            optimizer.step()
        if epoch % 10 == 0:
            print(f"Epoch {epoch}/{epochs}, Loss: {loss.item()}")

train(model, criterion, optimizer, train_loader)

# テストデータで評価
with torch.no_grad():
    outputs = model(X_test)
    _, predicted = torch.max(outputs, 1)
    accuracy = (predicted == y_test).sum().item() / y_test.size(0)

accuracy

pytorchのモデルの定義を調べてみた

全体のコードの中でモデルに当たる部分は以下の箇所です。

# ニューラルネットワークの定義
class IrisNet(nn.Module):
    def __init__(self):
        super(IrisNet, self).__init__()
        self.fc1 = nn.Linear(4, 64)
        self.fc2 = nn.Linear(64, 64)
        self.fc3 = nn.Linear(64, 3)

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

すごく難しそうです…

では読み解いてみましょう。さて

モデルの定義

class IrisNet(nn.Module):
    def __init__(self):
        super(IrisNet, self).__init__()

が分らん。まずはnn.Moduleからこちらによると決まり文句のようです。ただ、super(…)とも関係しているようでこちらの記事と合わせるとnn.Moduleというpytorchに含まれているモジュールを継承してきて、そのinitを引き継いでいるようです。まぁ、決まり文句ということで

ニューロンの定義

次は

self.fc1 = nn.Linear(4, 64)
self.fc2 = nn.Linear(64, 64)
self.fc3 = nn.Linear(64, 3)

ですね。よくわからなけど数字を見るとニューロンに見えます。

4が入力層、64が隠れ層のニューロン数、3が出力層

のように見えます。前回の前処理で入力ががく片と花弁の長さ、幅でしたので、入力層は4。あやめの種類が3だったので出力層が3になってます。これはニューロン数で確定ですね。

図で書くとこんな感じ

順伝播の定義

次はこれ

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

forwardが書いてあるので、順伝播なのでしょう。きっと

となると、self.fc1というのが、上で定義したニューロンなので、xで入力されて活性化関数reluで出力し、さらにself.fc2の入力になって、またreluで出力し、最後にself.fc3を通して活性化関数なしで出力するという流れでしょうか

すごく分かりやすい順伝播ですね。

では、逆伝播はどこにあるのでしょうか?

後々のコードをみるとloss.backward()とあるので、こちらで何か行っているのでしょう。

そのときが来たら調べてみます。

コメント

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