Нейронные сети XOR возвращают неверный вывод - PullRequest
2 голосов
/ 30 апреля 2020

Мне интересно, почему моя нейронная сеть не работает. Я хотел бы сказать, что я задал имитационный вопрос, но у меня все еще есть вещи, которые я не понимаю ...

Код:

import numpy as np
inputs = np.array([
    [[0],[0]],
    [[1],[0]],
    [[0],[1]],
    [[1],[1]]
])

expected_output = np.array([
    [0],
    [1],
    [1],
    [0]
])

epochs = 100
lr = 0.2

hidden_weights = np.array([
    [0.2, 0.3],
    [0.4, 0.5]
])
hidden_bias = np.array([[0.3], [0.6]])

output_weights = np.array([[0.6, 0.7]])
output_bias = np.array([[0.5]])

def sigmoid(z):
    return 1/(1+np.exp(-z))

def sigmoid_derivative(z):
    return z * (1.0-z)

for _ in range(epochs):
    for index, input in enumerate(inputs):
        hidden_layer_activation = np.dot(hidden_weights, input)
        hidden_layer_activation += hidden_bias
        hidden_layer_output = sigmoid(hidden_layer_activation)

        output_layer_activation = np.dot(output_weights, hidden_layer_output)
        output_layer_activation += output_bias
        predicted_output = sigmoid(output_layer_activation)

        #Backpropagation
        output_errors = expected_output[index] - predicted_output
        hidden_errors = output_weights.T.dot(output_errors)
        d_predicted_output = output_errors * sigmoid_derivative(predicted_output)
        d_hidden_layer = hidden_errors * sigmoid_derivative(hidden_layer_output)

        output_weights += np.dot(d_predicted_output, hidden_layer_output.T) * lr
        hidden_weights += np.dot(d_hidden_layer, input.T) * lr

        output_bias += np.sum(d_predicted_output) * lr
        hidden_bias += np.sum(d_hidden_layer) * lr

# NOW THE TESTING,I pass 2 input neurons. One with value 1 and value 1
test = np.array([
    [[1], [1]]
])

hidden_layer_activation = np.dot(hidden_weights, test[0])
hidden_layer_activation += hidden_bias
hidden_layer_output = sigmoid(hidden_layer_activation)

output_layer_activation = np.dot(output_weights, hidden_layer_output)
output_layer_activation += output_bias
predicted_output = sigmoid(output_layer_activation)

print(predicted_output)
Result : [[0.5]] for inputs 1 and 1

Wanted : [[0]] for inputs 1 and 1

Я тестировал фид -продвижение-распространение, и оно работает нормально. Ошибки кажутся хорошими.

Я думал, что обновление весов было проблемой, но у обновления весов есть правильная формула. Этот код взят из книги «Создайте свою собственную нейронную сеть, и я использую почти то же самое:

self.who += self.lr * numpy.dot((output_errors * final_outputs * (1.0 ­ final_outputs)), numpy.transpose(hidden_outputs))

В настоящее время я пересылаю только 1 вход из 2 нейронов одновременно и вычисляю ошибку. Я хотел бы чтобы все было так, вместо того, чтобы пересылать все тестовые данные снова и снова.

Есть ли способ, которым я могу это сделать? Заранее спасибо:)

1 Ответ

1 голос
/ 30 апреля 2020

У вас есть небольшая ошибка реализации:

в Обратном распространении, вы оцениваете:

hidden_errors = output_weights.T.dot(output_errors)

, но ваша скрытая ошибка должна быть оценена на основе d_predicted_output, например:

hidden_errors = output_weights.T.dot(d_predicted_output)

Кроме того, вы должны уменьшить скорость обучения и увеличить количество эпох. У меня работает 10000 эпох и lr = 0.1, но вы можете это настроить.

...