構建神經網絡----「深度學習#2」

數據驅動
神經網絡的特征是可以從數據中學習,即可以由數據自動決定權重參數的值。
人工學習、機器學習、深度學習的區(qū)別:
人工學習:數據——>人想到的算法——>答案
機器學習:數據——>人想到的特征量(SIIFT、HOG等)——>機器學習(SVM、KNN等)——>答案
深度學習:數據——>神經網絡(深度學習)——>答案

訓練數據和測試數據
在機器學習中一般將需要用到的數據分為訓練數據和測試數據,之所以這么分,是為了追求模型的泛化能力。
訓練數據也稱為監(jiān)督數據。泛化能力是指處理未被觀察過的數據(不包含在訓練數據中的數據)的能力。獲得泛化能力是機器學習的最終目標。

損失函數
神經網絡以某個指標為線索尋找最優(yōu)權重參數,這個指標在神經網絡中稱為損失函數。
損失函數表示神經網絡性能的惡劣程度,即指當前的神經網絡對監(jiān)督數據在多大程度上不擬合,在多大程度上不一致。
均方誤差

yk表示神經網絡的輸出,tk表示監(jiān)督數據,k表示數據的維度
python代碼
交叉熵誤差

og表示以e為底數的自然對數(loge)o,yk表示神經網絡的輸出,tk表示正確解標簽
tk中只有正確解標簽的索引為1,其他均為0(one-hot表示)

python代碼
mini-batch學習
機器學習使用訓練數據進行學習,針對訓練數據計算損失函數的值,來找出使該值盡可能小的參數,即計算損失函數時必須將所有的訓練數據作為對象。
上述兩種損失函數的python代碼實現考慮的是針對單個數據的損失函數,要想在神經網絡中實際使用起來,就要求計算所有的訓練數據損失函數的總和。

當數據量較大時,如果以全部數據作為計算損失函數的對象是很耗費時間的,因此在神經網絡的學習中,一般從全部數據中選取一部分,作為全部數據的近似,這種學習方式稱為mini-batch學習。
one-hot表示(指僅正確解標簽為1,其余為0的數據結構)
(支持one-hot表示)交叉熵誤差的python代碼
(非one-hot表示)交叉熵誤差的python代碼

梯度法
在了解梯度法前,需要先了解一下,為什么要設定損失函數?
在神經網絡的學習時,不能將識別精度作為指標。因為如果以識別精度作為指標時,參數的導數在絕大多數地方都會變成0.
階躍函數就想“竹筒敲石”,只在某個瞬間產生變化。而sigmoid函數不僅y的輸出時連續(xù)變化的,曲線的斜率(導數)也是連續(xù)變化的,因此得益于sigmoid函數導數在任何地方都不為0的性質,使得神經網絡的學習得以正常進行。

在高等數學課上我們知道,導數就是某個瞬間的變化量。

數值微分的python代碼:
由于計算機缺陷導數無法真正意義上被計算,因此上述代碼中引入的微小值h變量取值0.0001,避免過小導致的舍入誤差,然后通過中心差分法繼續(xù)減小誤差,這一過程的代碼改進過程在《深度學習入門基于Python的理論與實現 齋藤康毅》書中p95-96有詳細介紹。
單變量的導數和多變量的偏導數,都是求某個地方的斜率,不過偏導數需要將多個變量中的其中一個定位目標變量,將其他變量固定為某個值,定義新的函數,對新定義的函數應用數值微分的函數得到偏導數。
對于一個多變量的函數,若想計算所有變量的偏導數,一般這種由全部變量的偏導數匯總而成的向量稱為梯度。
梯度的python代碼:
梯度有一個重要的性質,那就是梯度會指向各點處的函數值降低的方向。梯度指示的方向時各點處的函數值減少最多的方向。
在高等數學中,方向導數=cos(?) * 梯度(?是方向導數的方向與梯度方向的夾角)。因此,所有的下降方向中,梯度方向下降最多。
機器學習的主要任務是在學習中尋找最優(yōu)參數,神經網絡也必須在學習時找到最優(yōu)參數(權重和偏置)。最優(yōu)參數即損失函數取最小值時的參數。
一般而言,損失函數很復雜,參數空間相當龐大,我們不知道它在何處能取得最小值。而通過巧妙地使用梯度來尋找函數最小值(或者盡可能小的值)的方法就是梯度法。
當函數很復雜且呈扁平狀時,學習可能會進入一個(幾乎)平坦的地區(qū),陷入被稱為“學習高原”的無法前進的停滯期。
在梯度法中,函數的取值從當前位置沿著梯度方向前進一定距離,然后在新的地方重新求梯度,再沿著新梯度方向前進,如此反復,不斷地沿梯度方向前進。即通過不斷地沿著梯度方向前進,逐漸減小函數值的過程。

Π表示更新量,在神經網絡的學習中,被稱為學習率。學習率決定在一次學習中,應該學習多少,以及在多大程度上更新參數。

梯度下降法的python代碼:
學習率過大或者過小都無法得到好的結果。
像學習率這樣的參數一般稱為超參數。這是一種和神經網絡的參數(權重和偏置)性質不同的參數。相對于神經網絡的權重參數是通過訓練數據和學習算法自動獲得的,學習率這樣的超參數則是人工設定的。
一般的,神經網絡數據量龐大,我們一般使用隨機選擇的mini-batch數據進行梯度下降,所有該算法又稱隨機梯度下降法(SGD)。
SGD完整代碼:

神經網絡的學習順序
前提
神經網絡存在合適的權重和偏置,調整權重和偏置以便擬合訓練數據的過程稱為學習。
步驟1(mini-batch)
從訓練數據中隨機選出部分數據,這部分數據稱為mini-batch。我們的目標是減小mini-batch的損失函數的值。
步驟2(計算梯度)
為了減小mini-batch的損失函數的值,需要求出各個權重參數的梯度。梯度表示損失函數的值減小最多的方向。
步驟3(更新參數)
將權重參數沿梯度方向進行微小更新。
步驟4(重復)
重復步驟1、步驟2、步驟3。
2層神經網絡的實現
下面,來實現一個手寫數字識別的神經網絡,以2層神經網絡為對象(隱藏層為1層的網絡),使用MNIST數據集進行學習。
代碼的實現參考斯坦福大學CS231n課程提供的python源代碼
完整代碼:


mini-batch的改造和對測試數據的評價
通過上述2層神經網絡TwoLayerNet為對象,使用MNIST數據集,從訓練數據隨機選擇一部分數據使用梯度法更新參數,即mini-batch學習。
此外,神經網絡的學習中,必須確認是否能夠正確識別訓練數據以外的其他數據,即確認是否會發(fā)生過擬合。神經網絡學習的最初目標是掌握泛化能力,因此要評價神經網絡的泛化能力,就必須使用不包含在訓練數據中的數據。
對于mini-batch的學習,一般做法是事先將所有訓練數據隨機打亂,然后按指定的批次大小,按序生成mini-batch。這樣每個mini-batch均有一個索引號,比如比例可以是0,1,2,…,99,然后用索引號可以遍歷所有的mini-batch。遍歷一次所有數據,就稱為一個epoch。?一個epoch表示學習中所有訓練數據均被使用過一次時的更新次數。
過擬合是指,對于手寫數字識別,雖然訓練數據中的數字圖像能被正確辨別,但是不在訓練數據中的數字圖像卻無法被識別的現象。

