为什么简单的2层神经网络无法学习0,0序列?

min*_*als 14 python machine-learning neural-network

在通过一个微小的2层神经网络的例子时,我注意到了我无法解释的结果.

想象一下,我们有以下数据集和相应的标签:

[0,1] -> [0]
[0,1] -> [0]
[1,0] -> [1]
[1,0] -> [1]
Run Code Online (Sandbox Code Playgroud)

让我们创建一个微小的2层NN,它将学习预测两个数字序列的结果,其中每个数字可以是0或1.我们将根据上面提到的数据集训练这个NN.

    import numpy as np

    # compute sigmoid nonlinearity
    def sigmoid(x):
        output = 1 / (1 + np.exp(-x))
        return output

    # convert output of sigmoid function to its derivative
    def sigmoid_to_deriv(output):
        return output * (1 - output)

    def predict(inp, weigths):
        print inp, sigmoid(np.dot(inp, weigths))

    # input dataset
    X = np.array([ [0,1],
                   [0,1],
                   [1,0],
                   [1,0]])
    # output dataset
    Y = np.array([[0,0,1,1]]).T

    np.random.seed(1)

    # init weights randomly with mean 0
    weights0 = 2 * np.random.random((2,1)) - 1

    for i in xrange(10000):
        # forward propagation
        layer0 = X
        layer1 = sigmoid(np.dot(layer0, weights0))
        # compute the error
        layer1_error = layer1 - Y

        # gradient descent
        # calculate the slope at current x position
        layer1_delta = layer1_error * sigmoid_to_deriv(layer1)
        weights0_deriv = np.dot(layer0.T, layer1_delta)
        # change x by the negative of the slope (x = x - slope)
        weights0 -= weights0_deriv

    print 'INPUT   PREDICTION'
    predict([0,1], weights0)
    predict([1,0], weights0)
    # test prediction of the unknown data
    predict([1,1], weights0)
    predict([0,0], weights0)
Run Code Online (Sandbox Code Playgroud)

在我们训练了这个NN之后,我们进行了测试.

INPUT   PREDICTION
[0, 1] [ 0.00881315]
[1, 0] [ 0.99990851]
[1, 1] [ 0.5]
[0, 0] [ 0.5]
Run Code Online (Sandbox Code Playgroud)

好了,0,1而且1,0是我们所期望的那样.对于这些情况的预测0,01,1可解释,我们的NN只是没有这些案例的训练数据,所以让我们将它添加到我们的训练数据集中:

[0,1] -> [0]
[0,1] -> [0]
[1,0] -> [1]
[1,0] -> [1]
[0,0] -> [0]
[1,1] -> [1]
Run Code Online (Sandbox Code Playgroud)

重新调整网络并再次测试!

INPUT   PREDICTION
[0, 1] [ 0.00881315]
[1, 0] [ 0.99990851]
[1, 1] [ 0.9898148]
[0, 0] [ 0.5]
Run Code Online (Sandbox Code Playgroud)
  • 等等,为什么[0,0]仍为0.5

这意味着NN 仍然不确定0,0,在1,1我们训练它之前它是不确定的.

Alv*_*oao 12

分类也是正确的.您需要了解网络能够分离测试集.

现在您需要使用步进函数来对0或之间的数据进行分类1.

在你的情况下0.5似乎是一个很好的threshold

编辑:

您需要在代码中添加偏差.

# input dataset
X = np.array([ [0,0,1],
               [0,0,1],
               [0,1,0],
               [0,1,0]])

# init weights randomly with mean 0
weights0 = 2 * np.random.random((3,1)) - 1
Run Code Online (Sandbox Code Playgroud)

  • 是的,添加一个偏差,如果你想解释原因,请考虑在没有偏置单位的神经网络中[0,0]的输入会发生什么.由于神经网络在每个层之间执行乘法,因此权重没有影响,因为任何数字乘以0仍为0.因此,在最后一层,每个节点的激活为0,并且当零传递给sigmoid时功能,它输出.5,这是你的网络输出. (9认同)