新着情報
Neural Network Classのインスタント化
pythonによるNeuralNetworkをクラスで実装する:
実装するpythonのNeuralNetwork classは入力層(第0層)、隠れ層(第1層)、出力層(第2層)から成る2層構造のNeuralNetworkを考える。

Fig.1 2層のneural network.
ニューラル・ネットワークをNeuralNetwork classによって実装することにする。NeuralNetworkの実現には
ネットワークの作成、重みの更新、ネットワークへの照会という異なる処理が必要となる。まず、
class NeuralNetwork:
def _ _init_ _( ): コンストラクタ(初期化)・メソッド
ここで、入力層、隠れ層、出力層のneuronの数と学習率をインスタンス変数に代入し、ニューラル・ネットワークの 初期化をする。
def weight_initialize( ): 重みの初期化をするメソッド。
def activation_function( ): シグモイド関数を実装するメソッド。
def train( ):訓練データを読み込み、最適な重みを計算するメソッド。
def evaluate( ): 更新された重みを用いてテストデータを評価するメソッド。
import numpy as np
class neuralNetwork:
# ニューラルネットワークの初期化
def __init__(self,
input_neurons, # 入力層のニューロン数
hidden_neurons, # 隠れ層のニューロン数
output_neurons, # 出力層のニューロン数
learning_rate # 学習率
):
# 入力層、隠れ層、出力層のニューロン数をインスタンス変数に代入
self.inneurons = input_neurons # 入力層のニューロン数
self.hneurons = hidden_neurons # 隠れ層のニューロン数
self.oneurons = output_neurons # 出力層のニューロン数
# 学習率をインスタンス変数に代入
self.lr = learning_rate
# weight_initialize()を呼ぶ
self.weight_initialize()
# 重みの初期化を行う
def weight_initialize(self):
# 入力層と隠れ層の間のリンクの重みの初期値を設定
self.w_h = np.random.normal(0.0, # 平均は0
pow(self.inneurons, -0.5), # 標準偏差は入力層のニューロン数を元に計算
(self.hneurons, # 隠れ層のニューロン数を行数
self.inneurons + 1) # バイアスを加え、列数とする
)
# 隠れ層と出力層の間のリンクの重みの初期値を設定
self.w_o = np.random.normal(0.0, # 平均は0
pow(self.hneurons, -0.5), # 標準偏差は隠れ層のニューロン数を元に計算
(self.oneurons, # 出力層のニューロン数を行数
# 隠れ層のニューロン数に
self.hneurons + 1) # バイアスを加え、列数とする
)
# シグモイド関数を活性化関数として定義
def activation_function(self, x):
return 1 / (1 + np.exp(-x))
# ニューラルネットワークの学習を行うメソッド
def train(self,
inputs_list, # 入力値の配列
targets_list # 目標出力の配列
):
# 入力値の配列にバイアス項を追加して1列の行列に変換
inputs = np.array(
np.append(inputs_list, [1]), # 配列の末尾にバイアスのための値「1」を追加
ndmin=2 # 2次元化
).T # 転置して1列の行列にする
# 目標値の配列を1列の行列に変換する
targets = np.array(targets_list, # 目標値の配列
ndmin=2 # 2次元化
).T # 転置して1列の行列にする
# 隠れ層への入力信号を計算
hidden_inputs = np.dot(self.w_h, # 入力層と隠れ層の間の重み
inputs # 入力値の行列
)
# 活性化関数を適用して隠れ層から出力する
hidden_outputs = self.activation_function(hidden_inputs)
# 隠れ層の出力行列の末尾にバイアスの値として1を追加
hidden_outputs = np.append(hidden_outputs, # 隠れ層の出力行列
[[1]], # 2次元形式でバイアス値を追加
axis=0 # 行を指定(列は1)
)
# 出力層への入力信号を計算
final_inputs = np.dot(self.w_o, # 隠れ層と出力層の間の重み
hidden_outputs # 隠れ層の出力
)
# 活性化関数を適用して出力層から出力する
final_outputs = self.activation_function(final_inputs)
# 目標値と出力層の出力信号の誤差を求める
output_errors = targets - final_outputs
# 誤差逆伝播により隠れ層の誤差を求める
hidden_errors = np.dot(self.w_o.T, # 隠れ層と出力層の間の重み行列を転置する
output_errors # 出力値と目標値との誤差
)
# 隠れ層と出力層の間の重みの更新
self.w_o += self.lr * np.dot(
# 出力誤差*出力信号* (1-出力信号)
(output_errors * final_outputs * (1.0 - final_outputs)),
# 出力信号の行列を転置
np.transpose(hidden_outputs)
)
# 隠れ層の出力エラーからバイアスのものを取り除く
hidden_errors_nobias = np.delete(
hidden_errors, # 隠れ層の出力エラーの行列
self.hneurons, # バイアスを除くニューロン数をインデックスにする
axis=0 # 行の削除を指定
)
# 隠れ層の出力からバイアスを取り除く
hidden_outputs_nobias = np.delete(
hidden_outputs, # 隠れ層の出力の行列
self.hneurons, # バイアスを除くニューロン数をインデックスにする
axis=0 # 行の削除を指定
)
# 入力層と隠れ層の間の重みの更新
self.w_h += self.lr * np.dot(
# 隠れ層の出力誤差*隠れ層の出力* (1-隠れ層の出力)
(hidden_errors_nobias * hidden_outputs_nobias * (
1.0 - hidden_outputs_nobias)),
# 入力層の出力信号の行列を転置
np.transpose(inputs))
# 学習結果を元にテストデータを評価するメソッド
def evaluate(self,
inputs_list # テスト用データの配列
):
# テスト用データの配列を1列の行列に変換する
inputs = np.array(
np.append(inputs_list, [1]), # 配列の末尾にバイアスの値「1」を追加
ndmin=2 # 2次元化
).T # 転置して1列の行列にする
# 隠れ層への入力信号を計算
hidden_inputs = np.dot(self.w_h, # 入力層と隠れ層の間の重み
inputs # テストデータの行列
)
# 活性化関数を適用して隠れ層から出力する
hidden_outputs = self.activation_function(hidden_inputs)
# 出力層への入力信号を計算
final_inputs = np.dot(
self.w_o, # 隠れ層と出力層の間の重み
np.append(hidden_outputs, [1]), # 隠れ層の出力配列の末尾にバイアスの値「1」を追加
)
# 活性化関数を適用して出力層から出力する
final_outputs = self.activation_function(final_inputs)
# 出力層からの出力を戻り値として返す
return final_outputs
neuralNetworkクラスをインスタンス化して、train()メソッドで手書き数字の訓練データの学習を行う。