Однослойная нейронная сеть для логических элементов AND (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]. Первый элемент каждого из "входов" обучения / тестирования представляет единицу смещения. Кодекс был основан на видео Эндрю Нг на его курсе Coursera по машинному обучению: https://www.coursera.org/learn/machine-learning
Заранее спасибо за вашу помощь.
1 ответ
Несколько указателей:
- НН нужно много данных. Вы не можете передать ему несколько образцов и ожидать, что он многому научится.
- Вы работаете со списками и одномерными массивами вместо 2D-массивов. Это опасно для numpy, потому что оно будет транслироваться вслепую везде, где не предполагается фигура, что может быть опасно в некоторых случаях.
- Вы не используете сигмовидную производную в обратном распространении, как вы должны
Я изменил ваши массивы, а также увеличил ваш вклад.
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, ближе к 0, чем входные данные, которые должны давать теоретический 1.