一文看懂计算机神经网络与梯度下降
1. 計算機神經(jīng)網(wǎng)絡(luò)與神經(jīng)元
要理解神經(jīng)網(wǎng)絡(luò)中的梯度下降算法,首先我們必須清楚神經(jīng)元的定義。如下圖所示,每一個神經(jīng)元可以由關(guān)系式y=f(∑i=1nwixi+b)y = f(\sum_{i=1}^nw_ix_i + b)y=f(∑i=1n?wi?xi?+b)來描述,其中X=[x1,x2,...,xn]X = [x_1,x_2,...,x_n]X=[x1?,x2?,...,xn?]就是N維的輸入信號,W=[w1,w2,...,wn]W =[w_1,w_2,...,w_n]W=[w1?,w2?,...,wn?]是與輸入向量一一對應(yīng)的n維權(quán)重,bbb bias 偏斜,yyy對應(yīng)該神經(jīng)元的輸出,fff函數(shù)稱為激勵函數(shù),例如sigmoid函數(shù),softmax函數(shù)等等。
那么一個神經(jīng)網(wǎng)絡(luò)是如何進行學(xué)習的呢?以一個神經(jīng)元為例,在一組輸入信號XXX經(jīng)過該神經(jīng)元后,我們得到了一個輸出信號稱之為yetoiley_{etoile}yetoile?,而訓(xùn)練集中給出的實際輸出例如為yyy,那么顯而易見地,想要提高正確率,即正確地學(xué)習對于一組輸入應(yīng)該獲得的輸出yyy,一個神經(jīng)元所做的計算,就是一個最優(yōu)化(最小化)問題,通過改變權(quán)重WWW來最小化損失(誤差) l(y,yetoile)l(y,y_{etoile})l(y,yetoile?)。當然,這個誤差的定義可以根據(jù)問題的不同有所區(qū)別,例如簡單的向量L1,L2距離,MSE均方誤差。對于整個訓(xùn)練集而言,當然不止包含了一組輸入輸出。因此整體而言,誤差Loss Function L(W)=1N∑t=1Kl(yt,ytetoile)L(W) = \frac{1} {N}\sum_{t=1}^{K}l(y_t,y_{t_{etoile}})L(W)=N1?∑t=1K?l(yt?,ytetoile??) 是所有K組訓(xùn)練數(shù)據(jù)誤差的總和的平均數(shù)。
我們已經(jīng)知道了,Loss Function損失函數(shù)與神經(jīng)元的權(quán)重息息相關(guān),神經(jīng)元要做的計算,就是找到能最小化該損失函數(shù)的權(quán)重WWW。優(yōu)化的算法紛繁多樣,使用的較為廣泛的就是梯度下降gradientdescentgradient\space\space descentgradient??descent 及其衍生算法SGD隨機梯度下降,BGD批量梯度下降。
2. 梯度下降算法 gradientdescentgradient\space\space descentgradient??descent
梯度下降算法,一言以蔽之,就是沿著梯度下降的方向不斷迭代,最終逼近函數(shù)最小值的優(yōu)化方法。如下圖所示,在最小化Loss Function損失函數(shù)的過程中,權(quán)重總是沿著損失函數(shù)梯度下降的方向變化,即wi=wi?λ?L∣wiw_i = w_i - \lambda\nabla L|_{w_i}wi?=wi??λ?L∣wi??,其中λ\lambdaλ為學(xué)習率。當損失函數(shù)的梯度接近0時,可以終止迭代。大致理解了梯度下降算法的原理,接下我們看看在優(yōu)化神經(jīng)元的過程中,梯度下降算法是如何實現(xiàn)的。
3. backpropagation 反向傳播算法
通過上一個部分,我們理解了使權(quán)重沿著Loss的梯度下降方向迭代,可以最終最小化損失函數(shù)。這個過程中,權(quán)重的更新wi=wi?λ?L∣wiw_i = w_i - \lambda\nabla L|_{w_i}wi?=wi??λ?L∣wi??取決于損失函數(shù)的梯度。計算該梯度的最常用方法,就是反向傳播算法。反向傳播算法其實際原理類似于復(fù)合函數(shù)導(dǎo)數(shù)。我們通過鏈式法則,可以將所需求的梯度分割成子變量的梯度的乘積。
 以單個神經(jīng)元的神經(jīng)網(wǎng)絡(luò)的優(yōu)化為例:
 yetoile=f(∑i=1nwixi+b)y_{etoile} = f(\sum_{i=1}^nw_ix_i + b)yetoile?=f(∑i=1n?wi?xi?+b)
ei=wixie_i = w_ix_iei?=wi?xi?,
v=∑iei+θv=\sum_ie_i+ \thetav=∑i?ei?+θ
默認使用sigmoid激勵函數(shù):
yetoile=σ(v)y_{etoile} = \sigma(v)\space\spaceyetoile?=σ(v)?? 經(jīng)過激勵函數(shù)后的輸出
σ(v)=11+e?v\sigma(v) = \frac{1}{1+e^{-v}}\space\spaceσ(v)=1+e?v1??? sigmoid函數(shù)
?=yetoile?y\epsilon = y_{etoile} - y\space\space?=yetoile??y?? yetoiley_{etoile}yetoile?與實際值yyy的誤差
L=?2L = \epsilon^2L=?2
使用鏈式法則我們不難得到 :
 ?L?wi=?L?ei?ei?wiwhere?ei?wi=xi\frac{\partial L}{\partial w_i} = \frac{\partial L}{\partial e_i}\frac{\partial e_i}{\partial w_i} \space\space where \space\frac{\partial e_i}{\partial w_i} = x_i ?wi??L?=?ei??L??wi??ei????where??wi??ei??=xi?
