PyTorch による全接続ニューラルネットワークの実装と学習フロー

全接続ニューラルネットワークの概要

全接続ニューラルネットワーク(Fully Connected Neural Network: FCNN)は、多層パーセプトロン(MLP)と呼ばれる基本的な構造を持っています。このアーキテクチャでは、ある層に属するすべてのニューロンが、次の層のすべてのニューロンと結合関係を持ち、重み付きの演算が行われます。標準的な構成としては、入力層、少なくとも一つの隠れ層、そして出力層から成り立ちます。

PyTorch を用いた実装手順

PyTorch フレームワークを利用すると、ニューラルネットワークの構築を効率的に行えます。主に torch.nn.Module クラスを継承することでモデルを定義し、必要なライブラリをインポートすることから開始します。

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

モデルクラスの定義

ネットワーク構造を表現するクラスを作成します。ここでは MultiLayerPerceptron という名前で定義し、nn.Module を継承します。コンストラクタ内で層を定義し、順伝播関数でデータの流れを記述します。

class MultiLayerPerceptron(nn.Module):
    def __init__(self, in_features=3, h_units=4, out_features=2):
        """
        モジュールの初期化
        :param int in_features: 入力次元数
        :param int h_units: 隠れ層のユニット数
        :param int out_features: 出力次元数
        """
        super(MultiLayerPerceptron, self).__init__()
        # 入力層から隠れ層への線形変換
        self.fc_input_hidden = nn.Linear(in_features, h_units, dtype=torch.float32)
        # 隠れ層から出力層への線形変換
        self.fc_hidden_output = nn.Linear(h_units, out_features, dtype=torch.float32)

    def forward(self, x):
        """
        順伝播計算
        :param Tensor x: 入力データ
        :return: Tensor 出力
        """
        # 隠れ層での活性化関数適用
        h = F.relu(self.fc_input_hidden(x))
        # 出力層(活性化関数は適用しない)
        out = self.fc_hidden_output(h)
        return out

この実装では、入力 3 次元、隠れ層 4 ユニット、出力 2 次元の単一隠れ層ネットワークを想定しています。必要に応じて nn.Linear を追加することで多層化も可能であり、過学習抑制のために Dropout 層を挿入する選択肢もあります。隠れ層には ReLU 関数を適用し、出力層は生値を返す構成です。

インスタンス化は以下のように行います。

network = MultiLayerPerceptron(3, 4, 2)

学習プロセスの実装

モデルの訓練には、最適化アルゴリズムと損失関数、そしてデータローダーが必要です。訓練モードにするため model.train() を呼び出し、バッチごとに勾配計算を行います。

def execute_training(network, data_iterator, optim, loss_fn):
    """
    1 エポック分の訓練を実行し、平均損失を返す
    :param MultiLayerPerceptron network: モデル
    :param DataLoader data_iterator: 訓練データ
    :param Optimizer optim: 最適化手法
    :param Loss loss_fn: 損失関数
    :return: float 平均損失
    """
    network.train()
    total_loss = 0.0
    
    for batch_x, batch_y in data_iterator:
        optim.zero_grad()  # 勾配のリセット
        predictions = network(batch_x).to(torch.float32)  # 順伝播
        loss = loss_fn(predictions, batch_y)  # 損失計算
        loss.backward()  # 逆伝播
        optim.step()  # パラメータ更新
        
        total_loss += loss.detach().numpy()
    
    return total_loss / len(data_iterator)

呼び出し側では、Adam 最適化手法と平均二乗誤差(MSE)を定義します。

optim = torch.optim.Adam(network.parameters(), lr=0.001)
loss_fn = nn.MSELoss(reduction='mean')

評価プロセスの実装

訓練の合間にテストデータで性能を確認します。評価時には model.eval() を設定し、勾配計算を無効化してメモリ効率を上げます。

def execute_evaluation(network, data_iterator, loss_fn):
    """
    テストデータに対する評価を行い、平均損失を返す
    :param MultiLayerPerceptron network: モデル
    :param DataLoader data_iterator: テストデータ
    :param Loss loss_fn: 損失関数
    :return: float 平均損失
    """
    network.eval()
    total_loss = 0.0
    
    with torch.no_grad():
        for batch_x, batch_y in data_iterator:
            predictions = network(batch_x).to(torch.float32)
            loss = loss_fn(predictions, batch_y)
            total_loss += loss.detach().numpy()
    
    return total_loss / len(data_iterator)

評価段階では逆伝播が不要であるため、損失値の算出のみを行います。

統合的な実行スクリプト

上記のコンポーネントを組み合わせ、複数エポックにわたる学習ループを構築します。

"""
データローダーの準備
train_loader = ...
test_loader = ...
"""

network = MultiLayerPerceptron(3, 4, 2)
optim = torch.optim.Adam(network.parameters(), lr=0.001)
loss_fn = nn.MSELoss(reduction='mean')

num_epochs = 100
for epoch in range(num_epochs):
    train_loss = execute_training(network, train_loader, optim, loss_fn)
    test_loss = execute_evaluation(network, test_loader, loss_fn)
    print(f"Epoch {epoch + 1} | Train Loss: {train_loss:.4f} | Test Loss: {test_loss:.4f}")

タグ: PyTorch fully-connected-network deep-learning Python neural-network-implementation

6月18日 20:25 投稿