构建一个四层的人工神经网络

2017-11-23 03:50

 从下午推导公式到现在,成功完成了四层神经网络的构建和相关代码的编写,用这个神经网络和之前三层的神经网络相比较,发现了一些比较有趣的现象(三层的和四层的神经网络暂时简写为T_rnnF_rnn,)。

首先,当训练次数较少时,T_rnn的结果更接近理想值,但两者相差并不大,训练次数增加后,F_rnn更接近理想值。

 

其次,之前忘了给F_rnn写更新b的代码,由此发现了更新b也是挺重要的,未添加代码前,与T_rnn差距在10^(-4)以内,添加代码后,差距在10^(-3)以内,且F_rnn的结果明显更接近理想值(均是在训练80次,alpha值在0.5是取得的数据)。

最后是速度,F_rnn所用的时间要比T_rnn多用0.3倍左右,单F_rnn拥有32个权值,而T_rnn只有16个,因此在连接程度上,F_rnnT_rnn更加复杂,而速度只比T_rnn0.3倍,可见向量化处理的确是有作用的(T_rnn我为了更直观一点,是依次运算单个值的,并未向量化操作)。
下面是这个神经网络的结构图:


该神经网络的python3代码:

import numpy as np

def sigma(z):
    return 1/(1+np.exp(-z))

def sigma_da(a):
    return a*(1-a)

def run():
    x=np.array([0.15,0.6,0.2])#输入
    y=0.32#理想输出
    np.random.seed(1)#加上这一条语句可以确保每次随机生成的数都一样
    #初始化权值矩阵
    w1=np.random.random((4,3))
    w2=np.random.random((4,4))
    w3=np.random.random(4)
    #初始化截距项
    b1=np.sum(np.random.random(1))
    b2=np.sum(np.random.random(1))
    b3=np.sum(np.random.random(1))
    alpha=0.5#学习率,相当于梯度下降步长
    m=100#循环次数    
    for i in range(m):
        '''网络共分4层,输入层x、隐含层l1、隐含层l2、输出层y'''
        #计算l1层
        netl1=np.array([sum(x*w1[0]),sum(x*w1[1]),sum(x*w1[2]),sum(x*w1[3])])+b1
        outl1=sigma(netl1)
        #计算l2层        netl2=np.array([sum(outl1*w2[0]),sum(outl1*w2[1]),sum(outl1*w2[2]),sum(outl1*w2[3])])+b2
        outl2=sigma(netl2)
        #计算输出层
        nety=sum(outl2*w3)+b3
        outy=sigma(nety)
        #总误差
        Ey=0.5*(y-outy)*(y-outy)
        #反向传播
        #输出层误差
        delta_y=-(y-outy)*sigma_da(outy)
        #l2层误差
        delta_l2=np.array([delta_y*w3[0]*sigma_da(outl2[0]),
                           delta_y*w3[1]*sigma_da(outl2[1]),
                           delta_y*w3[2]*sigma_da(outl2[2]),
                           delta_y*w3[3]*sigma_da(outl2[3])])
        #l1层误差
        delta_l1=np.array([sum(delta_l2*w2[0])*sigma_da(outl1[0]),
                           sum(delta_l2*w2[1])*sigma_da(outl1[1]),
                           sum(delta_l2*w2[2])*sigma_da(outl1[2]),
                           sum(delta_l2*w2[3])*sigma_da(outl1[3])])
        #计算输入层和l1层之间的权值矩阵w1对整体误差的偏导
        dw1=np.array([delta_l1*x[0],
                      delta_l1*x[1],
                      delta_l1*x[2]])
        #更新w1
        w1-=dw1.T*alpha
        #计算截距项b1对整体误差的偏导
        db1=sum(delta_l1)
        #更新b1
        b1-=db1*alpha
        #计算l1层和l2层之间的权值矩阵w2对整体误差的偏导
        dw2=np.array([delta_l2*outl1[0],
                      delta_l2*outl1[1],
                      delta_l2*outl1[2],
                      delta_l2*outl1[3]])
        #更新w2
        w2-=dw2.T*alpha
        #计算截距项b2对整体误差的偏导
        db2=sum(delta_l2)
        #更新b2
        b2-=db2*alpha
        #计算l2层和输出层之间的权值矩阵w3对整体误差的偏导
        dw3=delta_y*outl2
        #更新w3
        w3-=dw3*alpha
        #计算截距项b3对整体误差的偏导
        db3=delta_y
        #更新b3
        b3-=db3*alpha
    #向屏幕打印训练完成后的结果
    print(outy)

if __name__=='__main__':
    run()



下面是推导时的手稿: 

 

图片

 







發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章