對(duì)于許多機(jī)器學(xué)習(xí)算法來說,最終要解決的問題往往是最小化一個(gè)函數(shù),我們通常稱這個(gè)函數(shù)叫損失函數(shù)。在神經(jīng)網(wǎng)絡(luò)里面同樣如此,損失函數(shù)層(CostLayer)和Optimizers因而應(yīng)運(yùn)而生(……),其中:
CostLayer 用于得到損失
Optimizers 用于最小化這個(gè)損失
需要一提的是,在神經(jīng)網(wǎng)絡(luò)里面,可以這樣來理解損失:它是輸入 x 經(jīng)過前傳算法后得到的輸出和真實(shí)標(biāo)簽y 之間的差距。如何定義這個(gè)差距以及如何縮小這個(gè)差距會(huì)牽扯到相當(dāng)多的數(shù)學(xué)知識(shí),我們這里就只講實(shí)現(xiàn),數(shù)學(xué)層面的內(nèi)容(有時(shí)間的話)(也就是說基本沒可能)(喂)會(huì)在數(shù)學(xué)系列里面說明。感謝萬能的 tensorflow,它貼心地幫我們定義好了損失函數(shù)和 Optimizers,所以我們只要封裝它們就好了
CostLayer
先定義一個(gè)基類:
相當(dāng)于我們把 Layer 的激活函數(shù)“偷換”成了損失函數(shù)。calculate 函數(shù)用于直接計(jì)算損失,它只在復(fù)雜模型中分析模型表現(xiàn)時(shí)用到,可以暫時(shí)不管
再定義實(shí)際應(yīng)用的 CostLayer,我們以應(yīng)用最廣泛的 CrossEntropy 為例:
這里面用的正是 tensorflow 的內(nèi)置函數(shù)
Optimizers
這一部分的封裝做得更加沒有營(yíng)養(yǎng),大部分代碼都僅僅是為了和我自己造的輪子的接口 一致。最關(guān)鍵的部分只有兩行:
其中 self._opt 是 tensorflow 幫我們定義好的 Optimizers 中的一個(gè),它的作用也很簡(jiǎn)單粗暴:更新 session 中的各個(gè)變量以使得損失 x 向最小值邁進(jìn)
以上,CostLayer 和 Optimizers 的定義、功能和實(shí)現(xiàn)就說得差不多了;再加上前幾章,一個(gè)完整的、較樸素的神經(jīng)網(wǎng)絡(luò)就完全做好了,它支持如下功能:
自定義激活函數(shù)
任意堆疊 Layer
通過循環(huán)來堆疊重復(fù)的結(jié)構(gòu)
通過準(zhǔn)確率來評(píng)估模型的好壞
這不算是一個(gè)很好的模型、但已經(jīng)具有了基本的雛形,走到這一步可以算是告一段落。接下來如果要拓展的話,大致流程會(huì)如下:
在訓(xùn)練過程中記錄下當(dāng)前訓(xùn)練的結(jié)果、從而畫出類似這樣的曲線:
讓模型支持比較大規(guī)模數(shù)據(jù)的訓(xùn)練,它包括幾個(gè)需要改進(jìn)的地方:
我們目前沒有把數(shù)據(jù)分割成一個(gè)個(gè)小 batch 來訓(xùn)練我們的模型;但當(dāng)數(shù)據(jù)量大起來的時(shí)候、這種處理是不可或缺的
我們目前做預(yù)測(cè)時(shí)是將整個(gè)數(shù)據(jù)扔給模型讓它做前傳算法的。數(shù)據(jù)量比較大時(shí),這樣做會(huì)引發(fā)內(nèi)存不足的問題,為此我們需要分批前傳并在最后做一個(gè)整合
我們目前沒有進(jìn)行交叉驗(yàn)證,這使我們的模型比較容易過擬合。雖然其實(shí)讓用戶自己去劃分?jǐn)?shù)據(jù)也可以,但留一個(gè)接口是好的習(xí)慣
最后也是最重要的,當(dāng)然就是把我們的模型擴(kuò)展成一個(gè)支持 CNN 模型了。這是一個(gè)巨坑、且容我慢慢來填……
-
神經(jīng)網(wǎng)絡(luò)
+關(guān)注
關(guān)注
42文章
4762瀏覽量
100539
原文標(biāo)題:從零開始學(xué)人工智能(6)--Python · 神經(jīng)網(wǎng)絡(luò)(五)· Cost & Optimizer
文章出處:【微信號(hào):AI_shequ,微信公眾號(hào):人工智能愛好者社區(qū)】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論