cs231n-學習筆記-06訓練神經網路
訓練神經網路
小批隨機梯度下降
① 取一批樣本資料
② 通過網路進行前向傳播,得到損失函式
③ 方向傳播計算梯度
④ 使用梯度更新引數
概覽本章內容:
① 初始化設定
啟用函式、資料預處理、權重初始哈、正則化、梯度檢查
② 動態訓練
監控學習率、引數更新、超引數優化
③ 評估
整體模型評估
第一部分
① 啟用函式(使用relu)
② 資料預處理(對資料的每個特徵都進行零中心化,然後將其數值範圍都歸一化到[-1, 1]範圍之內)
③ 權重初始化(使用標準差為的高斯分佈來初始化權重,其中
是輸入的神經元數)④ 批處理(用)
⑤ 監控學習過程
⑥ 超引數優化(隨機樣本引數,)
1 啟用函式
(1)Sigmoid:
(2)tanh: 其中,
(3)relu:
(4)Leaky relu: 為解決relu死亡問題的嘗試
(5)maxout:
(6)elu:
實踐:
(1)首選RELU,關注學習率的變化;
(2)嘗試Leaky relu/maxout/elu;
(3)嘗試tanh,但是不要有太多期望;
(4)不要使用sigmoid函式
2 資料預處理
均值減法:是預處理常用的形式。對資料中每個獨立特徵減去平均值,從幾何上可以理解為,每個維度上都將資料雲的中心遷置原點。
歸一化:將所有的資料都歸一化,使其數值範圍都近似相等。實現歸一化的兩種常用方法:①先對資料做零中心化,然後每個維度都除以其標準差;②對每個維度做歸一化,使得每個維度的最大和最小值是1和-1。(這個操作只有在確信不同的輸入特徵有不同的數值範圍時才有意義)
PCA:先對資料做零中心化處理,然後計算協方差矩陣,它展示了資料中的相關性結構。
協方差矩陣的對角線上是方差,協方差矩陣是對稱和半正定的。
通常使用PCA降維過的資料訓練線性分類器和神經網路會達到非常好的效能結果,同時還節省時間和儲存器空間。
白化:白化操作的輸入時特徵基準上的資料,然後對每個維度除以其特徵值來對數值範圍進行歸一化。該變換的幾何解釋是:如果資料服從多變數的高斯分佈,那麼經過白化後,資料的分佈將會是一個均值為零,且協方差相等的矩陣。
記住:任何預處理策略(比如資料均值)都只能在訓練集上進行計算,演算法訓練完畢後,在應用到驗證集或者測試集上。
3 權重初始化
當權重用0初始化會發生什麼?
全0初始化時一個錯誤的開始。如果網路中的每個神經元都計算出同樣的輸出,然後他們就會在反向傳播中計算出同樣的梯度,從而進行同樣的引數更新。換句話說,如果權重被初始化為同樣的值,神經元之間就失去了不對稱性的源頭。
解決:小的隨機數初始化,0均值和0.01的標準差的高斯分佈
權重初始值要非常接近0又不能等於0,
這種方式對小的網路是可行的,但是對於深層網路會發生問題。
稀疏初始化:所有權重矩陣初始化為0,但每個神經元都同下一層固定數目的神經元隨機連線。
偏置初始化:通常將偏置初始化為0,這是因為隨機小數值權重矩陣已經打破了對稱性。
初始化值太小,啟用函式為0,梯度為0,不更新
初始化值太大,對於tanh,啟用函式飽和,梯度為0,不學習
初始化剛剛好,所有層的啟用函式很好地執行,學習過程非常好
4 批處理
1、為每個維度獨立計算均值和方差;
2、標準化;
批處理通常放在全連線或者卷積層之後,在非線性函式之前。
1、使梯度升高,流向整個網路;
2、允許有更高的學習率;
3、在初始化時,減少依賴性;
4、充當正則化的形式,可能輕微的減少了dropout的需要
注;
在測試階段,批處理層的函式功能完全不同;
均值和標準差不是基於批計算的,相反,在訓練過程中使用單個固定的經驗平均值;
標準化之前,分類損失對權重矩陣的改變非常敏感,很難優化。
標準化之後,權重矩陣的微小的改變對損失值不會產生很大的影響,實現優化非常容易
5 監控學習過程
一 資料預處理
二 選擇網路結構
訓練:以小的正則化項係數開始,並找到使損失函式下降的學習率,損失值不下降的話,是因為學習率太低。NAN代表學習率過高。
梯度檢查
梯度檢查就是把解析梯度很數值計算梯度進行比較。在實踐中,使用中心化公式。
在使用有限差值近似計算數值梯度的時候,我們常見的公式是:
但是,在實踐中,我們通常不這麼使用,是一個很小的數字,近似為1e-5。在實踐中證明,使用中心化公式效果更好: 在進行梯度檢查時,記得關閉隨機失活和梯度擴張6 超引數優化
交叉驗證策略
訓練集和驗證集精確度差距較大,代表過擬合,增加正則化項
訓練集和驗證集精確度差不多,增加模型容量
第二部分
① 優化(Momentum,RMSProp,Adam等)
② 正則化(使用L2正則化和dropout的倒置版本)
③ 轉移學習(專案中使用)
1 優化
我們的梯度來自於小批處理,所以可以有一些噪聲。
SGD+Momentum
AdaGrad: 根據每個維度的歷史平方和新增元素的梯度縮放
AdaGrad的一個缺點就是,在深度學習中單調的學習率被證明通常過於激進且過早停止學習
RMSProp
Adam(使用最多)
實踐中,Adam在大多數案例中是一個不錯的惡魔人選擇,
模型整合:① 訓練多個獨立地模型;②測試階段,平均化他們的結果,
可以提高額外2%的效能。
不要獨立地訓練模型,在訓練過程中,我們使用單個模型的簡單樣式。
2 正則化
正則化可以提高單個模型的效能。
正則化:在損失函式中,額外增加一項
Dropout正則化方法,在每個前向過程中,隨機把一些神經元的權重置為0,通常把這個超引數設定為0.5
正則化,增加資料
在訓練集中的所有畫素應用PCA,
沿著原來的顏色方向,設定一個顏色偏移,
對訓練影象的所有畫素增加顏色偏移,
每層正則化:對於不同層進行不同的正則化很少見(除了輸出層以外)
2 轉移學習
如果你想要訓練或者使用CNN,你將會使用許多資料。
少資料,相似資料集 -> 在最高層使用線性分類器
少資料,不同資料集 -> 這種情況不好處理,嘗試在不同階段使用線性分類器
多資料,相似資料集 -> 調整一些層
多資料,不同資料集 -> 調整層中的大部分資料
模型整合的幾種方法:
(1)同一個模型,不同的初始化。使用交叉驗證來得到最好的引數,然後用最好的引數來訓練不同初始化條件的模型。這種方法的風險在於多樣性只來自於不同的初始化條件。
(2)在交叉驗證集中發現最好的模型。使用交叉驗證來得到最好的超引數,然後取其中最好的幾個模型來進行整合。這樣就提高了整合的多樣性,但是風險在於可能包含不夠理想的模型。在實際操作中,這樣操作起來比較簡單,在交叉驗證後就不需要額外的訓練。
(3)一個模型設定多個記錄點。如果訓練非常耗時,那就在不同的訓練時間對網路留下記錄點,然後用他們來進行模型整合。這樣做多樣性不足,但是在實踐中效果還是不錯的,這種方法的優勢就是代價比較小。
(4)在訓練的時候跑引數的平均值。在訓練過程中,如果損失值相較於前一次權重出現指數下降時,就在記憶體中對網路的權重進行一個備份。這樣就對前幾次迴圈中的網路狀態進行了平均。
模型整合的一個劣勢就是在測試資料的時候會花費更多的時間
3 總結
(1)利用小批量資料對實現進行梯度檢查,還要注意各種錯誤;
(2)進行合理性檢查,確認初始損失值是合理的,在小資料集上能得到100%的準確率
(3)在訓練時,跟蹤損失函式值,訓練集合驗證集準確率,如果願意,還可以跟蹤更新的引數量相對於總引數量的比例(一般在1e-3左右),然後如果是對於卷積神經網路,可以將第一層的權重視覺化
(4)推薦的兩個更新方法是SGD+Nesterov動量方法,或者Adam方法
(5)隨著訓練進行學習率衰減
(6)使用隨機搜尋來搜尋最優的超引數
(7)進行模型整合來獲得額外的效能提高
第三部分
① CPU vs GPU
② 深度學習框架
1 CPU vs GPU
CPU:更少的核,但每個核要快的多,能力更強,善於序列化執行任務;
GPU:更多的核,但每個核比較慢,善於並行任務;
GPU程式設計
CUDA(僅僅NVIDIA)
(1)編寫類C程式碼,直接在GPU上執行;
(2)高階API,cuBLAS,cuFFT,cuDNN等;
OPENCL
(1)和CUDA類似,在CPU和GPU上都能執行;
(2)執行速度相對較慢;
CPU的效能往往沒有得到好的優化。
cuDNN比沒有優化的CUDA快。
若你不夠小心,在讀取資料並轉移到GPU的時候,訓練過程會遇到瓶頸。
解決辦法,① 把所有的資料讀到記憶體,② 使用固態硬碟不使用機械硬碟,③ 使用多個CPU程序預先取到資料。
2 深度學習框架
要點
(1)容易構建大的計算圖;
(2)在計算圖中容易計算梯度;
(3)在包裹了cuDNN,CUBLAS的GPU中高效執行;
計算圖
使用numpy實現的程式,只能夠自己計算梯度,不能夠在GPU上加速。但是Tensorflow和PyTorch可以在GPU上執行
建議
(1)對大多數專案來說,Tensorflow是一個安全的選擇,雖然它有不完美的地方,但是它的社群非常龐大,得到了廣泛的使用,可以和高階的封裝一起使用(Keras,Sonnet);
(2)PyTorch用作研究是非常好的,但是他比較新;
(3)在多個機器上使用Tensorflow計算一個圖;
(4)釋出產品時,考慮Caffe,Caffe2或者Tensorflow;
(5)在移動端使用,考慮Caffe2或者Tensorflow