1. 程式人生 > >深度學習第五課-訓練注意事項與框架使用

深度學習第五課-訓練注意事項與框架使用

說明:本文是七月演算法5月深度學習班第五次課聽課筆記。黃色標註的部分為自己不太確定的部分。

訓練

mini-batch SGD

神經網路使用mini-batch SGD訓練得到最優權重。訓練過程如下:(以下參考了andrew ng的機器學習課程) 例如訓練樣本量m=3200,mini-batch 每次取32張 for  i = 1,33,65,... 從i 開始取32個圖片樣本 前向計算得到中間變數a  z 和 損失函式值 後向計算得到梯度 用這部分梯度更新權重 問:為什麼使用batch而不使用一張圖片呢? 答:一張圖片樣本量不夠,容易發生振盪。如果是一張圖片,就是隨機梯度下降了。 

兩種去均值方法

第一種:減去圖片每個畫素的均值。在圖片的每個畫素位求均值。例如樣本圖片是[32,32,3],將會得到[32,32,3]陣列的平均值。每個樣本的不同畫素減去對應位置的均值。AlexNet使用該方法。
第二種:減去每個通道(channel)的均值。例如樣本圖片是[32,32,3],會得到3個平均值,分別表示R、G、B的均值。每個樣本不同通道的值減去對應的均值。VGGNet使用該方法。
再次強調:CNN訓練不需要做標準化、PCA和白化

權重初始化

SGD引數學習第一步就是權重初始化。權重初始化有多種方法。
al表示每層神經單元值。W1表示從第一層到第二層的權重
方法1  w=0。不可以。所有權重初始化為0,這會發生對稱現象。例如a2=g(a1*W1)。所有W1=0,a2所有神經單元的值就都相同了。而神經網路的不同神經元是用來學習不同的知識點。這樣就引起了對稱性。不能好好工作了。
方法2 w=0.01*np.random.rand(D,H).  初始化權重為一些小的隨機數。在python實現中,實現了權重正負數各一半。效果:該方法在包含1-2個隱藏層的網路中是有效的。網路層數加深,帶來整個網路啟用傳遞的不對稱性(會引起資料在很小或者特別大的範圍內變動,也就是說方差趨於0,或者無窮)
實現:使用10層網路(500)神經元,觀察 每一層 神經單元的 平均值 和方差。可以看到從第三層開始均值與方差幾乎不發生變化,接近0。
方法3 w=np.random.rand(fan_in,fan_out).
 
說明:fan_in = 這一層輸入元素的個數,fan_out=這一層輸出元素的個數。效果:會出現梯度為0的情況,類似sigmoid函數出現的情況。
方法4 w=np.random.rand(fan_in,fan_out)/np.sqr(fan_in) 效果:效果還不錯可以使用。但是在使用ReLU啟用函式的時候,同樣帶來整個網路啟用傳遞的不對稱性方法5 w=np.random.rand(fan_in,fan_out)/np.sqr(fan_in/2)這是一篇在2015年的論文中提到的方法。可以解決ReLU時發生的問題。

Batch Normalization

        對於權重可能引起網路啟用的不對稱性問題,谷歌提出了一種解決方法Batch Normalization。思想是期望激勵過後的神經元的值仍然能夠保持高斯分佈。
        問:為什麼是高斯分佈呢?         答:高斯分佈簡單,方差可控。而且還滿足了同一層神經元要有一定的差異性。         問題:BN放在什麼問題?         Batch Normalization通常接在全連線之後,激勵層之前。全連線層是產生波動最大可能性的地方,也是學習能力最強的地方。         問題:BN的具體操作         求均值;求方差;xi=(xi-均值)/np.sqr(方差+e);最後一步做伸縮和平移且輸出:yi=gama * xi+beta     。gama和beta是訓練過程中可以獲得的。之所以有最後一步,是因為BN過程中對原始資料做了修改,表達的資訊會有部分丟失。通過伸縮平移儘量將資訊還原。         BN的優點是:學習率設定高一點也可以;對初始化資料依賴少了。

開始訓練

首先先用小資料集訓練(10個分類,每個分類下10個樣本)測試訓練模型是否OK。接著可以改變正則化,從無到有。 需要監控的引數 1const function的值是不是振盪下降;2 訓練集上的準確率是否能到100%。 幾個現象:準確率低(0.6),cost function值不變=>有問題,學習率太大了? 訓練集準確率>>交叉驗證集準確率   =>過擬合,試試調大正則化項? 訓練集準確率 約等於 交叉驗證集準確率   如果都很高,那模型不錯,可以使用。如果都很低(0.6),資料問題?模型問題?樣本傾斜了?

Dropout ---神經網路正則化

        L2 正則化    l = ... + lamda*(權重和)    用於神經網路,引數個數多,計算量大。所以不是最好的選擇。         Dropout 語言描述:1 別一次開啟所有學習單元;別讓神經元記住那麼多東西;每次關掉一部分感知器,得到新的模型,最後融合。         設定一個概率p=允許通過的概率。在dropout層,會有n*(1-p)個節點關閉,神經單元的值為0。注意:不是權重為0。由於訓練的時候有一個概率,在預測的時候同樣需要概率。所以工業上一般是在訓練過程中,將輸入資料x=x*p。預測的時候就不需要再乘以p了。

Caffe使用

主要模組

                Blob 儲存資料和梯度值                 Layer 傳遞層與層的輸入輸出                 Net   網路,利用前向後向計算梯度                 Solver 用梯度更新權重                                                         

使用過程

               網上有很多資料講使用過程,這裡不詳細記錄。                 1 Resize圖片,轉存為LMDB/LevelDB格式。注意分類下表從0開始。                 2 定義網路結構                 3 定義solver,訓練引數                 4 訓練

模型庫選擇  model zoo

               1 如果層次不變,改變輸入輸出                   輸入是 data層 data_param 和transform_param 引數段。輸出是layer {  name: "fc8"  ,name 需要修改。                2 如果新增/刪除層次,注意順序。一般把前面層學習率調低,從修改層開始調高學習率。一般fine-tuning的前期loss下降非常快,中間有個瓶頸期,要有耐心。                3 在solver調整學習率(1/10,1/100)。利用snapshot 儲存中間結果。如果發生宕機,可以接著繼續訓練。