神經網路參數選擇(keras,tensorflow)
1.神經網路的超參數分類
神經網路中的超參數主要包括1. 學習率 η,2. 正則化參數 λ,3. 神經網路的層數 L,4. 每一個隱層中神經元的個數 j,5. 學習的回合數Epoch,6. 小批量數據 minibatch 的大小,7. 輸出神經元的編碼方式,8. 代價函數的選擇,9. 權重初始化的方法,10. 神經元激活函數的種類,11.參加訓練模型數據的規模 這十一類超參數。
這些都是可以影響神經網路學習速度和最後分類結果,其中神經網路的學習速度主要根據訓練集上代價函數下降的快慢有關,而最後的分類的結果主要跟在驗證集上的分類正確率有關。因此可以根據該參數主要影響代價函數還是影響分類正確率進行分類。
- 超參數正則化參數 λ,神經網路的層數 L,每一個隱層中神經元的個數 j, 輸出神經元的編碼方式主要影響的時神經網路的分類正確率
- 權重初始化的方法 主要影響代價函數曲線下降速度,同時有時也會影響正確率
- 學習率 η,代價函數的選擇,神經元激活函數的種類主要影響學習速度,這點主要體現在訓練數據代價函數曲線的下降速度上
- 學習的回合數Epoch,小批量數據 minibatch 的大小,參加訓練模型數據的規模主要影響模型分類正確率和訓練用總體時間。
這上面所提到的時某個超參數對於神經網路想到的首要影響,並不代表著該超參數隻影響學習速度或者正確率。
1.1 前提
編程安排
- 將各個參數的設置部分集中在一起。如果參數的設置分布在代碼的各個地方,那麼修改的過程想必會非常痛苦。
- 可以輸出模型的損失函數值以及訓練集和驗證集上的準確率。
- 可以考慮設計一個子程序,可以根據給定的參數,啟動訓練並監控和周期性保存評估結果。再由一個主程序,分配參數以及並行啟動一系列子程序。
畫圖
訓練數據遍歷一輪以後,就輸出一下訓練集和驗證集準確率。同時畫到一張圖上。這樣訓練一段時間以後,如果模型一直沒有收斂,那麼就可以停止訓練,嘗試其他參數了,以節省時間。
如果訓練到最後,訓練集,測試集準確率都很低,那麼說明模型有可能欠擬合。那麼後續調節參數方向,就是增強模型的擬合能力。例如增加網路層數,增加節點數,減少dropout值,減少L2正則值等等。
如果訓練集準確率較高,測試集準確率比較低,那麼模型有可能過擬合,這個時候就需要向提高模型泛化能力的方向,調節參數。2.總體策略
從簡單的開始實驗:MNIST數據集,可以先簡化使用0,1兩類圖,減少百分之八十的數據量,用兩層神經網路[784,10](比[784,32,10])要快上不少。
更快地取得反饋:之前每個epoch來檢測準確率,可以替換為每一千幅圖片後,或者減少validation set的量,比如用100代替10,000
深度學習中經常看到epoch、 iteration和batchsize
- batchsize:批大小。在深度學習中,一般採用SGD訓練,即每次訓練在訓練集中取batchsize個樣本訓練;
- iteration:1個iteration等於使用batchsize個樣本訓練一次;
- epoch:1個epoch等於使用訓練集中的全部樣本訓練一次;
舉個例子,訓練集有1000個樣本,batchsize=10,訓練完整個樣本集需要:100次iteration,1次epoch
2.0 事前準備
方差縮放初始化
這種初始化方法比常規高斯分布初始化、截斷高斯分布初始化及 Xavier 初始化的泛化/縮放性能更好。粗略地說,方差縮放初始化根據每一層輸入或輸出的數量來調整初始隨機權重的方差,從而幫助信號在不需要其他技巧(如梯度裁剪或批歸一化)的情況下在網路中更深入地傳播。Xavier 和方差縮放初始化類似,只不過 Xavier 中每一層的方差幾乎是相同的;但是如果網路的各層之間規模差別很大(常見於卷積神經網路),則這些網路可能並不能很好地處理每一層中相同的方差。
這裡提出知乎一篇很好的文章
論智:可視化超參數作用機制:二、權重初始化
數據預處理
歸一化處理
X /= np.std(X, axis=0)
歸一化處理是指每個維度都通過標準偏差來進行縮放或者確保每個維度最大值和最小值在-1到1之間等等,紅線表示數據的範圍,中間長度不等,右邊長度相等。在圖像處理中,歸一化並不常用。
零中心化處理
x -= np.mean(X, axis=0)
零中心化處理是指減去每個維度的平均值,進而使得數據是以零為中心的。數據集中在原點的周圍。在圖像處理中,零中心化處理是一種常用的數據預處理的方式。
PCA and Whitening(PCA演算法和白化處理)
PCA和白化是數據預處理的另一種方式。在這個過程中,應用PCA演算法將協方差矩陣變成對角矩陣,或者對數據進行白化處理,那意味著在PCA處理後對數據進行壓縮,使協方差矩陣變成單位矩陣,這種預處理方式在機器學習中經常用到。
2.1 學習率的調整
如果學習率太大,可能造成越走越高,跳過局部最低點,學習率太小,學習有可能太慢。對於學習率可以從0.001,0.01,0.1,1,10開始嘗試,如果cost開始增大就停止,實驗更小的微調,因此學習率的調整步驟為:
- 首先,我們選擇在訓練數據上的代價立即開始下降而非震蕩或者增加時的作為 η閾值的估計,不需要太過精確,確定量級即可。
- 如果代價在訓練的前面若干回合開始下降,你就可以逐步增加 η的量級,直到你找到一個的值使得在開始若干回合代價就開始震蕩或者增加;
- 相反,如果代價函數曲線開始震蕩或者增加,那就嘗試減小量級直到你找到代價在開始回合就下降的設定,取閾值的一半就確定了學習速率 。在這裡使用訓練數據的原因是學習速率主要的目的是控制梯度下降的步長,監控訓練代價是最好的檢測步長過大的方法。
對於MNIST,先找到0.1,然後0.5,接著0.25
對於提前停止學習的條件設置,提前停止表示在每個回合的最後,我們都要計算驗證集上的分類準確率,當準確率不再提升,就終止它也就確定了迭代次數(或者稱回合數)。另外,提前停止也能夠幫助我們避免過度擬合。建議在更加深入地理解 網路訓練的方式時,僅僅在初始階段使用 10 回合不提升規則,然後逐步地選擇更久的回合,比如 20 回合不提升就終止,30回合不提升就終止,以此類推。
但是這裡有一個例外,在我們使用Adam梯度下降演算法的時候一般不需要考慮學習率衰減ADAM 天然地就考慮到了這個問題。如果你真的希望達到模型性能的極致,請在訓練結束前的一小段時間內降低學習率;你可能會看到一個突然出現的很小的誤差下降,之後它會再次趨於平緩。
2.2 正則化參數regularization parameter λ
剛開始時代價函數應該不包含正則項,只是先確定 學習率η的值。使用確定出來的 η ,用驗證數據來選擇好的 λ。嘗試從 λ=1開始,然後根據驗證集上的性能按照因子 10 增加或減少其值。一旦找到一個好的量級,你可以改進 λ的值。這裡搞定 λ後,你就可以返回再重新優化 η 。
2.3 小批量數據的大小
選擇最好的小批量數據大小也是一種折衷。
太小了,你不會用上很好的矩陣庫的快速計算
太大,你是不能夠足夠頻繁地更新權重的。你所需要的是選擇一個折衷的值,可以最大化學習的速度。
幸運的是,小批量數據大小的選擇其實是相對獨立的一個超參數(網路整體架構外的參數),所以你不需要優化那些參數來尋找好的小批量數據大小。因此,可以選擇的方式就是使用某些可以接受的值(不需要是最優的)作為其他參數的選擇,然後進行不同小批量數據大小的嘗試,像上面那樣調整 η 。畫出驗證準確率的值隨時間(非回合)變化的圖,選擇哪個得到最快性能的提升的小批量數據大小。得到了小批量數據大小,也就可以對其他的超參數進行優化了。
2.4 梯度下降
在這裡我就直接推薦一篇文章
量子學園:一文看懂各種神經網路優化演算法:從梯度下降到Adam方法
如果想使訓練深層網路模型快速收斂或所構建的神經網路較為複雜,則應該使用Adam或其他自適應學習速率的方法,因為這些方法的實際效果更優。
2.5 激活函數
激活函數的介紹和對比
一文概覽深度學習中的激活函數
ReLU 是最好的非線性(激活函數),它在工作時梯度並不會逐漸減小(從而能夠防止梯度消失)。儘管 sigmoid 是一個常用激活函數,但是它在 DNN 中傳播梯度的效果並不太好。
2.6 過擬合
在深度學習中過擬合是一個十分常見的問題,直接影響了模型的應用效果,通常來說有以下四種方法供大家使用。
2.6.1 正則化
由於模型過擬合極有可能是因為我們的模型過於複雜。因此,我們需要讓我們的模型在訓練的時候,在對損失函數進行最小化的同時,也需要讓對參數添加限制,這個限制也就是正則化懲罰項。
假設我們模型的損失函數為

