Почему простая двухслойная нейронная сеть не может узнать последовательность 0,0?

Просматривая пример крошечной двухслойной нейронной сети, я заметил результат, который я не могу объяснить.

Предположим, у нас есть следующий набор данных с соответствующими метками:

[0,1] -> [0]
[0,1] -> [0]
[1,0] -> [1]
[1,0] -> [1]

Позвольте создать крошечный 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)

После того, как мы подготовили этот NN, мы протестируем его.

INPUT   PREDICTION
[0, 1] [ 0.00881315]
[1, 0] [ 0.99990851]
[1, 1] [ 0.5]
[0, 0] [ 0.5]

Хорошо, 0,1 и 1,0 - это то, чего мы ожидаем. Прогнозы для 0,0 и 1,1 также объяснимы, наш NN просто не имел данных обучения для этих случаев, поэтому добавьте его в наш набор учебных материалов:

[0,1] -> [0]
[0,1] -> [0]
[1,0] -> [1]
[1,0] -> [1]
[0,0] -> [0]
[1,1] -> [1]

Переустановите сеть и проверьте ее снова!

INPUT   PREDICTION
[0, 1] [ 0.00881315]
[1, 0] [ 0.99990851]
[1, 1] [ 0.9898148]
[0, 0] [ 0.5]
  • Подождите, почему [0,0] по-прежнему 0,5?

Это означает, что NN является еще неопределенным относительно 0,0, так же, когда он не знал о 1,1, пока мы его не обучили.

Ответ 1

Классификация также правильная. Вам нужно понять, что сеть смогла отделить тестовый набор.

Теперь вам нужно использовать функцию шага для классификации данных между 0 или 1.

В вашем случае 0.5 кажется хорошим threshold

EDIT:

Вам нужно добавить смещение к коду.

# 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