這一回聊一下神經(jīng)網(wǎng)絡(luò)的反向傳導(dǎo)算法問題。反向傳導(dǎo)算法是一個(gè)比較復(fù)雜的算法,但是如果把它拆解開,其實(shí)每一個(gè)小步驟并不復(fù)雜。 在此之前需要先介紹一個(gè)概念,那就是模型訓(xùn)練目標(biāo)。神經(jīng)網(wǎng)絡(luò)是一個(gè)用在監(jiān)督學(xué)習(xí)上的模型,所謂的監(jiān)督學(xué)習(xí)就是我們要提前知道輸入和輸出。那么我們的模型訓(xùn)練目標(biāo)自然是希望模型在接收輸入后,可以得到和我們提前知道的一樣的輸出。 但是怎么描述這個(gè)“一樣”呢?現(xiàn)實(shí)中會(huì)有很多具體的表述方法。這里我們介紹并采用一種相對(duì)簡單的方式,那就是二次損失函數(shù)。對(duì)于模型的輸出y,和我們提前知道的理論輸出t,有: 定義一個(gè)雙層神經(jīng)網(wǎng)絡(luò) 1. 輸入的數(shù)據(jù)是2維 2. 第一層神經(jīng)網(wǎng)絡(luò)的輸入也是2維,輸出是4維,非線性部分采用sigmoid函數(shù) 3. 第二層神經(jīng)網(wǎng)絡(luò)的輸入也是4維,輸出是1維,非線性部分采用sigmoid函數(shù) 下面的時(shí)間請(qǐng)大家想象這個(gè)神經(jīng)網(wǎng)絡(luò)…… 不用想了,畫了個(gè)比較丑的…… 下面的時(shí)間我們來推導(dǎo)神經(jīng)網(wǎng)絡(luò)的優(yōu)化公式。推導(dǎo)公式本身不需要太多的數(shù)學(xué)知識(shí),但是需要一些耐心,我們首先解決一個(gè)數(shù)據(jù)的推導(dǎo),然后擴(kuò)展到一批(batch)數(shù)據(jù)上。 我們的目標(biāo)函數(shù)是這個(gè)損失函數(shù)Loss,優(yōu)化方法還是之前提到的梯度下降法,那么我們就需要求出每一個(gè)參數(shù)的梯度,也就是: 如果我們能求出上面的17個(gè)梯度,后面我們就可以用負(fù)梯度乘以步長進(jìn)行優(yōu)化迭代了,說實(shí)話,直接求解這些確實(shí)有點(diǎn)難,這時(shí)候微分世界的一大神器就來了,那就是鏈?zhǔn)角髮?dǎo)。我們把數(shù)據(jù)傳遞的過程再詳細(xì)描述一下: 1. 輸入數(shù)據(jù) 2. 第一層的線性部分輸出 3. 第一層的非線性部分輸出 4. 第二層的線性部分輸出 5. 第二層的非線性部分輸出y 6. 二次損失函數(shù)Loss 下面就按照這個(gè)順序分步求導(dǎo),對(duì)于上面的六個(gè)變量和模型的參數(shù),我們根據(jù)每個(gè)分布的公式求出每個(gè)變量最近的輸出的導(dǎo)數(shù): 到這歇一下,我們已經(jīng)順利求出第二層的所有參數(shù)的導(dǎo)數(shù)了,具體的求導(dǎo)過程在這就不說了。下面是第一層 看著十分復(fù)雜是吧?可是實(shí)際上其中每一個(gè)部分都已經(jīng)被我們計(jì)算了,我們只需要把數(shù)據(jù)全部代入就可以了。當(dāng)然,實(shí)際上如果嚴(yán)格按照公式進(jìn)行計(jì)算,梯度的公式會(huì)比這個(gè)更復(fù)雜,但是其中一部分梯度實(shí)際上等于0,所以在此略去。 而且,隨著我們從高層網(wǎng)絡(luò)向低層計(jì)算的過程中,很多中間結(jié)果可以用于計(jì)算高層參數(shù)的梯度了。所以經(jīng)過整理,全部的計(jì)算過程可以如下表示: 以上就是計(jì)算的全過程了,經(jīng)過了這個(gè)過程,我們確實(shí)做到了導(dǎo)數(shù)的求解,雖然有些繁瑣,但是是不是看上去沒那么復(fù)雜了? 上面的8個(gè)步驟我們呢可以分成2部分:1-4步實(shí)際上完成了第2層神經(jīng)網(wǎng)絡(luò)的梯度計(jì)算,5-8步實(shí)際上完成了第1層神經(jīng)網(wǎng)絡(luò)的梯度計(jì)算。抽象地分析,可以得出: 1. Loss對(duì)本層非線性部分的梯度 2. Loss對(duì)本層線性部分的梯度 3. Loss對(duì)本層線性部分w的梯度 4. Loss對(duì)本層線性部分b的梯度 如果每一個(gè)高層把下面一層的輸出梯度計(jì)算好傳遞過去,那么我們就可以把每一層抽象出來,各自完成各自的計(jì)算即可,層與層之間的計(jì)算可以做到"完全獨(dú)立",雖然它們是連在一起的。 解決了上面的問題,我們還不能馬上寫出代碼,因?yàn)橛?xùn)練過程中真正的代碼比上面的內(nèi)容還要復(fù)雜一些。下一回我們來看看全連接層代碼該怎么寫。
|