from numpy import exp, array, random, dot class NeuralNetwork(): # NeuralNetworkというクラスを定義 def __init__(self): #コンストラクタ #重みの初期値として乱数を発生 シードを指定することで発生する乱数を固定する random.seed(1) # モデルは1個のニューロンで4個の入力で1個の出力 # 4個の重みは範囲が−1から1で平均は0とする 重みの初期値を乱数で設定する self.synaptic_weights = 2 * random.random((4, 1)) - 1 # 活性化関数として用いるtanh関数を定義する # 重みを掛けた入力の和に活性化関数で変換する。0〜1に正規化する def __tanh(self, x): return (exp(x) - exp(-x))/(exp(x) + exp(-x)) # tanhの微係数(tanh曲線の勾配)を定義する。重みを修正するのに用いる def __tanh_derivative(self, x): return 1 - (exp(x) - exp(-x))** 2/(exp(x) + exp(-x))** 2 # 試行錯誤によりニューラルネットワークを学習させる(重みを調整する) def train(self, training_set_inputs, training_set_outputs, number_of_training_iterations): for iteration in range(number_of_training_iterations): # 1個のニューロンからなるニューラルネットワークにより学習 output = self.think(training_set_inputs) # 期待される出力と予測された出力の誤差を計算 error = training_set_outputs - output # 誤差に入力を乗じ、さらに活性化関数の勾配を乗じる adjustment = dot(training_set_inputs.T, error * self.__tanh_derivative(output)) # 重みの調整 self.synaptic_weights += adjustment # ニューラルネットワークの思考 def think(self, inputs): # 入力を1個のニューロンからなるニューラルネットワークを通過させる return self.__tanh(dot(inputs, self.synaptic_weights)) if __name__ == "__main__": #単一ニューロンニューラルネットワークの初期化(インスタンスの生成) neural_network = NeuralNetwork() print ("Random starting synaptic weights: ") print (neural_network.synaptic_weights) # 4例の学習データ(4個の入力、1個の出力) training_set_inputs = array([[0, 0, 1, 0], [1, 1, 1, 0], [1, 0, 1, 1], [0, 1, 0, 1]]) training_set_outputs = array([[0, 1, 1, 0]]).T # 学習データを使っての学習 # 1万回行う neural_network.train(training_set_inputs, training_set_outputs, 10000) print ("New synaptic weights after training: ") print (neural_network.synaptic_weights) # 新規のデータによるニューラルネットワークのテスト print ("Considering new situation [0, 1, 0, 1] -> ?: ") print (neural_network.think(array([0, 1, 0, 1])))