Решение проблемы XOR с нейрокодированной нейронной сетью в Python - PullRequest
0 голосов
/ 29 сентября 2018

Я борюсь с самокодированной версией простой нейронной сети, состоящей из 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]

Спасибо за любые советы, предложения или решения!

...