与逻辑门的单层神经网络 (Python)

Single Layer Neural Network for AND Logic Gate (Python)

我一直在尝试让以下神经网络充当简单的与门,但它似乎不起作用。以下是我的代码:

import numpy as np

def sigmoid(x,derivative=False):
    if(derivative==True):
        return x*(1-x)
    return 1/(1+np.exp(-x))

np.random.seed(1)

weights = np.array([0,0,0])

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

for iter in xrange(training.shape[0]):
#forwardPropagation:
        a_layer1 = training[iter][0]
        z_layer2 = np.dot(weights,a_layer1)
        a_layer2 = sigmoid(z_layer2)
        hypothesis_theta = a_layer2

#backPropagation:
        delta_neuron1_layer2 = a_layer2 - training[iter][1]
        Delta_neuron1_layer2 = np.dot(a_layer2,delta_neuron1_layer2)
        update = Delta_neuron1_layer2/training.shape[0]
        weights = weights-update

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

print weights
print sigmoid(np.dot(weights,x))

上面的程序不断返回奇怪的值作为输出,输入 X 返回的值高于数组 [1,1,1]。 training/testing'inputs'中每一个的第一个元素代表偏置单元。该代码基于 Andrew Ng 在他的 Coursera 机器学习课程中的视频:https://www.coursera.org/learn/machine-learning

在此先感谢您的协助。

一些提示:

  1. NN 需要大量数据。您不能向它传递少量样本并期望它学到很多东西。
  2. 您正在使用列表和一维数组而不是二维数组。这对 numpy 来说是危险的,因为它会在没有假设任何形状的地方盲目广播,这在某些情况下可能很危险。
  3. 你没有像你应该的那样在你的反向传播中使用 sigmoid 导数

我重塑了你的数组,也增加了你的输入。

import numpy as np

def sigmoid(x,derivative=False):
    if(derivative==True):
        return x*(1-x)
    return 1/(1+np.exp(-x))

np.random.seed(1)

weights = np.random.randn(1, 3)

training = np.array([[np.array([0, 0, 0]).reshape(1, -1), 1],
                    [np.array([0,0,1]).reshape(1, -1), 0],
                    [np.array([0,1,0]).reshape(1, -1), 0],
                    [np.array([0,1,1]).reshape(1, -1), 0],
                    [np.array([1, 0, 0]).reshape(1, -1), 1],
                    [np.array([1,0, 1]).reshape(1, -1), 0],
                    [np.array([1,1,0]).reshape(1, -1), 0],
                    [np.array([1,1,1]).reshape(1, -1), 1],

                    ])

for iter in xrange(training.shape[0]):
#forwardPropagation:
        a_layer1 = training[iter][0]
        z_layer2 = np.dot(weights,a_layer1.reshape(-1, 1))
        a_layer2 = sigmoid(z_layer2)
        hypothesis_theta = a_layer2

#backPropagation:
        delta_neuron1_layer2 =  (a_layer2 - training[iter][1] ) * sigmoid(a_layer2 , derivative=True)
        Delta_neuron1_layer2 = np.dot(delta_neuron1_layer2 , a_layer1)
        update = Delta_neuron1_layer2
        weights = weights - update 


x = np.array([0,0, 1])
print sigmoid(np.dot(weights,x.reshape(-1, 1)))

x = np.array([0,1,1])
print sigmoid(np.dot(weights,x.reshape(-1, 1)))

x = np.array([1,1,1])
print sigmoid(np.dot(weights,x.reshape(-1, 1))) 

输出:

[[ 0.34224604]]
[[ 0.19976054]]
[[ 0.52710321]]

不干净,当然还有改进的余地。但至少,你现在有所收获。预计产生理论 0 的输入比应该产生理论 1 的输入更接近 0。