?L?ei=?L?v?v?eiwhere?v?ei=1\frac{\partial L}{\partial e_i} = \frac{\partial L}{\partial v}\frac{\partial v}{\partial e_i} \space\space where \space\frac{\partial v}{\partial e_i} =1 ?ei??L?=?v?L??ei??v???where??ei??v?=1
?L?v=?L?yetoile?yetoile?vwhere?yetoile?v=σ′(v)=e?v(1+e?v)2\frac{\partial L}{\partial v} = \frac{\partial L}{\partial y_{etoile}}\frac{\partial y_{etoile}}{\partial v} \space\space where \space\frac{\partial y_{etoile}}{\partial v} =\sigma'(v) = \frac{e^{-v}}{(1+e^{-v})^2}?v?L?=?yetoile??L??v?yetoile????where??v?yetoile??=σ′(v)=(1+e?v)2e?v?
?L?yetoile=?L?????yetoilewhere???yetoile=1\frac{\partial L}{\partial y_{etoile}} = \frac{\partial L}{\partial \epsilon}\frac{\partial \epsilon}{\partial y_{etoile}} \space\space where \space\frac{\partial \epsilon}{\partial y_{etoile}} =1 ?yetoile??L?=???L??yetoile??????where??yetoile????=1
最后,?L??=2?\frac{\partial L}{\partial \epsilon} = 2\epsilon???L?=2?
通過鏈式法則,我們將復(fù)雜的復(fù)合函數(shù)的梯度拆解為一個個基礎(chǔ)的梯度,他們的乘積就是我們需要的損失函數(shù)Loss Function關(guān)于權(quán)重的梯度:
 ?L∣wi=2(?)σ′(v)xi\nabla L|_{w_i} = 2(\epsilon)\sigma'(v)x_i?L∣wi??=2(?)σ′(v)xi?
首先對于每個訓(xùn)練集中的數(shù)據(jù)XXX,以及對應(yīng)的當前權(quán)重WWW,我們首先通過正向傳播,計算出各個關(guān)鍵值并儲存在內(nèi)存中。
 
 如下所示,通過正向傳播以及各個變量之間的數(shù)值關(guān)系,我們可以很簡單地計算出每次迭代各個變量對應(yīng)的值。
 
 接著就是反向傳播計算梯度的過程了,如下圖所示,例如我們有?L??=2?=?1.37?2=?2.75\frac{\partial L}{\partial \epsilon} = 2\epsilon = -1.37 * 2 = -2.75???L?=2?=?1.37?2=?2.75
 又有
 ???yetoile=1\frac{\partial \epsilon}{\partial y_{etoile}} =1?yetoile????=1
 因此
 ?L?yetoile=?L?????yetoile=?2.75\frac{\partial L}{\partial y_{etoile}} = \frac{\partial L}{\partial \epsilon}\frac{\partial \epsilon}{\partial y_{etoile}} = -2.75 ?yetoile??L?=???L??yetoile????=?2.75
…
 依此類推,我們不難通過鏈式法則,一步一步反向傳播,直到計算出我們最終需求的梯度值: ?L?wi\frac{\partial L}{\partial w_i}?wi??L?
 理解了梯度下降算法在訓(xùn)練神經(jīng)元過程中的應(yīng)用,以及反向傳播算法如何計算出復(fù)合梯度的過程,接下來分享一個Tensorflow模塊中非常好用的計算梯度的類,這大大簡化了我們計算反向傳播的過程。
4. Tensorflow GradientTape
用幾個簡單的例子介紹一下功能強大的GradientTape類,可以幫助我們在深度學(xué)習中簡便地計算函數(shù)的梯度。
import tensorflow as tf with tf.GradientTape(watch_accessed_variables=True) as t:x = tf.Variable(3.0)y = x ** 2# t.watch(x)dy_dx = t.gradient(y,x)print(type(dy_dx))print(dy_dx.numpy())print(dy_dx)上述代碼計算了 y=x2y = x^2y=x2這個函數(shù)在x=x=x=
 輸出結(jié)果如下 :
 
 Tensorflow庫中的GradientTape類使用簡單,其中輸入輸出都推薦定義為張量tensor的形式,即可訓(xùn)練的變量形式。GradientTape類中的watch_accessed_variables參數(shù)決定了類是否會自動觀測保存可訓(xùn)練的變量,當這個參數(shù)值為False時,我們可以使用 t.watch()方法指定類觀察的具體變量。
如下例子,調(diào)用t.gradient()方法時,變量也可以是高維的tensor。
w = tf.Variable(tf.random.normal((3,2)),name='w') b = tf.Variable(tf.zeros(2,dtype=tf.float32),name='b') x = [[1.,2.,3.]]with tf.GradientTape() as tape:y = x @ w + bloss = tf.reduce_mean(y**2)# 可以用張量的形式同時計算多個變量tensor對應(yīng)的梯度[dl_dw, dl_db] = tape.gradient(loss,[w,b])print(dl_dw)print(dl_db)輸出結(jié)果如下:
 
 以我們在上一部分做的反向傳播算法為例 :
輸出結(jié)果如下:
可以看到,我們使用tensorflow計算出的梯度?L?wi\frac{\partial L}{\partial w_i}?wi??L?與使用反向傳播算法的計算結(jié)果是一致的。
 
總結(jié)
以上是生活随笔為你收集整理的一文看懂计算机神经网络与梯度下降的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
                            
                        - 上一篇: 特征点检测 FAST算法及代码详解
 - 下一篇: Anaconda安装tensorflow