構建一個四層的人工神經網絡

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()



下面是推導時的手稿: 

 

圖片

 







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