我正在尝试学习神经网络,并编写了一个简单的反向传播神经网络,该网络使用S型激活函数和随机权重初始化。我正在尝试在输入层中使用两个输入值3和2以及在输出层中使用目标输出6进行乘法。当我执行代码时,w1
和w2
的值会不断增加,并且不会停留在正确的值上。
我对Python和神经网络都是陌生的,非常感谢您的帮助。
import numpy as np
al0 = 3
bl0 = 2
import random
w1 =random.random()
w2 =random.random()
b = 0.234
ol1 = 6
def sigm(x,deriv=False):
if deriv==True:
return x*(1-x)
return 1/(1+np.exp(-x))
y = sigm(x)
E = 1/2*(ol1 - y)**2
dsig = sigm(x,True)
dyE = y-ol1
for iter in range(10000):
syn0 = al0*w1
syn1 = bl0*w2
x = syn0 + syn1 + b
dtotal1 = dyE*dsig*al0
w1 = w1 + 0.01*dtotal1
dtotal2 = dyE*dsig*bl0
w2 = w2 + 0.01*dtotal2
w1
w2
答案 0 :(得分:1)
首先,您需要按顺序获取代码。这些行
y = sigm(x)
E = 1/2*(ol1 - y)**2
dsig = sigm(x,True)
dyE = y-ol1
需要在x = syn0 + syn1 + b
之后的for循环内发生。
接下来,有一些神经网络项目需要解决。 Here是对反向传播的技术描述。
sigm(x)
的派生词是sigm(x) * (1 - sigm(x))
,或者在您的情况下是y * (1 - y)
,您已经实现了sigm(y,True)
。
您的偏见也需要更新。这是网络的重要组成部分,是学习的参数。您可以使用:
dtotalb = dyE*dsig*1
b = b - 0.01*dtotalb
乘以1是不必要的,但很有启发性。这是相对于x
(即1)的“ net”项的派生,您称之为b
。
您可能已经注意到,我为b提供的更新使用的是-
而不是+
。上方链接中this section的最后一行显示了这样做的必要性,以确保更新方向正确,以最大程度地减少错误。
最后,考虑网络可以输出的可能值。最终输出y
是调用sigm(x)
的结果。 y
可以采用的值在打开间隔(0,1)中。但是,您的网络正在尝试学习6的值。它可以获取的最接近值几乎是1。因此,当您继续进行迭代时,权重将继续增加以尝试增加S型输出。权重将无限期增长。
进行所有这些更改后,请尝试将目标设置为(0,1),例如0.6。当我进行所有这些更改时,我能够使E
减小到接近0,并且使您的权重收敛。
旁注:为了让您的网络学习值6,您需要不使用激活功能的另一层权重。另外,您可以删除激活功能,但随后开始失去尝试学习的神经网络方法。