Pythonでnumpyを使用して逆伝播アルゴリズムを実装しようとしています。私はこのサイトを使用して逆伝播の行列形式を実装しています。XOR でこのコードをテストしている間、数千回の反復を複数回実行した後でも、私のネットワークは収束しません。何らかの論理エラーがあると思います。もしよろしければご覧いただける方がいらっしゃいましたら、よろしくお願いいたします。完全に実行可能なコードはgithubにあります
import numpy as np
def backpropagate(network, tests, iterations=50):
#convert tests into numpy matrices
tests = [(np.matrix(inputs, dtype=np.float64).reshape(len(inputs), 1),
np.matrix(expected, dtype=np.float64).reshape(len(expected), 1))
for inputs, expected in tests]
for _ in range(iterations):
#accumulate the weight and bias deltas
weight_delta = [np.zeros(matrix.shape) for matrix in network.weights]
bias_delta = [np.zeros(matrix.shape) for matrix in network.bias]
#iterate over the tests
for potentials, expected in tests:
#input the potentials into the network
#calling the network with trace == True returns a list of matrices,
#representing the potentials of each layer
trace = network(potentials, trace=True)
errors = [expected - trace[-1]]
#iterate over the layers backwards
for weight_matrix, layer in reversed(list(zip(network.weights, trace))):
#compute the error vector for a layer
errors.append(np.multiply(weight_matrix.transpose()*errors[-1],
network.sigmoid.derivative(layer)))
#remove the input layer
errors.pop()
errors.reverse()
#compute the deltas for bias and weight
for index, error in enumerate(errors):
bias_delta[index] += error
weight_delta[index] += error * trace[index].transpose()
#apply the deltas
for index, delta in enumerate(weight_delta):
network.weights[index] += delta
for index, delta in enumerate(bias_delta):
network.bias[index] += delta
さらに、出力を計算するコードとシグモイド関数を次に示します。ここにバグがある可能性は低いです。シミュレーテッド アニーリングを使用して XOR をシミュレートするようにネットワークをトレーニングすることができました。
# the call function of the neural network
def __call__(self, potentials, trace=True):
#ensure the input is properly formated
potentials = np.matrix(potentials, dtype=np.float64).reshape(len(potentials), 1)
#accumulate the trace
trace = [potentials]
#iterate over the weights
for index, weight_matrix in enumerate(self.weights):
potentials = weight_matrix * potentials + self.bias[index]
potentials = self.sigmoid(potentials)
trace.append(potentials)
return trace
#The sigmoid function that is stored in the network
def sigmoid(x):
return np.tanh(x)
sigmoid.derivative = lambda x : (1-np.square(x))