反向傳播:代碼演示篇
概述
本節繼上一節反向傳播:公式推導篇的代碼演示,本節將從零開始演示反向傳播訓練參數的整個過程,除此之外還將使用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、藉助深度學習框架
待更新。。。