Я работаю над школьным заданием.Я должен обучить нейронную сеть так, чтобы она могла решить проблему XOR Gate.
Мой дизайн - это нейронная сеть с входным слоем из двух нейронов, скрытым слоем из двух нейронов и выходным слоем толькоодна сеть.Я использую функцию sigmoid
и соответствующую ей производную в качестве функции активации.Я уже много раз проверял алгоритм, пытаясь найти что-то не так, но кажется, что шаги выполняются правильно, но когда дело доходит до вычисления среднеквадратичной ошибки, он застревает в значениях около 0.5000
.
Может кто-нибудь помочь?Я опубликую свой код, чтобы вы могли проверить его и сказать мне, если вы видите что-то необычное.У меня есть класс с именем Adaline
и сценарий, который использует этот класс, веса создаются автоматически в значениях от -1 до 1, а скорость обучения, которую я использую, составляет 0,1.Смещения добавляются во входные данные, добавляя 1
к ним, каждый раз, когда это необходимо.
Что следует сделать, так это то, что если среднеквадратичная ошибка достигнет значения, меньшего allowed_error
, это будет означать, чтоон правильно обучен, и пришло время попробовать его еще раз с примерами, и он должен показать значение, очень близкое к ожидаемому с проблемой XOR.
Заранее спасибо.
import numpy as np
class Adaline(object):
def __init__(self, no_of_inputs, learning_rate = 0.1):
self.weights = np.random.uniform(-1, 1, no_of_inputs + 1)
self.delta = 0
self.current_error = 0
self.propagation_output = 0
self.learning_rate = learning_rate
def sigmoid(self, prediction):
return 1 / (1 + np.exp(-prediction))
def derivative(self):
return self.sigmoid(self.propagation_output) * (1 - self.sigmoid(self.propagation_output))
def summation(self, inputs):
summation = np.dot(inputs, self.weights)
return summation
def calculate_output(self, inputs):
summation = self.summation(inputs)
self.propagation_output = self.sigmoid(summation)
def train(self, inputs):
self.weights += self.learning_rate * inputs * self.delta
Скрипт для обучения нейронной сети
import numpy as np
from adaline import Adaline
adaline1 = Adaline(no_of_inputs = 2)
adaline2 = Adaline(no_of_inputs = 2)
adaline3 = Adaline(no_of_inputs = 2)
allowed_error = 0.1
keep_iterating = True
inputs = np.array([
[0, 0],
[0, 1],
[1, 0],
[1, 1],
])
outputs = np.array([
0,
1,
1,
0
])
network = []
hidden_layer = []
output_layer = []
hidden_layer.append(adaline1)
hidden_layer.append(adaline2)
output_layer.append(adaline3)
network.append(hidden_layer)
network.append(output_layer)
errors = np.empty(outputs.shape)
while keep_iterating:
sample_number = 0
for sample, expected_output in zip(inputs, outputs):
temp_inputs = np.insert(sample, 0, 1) #preprend 1 for the bias
#propagation
for i in range(len(network)):
for j in range(len(network[i])):
if i != 0:
temp_inputs = np.random.rand(len(network[i - 1]) + 1)
temp_inputs[0] = 1
for _ in (number + 1 for number in range(len(network[i - 1]))):
temp_inputs[_] = network[i - 1][_ - 1].propagation_output
network[i][j].calculate_output(temp_inputs)
#backpropagating the error
for i in reversed(range(len(network))):
for j in range(len(network[i])):
if i == 1:
error = expected_output - network[i][j].propagation_output
errors[sample_number] = (error**2)
local_gradient = error * network[i][j].derivative()
else:
local_gradient = 0
for _ in (range(len(network[i + 1]))):
local_gradient += network[i + 1][_].weights[j + 1] * network[i + 1][_].delta
local_gradient *= network[i][j].derivative()
network[i][j].delta = local_gradient
#updating weights
for i in range(len(network)):
for j in range(len(network[i])):
if i == 0:
temp_inputs = np.insert(sample, 0, 1) #preprend 1 for the bias
else:
temp_inputs = np.random.rand(len(network[i - 1]) + 1)
temp_inputs[0] = 1
for _ in (number + 1 for number in range(len(network[i - 1]))):
temp_inputs[_] = network[i - 1][_ - 1].propagation_output
network[i][j].train(temp_inputs)
sample_number += 1
global_error = errors.sum() / 2
print(global_error)
print('\n')
if global_error <= allowed_error:
keep_iterating = False
print("salidas")
for sample, expected_output in zip(inputs, outputs):
# propagation
for i in range(len(network)):
for j in range(len(network[i])):
if i != 0:
temp_inputs = np.random.rand(len(network[i - 1]) + 1)
temp_inputs[0] = 1 #prepren 1 for the bias
for _ in (number + 1 for number in range(len(network[i - 1]))):
temp_inputs[_] = network[i - 1][_ - 1].propagation_output
network[i][j].calculate_output(temp_inputs)
if i == 1:
print(network[i][j].propagation_output)