反向傳播:代碼演示篇

概述

本節繼上一節反向傳播:公式推導篇的代碼演示,本節將從零開始演示反向傳播訓練參數的整個過程,除此之外還將使用TF2.0來進行快速求導作爲拓展演示。

正文

首先想一下訓練模型的步驟:
1、創建一個模型
2、準備好模型的輸入,以及標籤
3、損失函數根據模型的輸出以及標籤求出損失值
4、求損失函數對各個參數的偏導
5、根據求出的偏導數值更新參數

1、從零開始

由於是從零開始,所以這裏我們使用一個非常簡單的模型g(a,x,y)以方便求偏導,如下:
a表示模型的輸入,x、y表示變量,也就是我們訓練的值。

def g(a,x,y):
    h1=a*(x**2+x)
    h2=h1*y+2*y
    return h2,h1

有了g(a,x,y)這個前向傳播函數,我們就可以求出反向傳播的偏導數,這裏損失函數我們使用均方誤差0.5*(g_predict - g_target)**2,加0.5是爲了求導後更簡單。
有高數基礎的,我們可以輕易得出以下偏導數

#損失函數L對模型輸出g的偏導
def _dL_dg(g_predict,g_target):
    return g_predict-g_target
#g對參數y的偏導    
def _dg_dy(h1,y):
    return h1+2
#g對h1的偏導
def _dg_dh1(y):
    return y
#h1對參數x的偏導
def _dh1_dx(a,x):
    return a*(2*x + 1)

開始訓練:

import numpy as np
import random

#初始化參數x、y
x=np.array(0.).astype("float32")
y=np.array(0.).astype("float32")
#這裏手動設置你想要訓練的最終的x、y的值。
#一方面可以得出標籤,一方面能直觀驗證自己的模型的有沒有訓練成功
x_target=np.array(1)
y_target=np.array(5)
#定義學習率
lr=0.01
#開始訓練
for i in range(1000):
	#隨機取輸入
    a = np.array(np.random.random()).astype("float32")
    #根據自己設定的值,得出標籤
    g_target, _ = g(a,x_target,y_target)
    #得出模型預測的值
    g_predict, h1 = g(a,x,y)
	#求出損失值
    L=0.5*(g_predict-g_target)**2
    
	#開始反向傳播
    dL_dg = _dL_dg(g_predict,g_target)
    dg_dh1= _dg_dh1(y)
    dh1_dx= _dh1_dx(a,x)
    
    #根據鏈式法則,求出dg_dy,dg_dx
    dg_dy = dL_dg * _dg_dy(h1, y)
    dg_dx = dL_dg * dg_dh1 * dh1_dx
    
    #根據學習率,以及梯度(偏導)dg_dy,dg_dx更新參數值
    x=x - lr*dg_dx
    y=y - lr*dg_dy

    if i%100==0:
        print('Loss:',L)
        
print('x:',x)
print('y:',y)

運行輸出:

Loss: 121.5706952295294
Loss: 0.532752900621499
Loss: 0.01831088644040585
Loss: 0.004482554627769781
Loss: 0.0021340579303471266
Loss: 0.0011336842526728065
Loss: 6.456618332174425e-05
Loss: 1.3528191843236397e-07
Loss: 1.1819489879170875e-07
Loss: 2.6564044454382296e-07
x: 1.0000843120267124
y: 4.99975193425045

分析:我們可以看到訓練1000次後,x=1.0000843120267124
y=4.99975193425045;與x_target=1,y_target=5非常接近。

2、藉助深度學習框架

待更新。。。

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