全接続ニューラルネットワークの概要
全接続ニューラルネットワーク(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}")