Эта программа вызывает переполнение в нелинейной функции. И, наконец, выход получает nan во всех элементах.
import numpy as np
def nonlin(x,deriv=False):
if(deriv==True):
return x*(1-x)
return 1/(1+np.exp(-x))
X = np.array([[0,0],[0,1],[1,0],[1,1]])
Y = np.array([[0],[1],[1],[0]])
w1 = np.random.random((2,2))
w2 = np.random.random((2,1))
for i in range(1000):
a0 = X
z1 = np.dot(a0,w1)
a1 = nonlin(z1)
z2 = np.dot(a1,w2)
a2 = nonlin(z2)
C = Y-a2
#if(i%10==0):
# print(np.mean(np.abs(C)))
Cdz2 = C*nonlin(z2,True)
Cdz1 = Cdz2.dot(w2.T)*nonlin(z1,True)
w2 += a1.T.dot(Cdz2)
w1 += a0.T.dot(Cdz1)
print(a2)
Метод backpropagation дает предупреждение во время выполнения в нелинейной функции.
Ваш выбор имен переменных может быть немного вводит в заблуждение: z
, как правило, на выходе нелинейности в то время как вы используете его для линейной комбинации, и вы используете как для входов и выходов. a
На этапе backpropagation вам нужно вычислить производную от вывода скрытого и выходного уровней после применения нелинейности.
Что в вашем случае должно быть
Cdz2 = C*nonlin(a2,True)
Cdz1 = Cdz2.dot(w2.T)*nonlin(a1,True)
где z2
становится a2
а z1
становится a1
С этим изменением он учится, у меня есть:
[[ 0.23807658]
[ 0.70736702]
[ 0.70728018]
[ 0.37925629]]
после 1000
шагов и
[[ 0.01972628]
[ 0.95332159]
[ 0.95332158]
[ 0.06245363]]
после 20000
шагов.
Я предлагаю вам использовать более разумные имена переменных, если вы следуете учебнику, просто используйте одну и ту же нотацию, чтобы было легче увидеть, как преобразования формул преобразуются в код.