加入正則項LL後,損失函數為:

L1正則:

其中w代表模型的參數,k代表模型參數的個數。
L2正則:

其中w代表模型的參數,k代表模型參數的個數。
L1正則與L2正則的思想就是不能夠一味的去減小損失函數,你還得考慮到模型的複雜性,通過限制參數的大小,來限制其產生較為簡單的模型,這樣就可以降低產生過擬合的風險。
它們的區別在於L1更容易得到稀疏解。為什麼呢?我們先看看一個直觀的例子:

假設我們模型只有 w1,w2 兩個參數,上圖中左圖中黑色的正方形是L1正則項的等值線,而彩色的圓圈是模型損失的等值線;右圖中黑色圓圈是L2正則項的等值線,彩色圓圈是同樣模型損失的等值線。因為我們引入正則項之後,我們要在模型損失和正則化損失之間折中,因此我們去的點是正則項損失的等值線和模型損失的等值線相交處。通過上圖我們可以觀察到,使用L1正則項時,兩者相交點常在坐標軸上,也就是 w1,w2中常會出現0;而L2正則項與等值線常相交於象限內,也即為 w1,w2非0。因此L1正則項時更容易得到稀疏解的。
而使用L1正則項的另一個好處是:由於L1正則項求解參數時更容易得到稀疏解,也就意味著求出的參數中含有0較多。因此它自動幫你選擇了模型所需要的特徵。L1正則化的學習方式是一種嵌入式特徵學習方式,它選取特徵和模型訓練時一起進行的。
2.6.2 Dropout
Dropout是在深度學習中降低過擬合風險的常見方法,在神經網路進行訓練的時候,讓部分神經元失活,這樣就阻斷了部分神經元之間的協同作用,從而強制要求一個神經元和隨機挑選出的神經元共同進行工作,減輕了部分神經元之間的聯合適應性。
Dropout的具體流程如下:

