Я борюсь с самокодированной версией простой нейронной сети, состоящей из 2 входных, 2, скрытых и 1 выходных слоев.
Конечно, код отлично работает для различных данных ипредсказывает правильные результаты.Но это не решает проблему XOR.При подаче данных такого рода в сеть прогнозы для всех комбинаций значений x ([01, 10, 00, 11]) приводят к значениям около 0,5.
Возможно, я что-то неправильно понял, но я подумал, что это должноможно было решить эту проблему с установкой 2 x 2 x 1 с смещением (см. XOR, решаемая с помощью нейронной сети 2x2x1 без смещения? ).
Вот мой код ( _on для выходного нейрона, _hn для скрытого нейрона):
class NeuralNetSimple:
def __init__(self, weights_on, weights_hn):
self.weights_on = weights_on
self.weights_hn = weights_hn
self.out_all_hn = np.zeros(self.weights_hn.shape[0])
self.in_all_on = None
def activation(self, x_dat, weights):
return x_dat.dot(weights)
def logit(self, in_ges):
return 1 / (1 + np.exp(-in_ges))
def forward_prop(self, x_zeile):
""" Calculate hidden layer output """
for neuron in range(self.weights_hn.shape[0]):
akt_hn = self.activation(x_zeile, self.weights_hn[neuron])
self.out_all_hn[neuron] = self.logit(akt_hn)
""" Calculate output layer output"""
self.in_all_on = np.insert(self.out_all_hn, 0, 1) # add bias
akt_h3 = self.activation(self.in_all_on, self.weights_on)
y_pred = self.logit(akt_h3)
return y_pred
def fit(self, x_dat, y_true, learning_rate, epochs=1000):
""" add bias to x_dat """
x_dat_b = np.insert(x_dat, 0, 1, axis=1)
for iter in range(epochs):
for i in range(x_dat_b.shape[0]):
""" Forward propagation """
y_pred = self.forward_prop(x_dat_b[i])
""" Backward propagation: hidden layer """
## iterate over each neuron
for neuron in range(self.weights_hn.shape[0]):
## iterate over each weight/neuron
for g in range(self.weights_hn.shape[1]):
derivate_hn = self.derivate_hn(y_true[i],
y_pred,
self.weights_on[neuron+1],
self.out_all_hn[neuron],
x_dat_b[i][g])
self.weights_hn[neuron][g] -= derivate_hn * learning_rate
""" Backward propagation: output layer """
for g in range(self.weights_on.shape[0]):
derivate_on = self.derivate_on(y_true[i], y_pred, self.in_all_on[g])
self.weights_on[g] -= derivate_on * learning_rate
def derivate_on(self, y_true, y_pred, x):
error_out_d = -(y_true - y_pred)
out_in_d = y_pred * (1-y_pred)
in_weight_d = x
return error_out_d * out_in_d * in_weight_d
def derivate_hn(self, y_true, y_pred, weight_on, out_hn, x):
error_out_d = -(y_true - y_pred) * y_pred * (1 - y_pred) * weight_on
out_in_d = out_hn * (1-out_hn)
gew_in_d = x
return error_out_d * out_in_d * gew_in_d
А вот и данные:
X = np.array([[0,0],[0,1],[1,0],[1,1]])
Y = np.array([[0],[1],[1],[0]])
learning_rate = 0.3
weights_hn = np.array([[0.1, 0.5, -0.1],[0.1, -0.3, 0.2]])
weights_on = np.array([0.1, 0.4, -0.2])
nn1 = NeuralNetSimple(weights_on, weights_hn)
nn1.fit(X, Y, learning_rate)
# first value is bias
x_test1 = np.array([1, 0, 1])
y_1 = nn1.forward_prop(x_test1)
print('estimated', y_1, 'input:', x_test1)
x_test2 = np.array([1, 1, 0])
y_2 = nn1.forward_prop(x_test2)
print('estimated', y_2, 'input:', x_test2)
x_test3 =np.array([1, 1, 1])
y_3 = nn1.forward_prop(x_test3)
print('estimated', y_3, 'input:', x_test3)
Результаты
estimated 0.496 input: [1 0 1]
estimated 0.504 input: [1 1 0]
estimated 0.500 input: [1 1 1]
estimated 0.499 input: [1 0 0]
Спасибо за любые советы, предложения или решения!