def sigmoid(x):
y = 1/(1+np.exp(-x))
return y
def dersigmoid(x):
y=x*(1-x)
return y
step = 0.1
ipnumber = 2
hdnumber = 32
opnumber = 2
neu_i2h = 2*np.random.random((ipnumber,hdnumber)) - 1
neu_h2o = 2*np.random.random((hdnumber,opnumber)) - 1
neu_h2h = 2*np.random.random((hdnumber,hdnumber)) - 1
neu_i2hN = np.zeros_like(neu_i2h)
neu_h2oN = np.zeros_like(neu_h2o)
neu_h2hN = np.zeros_like(neu_h2h)
这里首先初始化三个随机数值的矩阵,分别代表输入层和隐藏层、隐藏层和输出层、隐藏层和隐藏层之间的连接权值,在之后的操作中,这三个矩阵中的数值不断随着网络的学习进行更改,最终使得网络中的权值能正确的对给定的输入值进行处理。
之后网络设定了三个值为零的大小和权值网络相同的矩阵,为的是进行每一次学习的暂时结果的记录。这些矩阵在每一次循环完之后都会将其重置为零矩阵。
训练数据集初始化
这里便于神经网络的更精确的计算,将输入神经网络的数值转换成二进制数字。
在这里的 bdigitbdigit 设定的是二进制数字的最大位数,即设定一个神经网络输入值的取值范围。并设定初始的字典 i2bi2b 。
i2b = {}
bdigit = 8
MAXnumber = pow(2,bdigit)
bin = np.unpackbits(np.array([range(MAXnumber)],dtype=np.uint8).T,axis=1)
for i in range(MAXnumber):
i2b[i] = bin[i]
for j in range(20000):
a_decimal = np.random.randint(MAXnumber / 2)
b_decimal = np.random.randint(MAXnumber / 2)
c_decimal = a_decimal + b_decimal
a = i2b[a_decimal]
b = i2b[b_decimal]
c = i2b[c_decimal]
binary = np.zeros_like(c)
aError = 0
oplayer_der = list()
hdlayer_val = list()
hdlayer_val.append(np.zeros(hdnumber))
for locate in range(bdigit):
X = np.array([[a[bdigit - locate - 1],b[bdigit - locate - 1]]])
Y = np.array([[c[bdigit - locate - 1]]]).T
hdlayer = sigmoid(np.dot(X,neu_i2h) + np.dot(hdlayer_val[-1],neu_h2h))
oplayer = sigmoid(np.dot(hdlayer,neu_h2o))
oplayer_error = Y - oplayer
oplayer_der.append((oplayer_error)*dersigmoid(oplayer))
aError += np.abs(oplayer_error[0])#首先计算出输出层和真是值的误差 oplayer_erroroplayer_error ,并将每一次训练输出值的导数进行储存,最后将句对误差进行相加。
binary[bdigit - locate - 1] = np.round(oplayer[0][0])
hdlayer_val.append(copy.deepcopy(hdlayer))
Fhdlayer_dels = np.zeros(hdnumber)
for locate in range(bdigit):
X = np.array([[a[locate],b[locate]]])
hdlayer = hdlayer_val[-locate-1]
hdlayer_pre = hdlayer_val[-locate-2]#反向将数据进行检索,以便于之后的误差的计算。通过前一个循环得到的隐藏层的数组,取出相应的隐藏层的值准备误差运算。
oplayer_dels = oplayer_der[-locate-1]
hdlayer_dels = (Fhdlayer_dels.dot(neu_h2h.T) + oplayer_dels.dot(neu_h2o.T)) * dersigmoid(hdlayer)#统计得到输出层和隐藏层的误差,以便权值进行更新。这里得到了两个网络层的误差,通过这两组误差将权值进行更新。
neu_h2oN += np.atleast_2d(hdlayer).T.dot(oplayer_dels)
neu_h2hN += np.atleast_2d(hdlayer_pre).T.dot(hdlayer_dels)
neu_i2hN += X.T.dot(hdlayer_dels)
Fhdlayer_dels = hdlayer_dels
neu_i2h += neu_i2hN * step
neu_h2o += neu_h2oN * step
neu_h2h += neu_h2hN * step
neu_i2hN *= 0
neu_h2oN *= 0
neu_h2hN *= 0#进行权值更新