2.6.3 提前終止
在對模型進行訓練時,我們可以將我們的數據集分為三個部分,訓練集、驗證集、測試集。我們在訓練的過程中,可以每隔一定量的step,使用驗證集對訓練的模型進行預測,模型在驗證集上的誤差在一開始是隨著訓練集的誤差的下降而下降的。當超過一定訓練步數後,模型在訓練集上的誤差雖然還在下降,但是在驗證集上的誤差卻不在下降了。此時我們的模型就過擬合了。因此我們可以觀察我們訓練模型在驗證集上的誤差,一旦當驗證集的誤差不再下降時,我們就可以提前終止我們訓練的模型。
2.6.4 增加樣本量
在實際的項目中,你會發現,上面講述的那些技巧雖然都可以減輕過擬合的風險,但是卻都比不上增加樣本量來的更實在。為什麼增加樣本可以減輕過擬合的風險呢?這個要從過擬合是啥來說。過擬合可以理解為我們的模型對樣本量學習的太好了,把一些樣本的特殊的特徵當做是所有樣本都具有的特徵。舉個簡單的例子,當我們模型去訓練如何判斷一個東西是不是葉子時,我們樣本中葉子如果都是鋸齒狀的話,如果模型產生過擬合了,會認為葉子都是鋸齒狀的,而不是鋸齒狀的就不是葉子了。如果此時我們把不是鋸齒狀的葉子數據增加進來,此時我們的模型就不會再過擬合了。因此其實上述的那些技巧雖然有用,但是在實際項目中,你會發現,其實大多數情況都比不上增加樣本數據來的實在。
2.6.5 Batch Normalization
經驗參數
這裡給出一些參數的經驗值,避免大家調參的時候,毫無頭緒。
- learning rate: 1 0.1 0.01 0.001, 一般從1開始嘗試。很少見learning rate大於10的。學習率一般要隨著訓練進行衰減。衰減係數一般是0.5。 衰減時機,可以是驗證集準確率不再上升時,或固定訓練多少個周期以後。 不過更建議使用自適應梯度的辦法,例如adam,adadelta,rmsprop等,這些一般使用相關論文提供的默認值即可,可以避免再費勁調節學習率。對RNN來說,有個經驗,如果RNN要處理的序列比較長,或者RNN層數比較多,那麼learning rate一般小一些比較好,否則有可能出現結果不收斂,甚至Nan等問題。
- 網路層數: 先從1層開始。
- 每層結點數: 16 32 128,超過1000的情況比較少見。超過1W的從來沒有見過。
- batch size: 128上下開始。batch size值增加,的確能提高訓練速度。但是有可能收斂結果變差。如果顯存大小允許,可以考慮從一個比較大的值開始嘗試。因為batch size太大,一般不會對結果有太大的影響,而batch size太小的話,結果有可能很差。
- clip c(梯度裁剪): 限制最大梯度,其實是value = sqrt(w1^2+w2^2….),如果value超過了閾值,就算一個衰減系係數,讓value的值等於閾值: 5,10,15
- dropout: 0.5
- L2正則:1.0,超過10的很少見。
- 詞向量embedding大小:128,256
- 正負樣本比例: 這個是非常忽視,但是在很多分類問題上,又非常重要的參數。很多人往往習慣使用訓練數據中默認的正負類別比例,當訓練數據非常不平衡的時候,模型很有可能會偏向數目較大的類別,從而影響最終訓練結果。除了嘗試訓練數據默認的正負類別比例之外,建議對數目較小的樣本做過採樣,例如進行複製。提高他們的比例,看看效果如何,這個對多分類問題同樣適用。 在使用mini-batch方法進行訓練的時候,盡量讓一個batch內,各類別的比例平衡,這個在圖像識別等多分類任務上非常重要。
總結
如果網路學習效果很差(指網路在訓練中的損失/準確率不收斂,或者你得不到想要的結果),你可以試試:
過擬合!如果你的網路學習效果不佳,你首先應該做的就是去過擬合一個訓練數據點。準確率基本上應該達到 100% 或 99.99%,或者說誤差接近 0。如果你的神經網路不能對一個數據點達到過擬合,那麼模型架構就可能存在很嚴重的問題,但這種問題可能是十分細微的。如果你可以過擬合一個數據點,但是在更大的集合上訓練時仍然不能收斂,請嘗試下面的幾條建議。
降低學習率。你的網路會學習地更慢,但是它可能會找到一個之前使用較大的步長時沒找到的最小值。(
提高學習率。這將加快訓練速度,有助於加強反饋迴路。這意味著你很快就能大概知道你的網路是否有效。儘管這樣一來網路應該能更快地收斂,但是訓練結果可能不會太好,而且這種「收斂」狀態可能實際上是反覆震蕩的。(使用 ADAM 優化器時,我們認為在許多實驗場景下,~0.001 是比較好的學習率。)
減小(小)批量處理的規模。將批處理大小減小到 1 可以向你提供與權重更新相關的更細粒度的反饋,你應該將該過程在 TensorBoard(或者其他的調試/可視化工具)中展示出來。
刪掉批歸一化層。在將批處理大小減小為 1 時,這樣做會暴露是否有梯度消失和梯度爆炸等問題。我們曾經遇到過一個好幾個星期都沒有收斂的網路,當我們刪除了批歸一化層(BN 層)之後,我們才意識到第二次迭代的輸出都是 NaN。在這裡使用批量歸一化層,相當於在需要止血帶的傷口上貼上了創可貼。批歸一化有它能夠發揮效果的地方,但前提是你確定自己的網路沒有 bug。
加大(小)批量處理的規模。使用一個更大的批處理規模——還覺得不夠的話,如果可以,你不妨使用整個訓練集——能減小梯度更新的方差,使每次迭代變得更加準確。換句話說,權重更新能夠朝著正確的方向發展。但是!它的有效性存在上限,而且還有一些物理內存的限制。我們發現,這條建議通常不如前兩個建議(將批處理規模減小到 1、刪除批歸一化層)有用。
檢查你矩陣的重構「reshape」。大幅度的矩陣重構(比如改變圖像的 X、Y 維度)會破壞空間局部性,使網路更不容易學習,因為這時網路也必須學習重構。(自然特徵變得支離破碎。事實上自然特徵呈現出空間局部性也是卷積神經網路能夠如此有效的原因!)使用多個圖像/通道進行重構時要特別小心;可以使用 numpy.stack() 進行適當的對齊操作。
仔細檢查你的損失函數。如果我們使用的是一個複雜的函數,可以試著把它簡化為 L1 或 L2 這樣的形式。我們發現 L1 對異常值不那麼敏感,當我們遇到帶有雜訊的批或訓練點時,可以進行稍小幅度的調整。
如果可以,仔細檢查你的可視化結果。你的可視化庫(matplotlib、OpenCV 等)是否調整數據值的範圍或是對它們進行裁剪,你可以考慮使用一種視覺上均勻的配色方案。
3. 自動調參
人工一直盯著實驗,畢竟太累。自動調參當前也有不少研究。下面介紹幾種比較實用的辦法:
- Gird Search. 這個是最常見的。具體說,就是每種參數確定好幾個要嘗試的值,然後像一個網格一樣,把所有參數值的組合遍歷一下。優點是實現簡單暴力,如果能全部遍歷的話,結果比較可靠。缺點是太費時間了,特別像神經網路,一般嘗試不了太多的參數組合。
tobe:貝葉斯優化: 一種更好的超參數調優方式
。Random Search比Gird Search更有效。實際操作的時候,一般也是先用Gird Search的方法,得到所有候選參數,然後每次從中隨機選擇進行訓練。
- Bayesian Optimization. 貝葉斯優化,考慮到了不同參數對應的實驗結果值,因此更節省時間。這裡同時推薦兩個實現了貝葉斯調參的Python庫,可以上手即用:
- jaberg/hyperopt, 比較簡單。
- fmfn/BayesianOptimization, 比較複雜,支持並行調參。
作者在編寫這篇文章的時候看到了一系列很不錯的文章,可以結合之前看到過的內容來進行進一步的學習
斯坦福cs231n學習筆記(10)------神經網路訓練細節(訓練過程,超參數優化) - huplion的專欄 - CSDN博客
推薦閱讀:
TAG:參數 | TensorFlow |
