@riZe_0

Как исправить неправильное обновление весов в реализации back propagation?

Есть реализация логической операции XOR с помощью нейронной сети, обучение - back propagation, язык - python:
import numpy as np

class NeuralNetwork:
    
    def __init__(self, input_size, hidden_size, output_size):
        
        self.weights_input_hidden = np.random.rand(input_size + 1, hidden_size).T
        self.weights_hidden_output = np.random.rand(hidden_size + 1, output_size).T
        #print('Веса входного слоя (weights_input)=\n', self.weights_input_hidden) # w_jh
        #print('Веса выходного слоя (weights_hidden)=\n', self.weights_hidden_output, '\n') # w_hm

    def sigmoid(self, x):
        return 1 / (1 + np.exp(-x))
    
    def sigmoid_derivative(self, x):
        return x * (1 - x)
    
    # Прямой ход
    def feedforward(self, X):
        self.hidden_layer_activation = np.dot(self.weights_input_hidden, X)
        self.hidden_layer_output = self.sigmoid(self.hidden_layer_activation) # u_h / sigma_h
        self.hidden_layer_output_bias = np.concatenate((self.hidden_layer_output, [-1]))
        
        self.output_layer_activation = np.dot(self.weights_hidden_output, self.hidden_layer_output_bias)
        output = self.sigmoid(self.output_layer_activation) # a_m / sigma_m
        
        return output
        
    # Обратный ход
    def back_prop(self, X, y, output, theta):
        output_error = output - y
        output_delta = output_error * self.sigmoid_derivative(output)
        
        hidden_error = output_delta.dot(self.weights_hidden_output)
        hidden_delta = hidden_error * self.sigmoid_derivative(self.hidden_layer_output_bias)
        
        self.weights_hidden_output -= theta * output_delta * self.hidden_layer_output_bias
        self.weights_input_hidden -= theta * hidden_delta * X
        
    def train(self, X, y, epochs, theta=0.01):
        X = np.concatenate((X, [-1]))
        for epoch in range(epochs):
            output = self.feedforward(X)
            self.back_prop(X, y, output, theta)
        
X = np.array([[0, 0],
              [0, 1],
              [1, 0],
              [1, 1]])

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

xor = NeuralNetwork(2, 2, 1)

for i in range(len(y)):
    xor.train(X[i], y[i], 10000)

for x in X:
    x = np.concatenate((x, [-1]))
    print(f"{x} -> {xor.feedforward(x)}")


Проблема:
После обучения сети получается неправильный ответ (если значение xor.feedforward > 0.5, 1, 0). Пробовал вариант с добавлением смещения в виде отдельной переменной, пробовал даже без самого смещения - ответ неверный.
Подозреваю, что проблема в обновлении весов в функции back_prop, но где именно и почему я понять не в состоянии. Чувствую, что ответ лежит на поверхности.
Теорию брал из лекций К.В.Воронцова 2014 года на youtube.
Сам алгоритм из лекции:
671d0cb72094e823554228.png
  • Вопрос задан
  • 13 просмотров
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы