感慨一下,人工智能這個名字挺有意思,這段時間也不知咋回事,朋友圈裏都是學人工智能的,什麼python,tf.......還有不少大神在互聯網上開講,也是賺了一筆,現在看來,真是百花齊放,一派繁榮的景象啊,有好有壞,大多數也只是人工的智能,就好像今天要講的訓練和調參,千萬不要覺得隨隨便便就能夠獲得一個好的結果,若是你沒有豐富的經驗、大量的實驗,等於空談。固然你徹底能夠借鑑別人的經驗,甚至是借用別人的成果,可是絕大多數實際的情形,咱們只能是在借鑑的基礎上作本身的工做。這篇博客是我以前寫的,現在放在博客裏,記錄下來,勉勵同志們共同窗習。python
博客中已經省略了公式,圖表引用網上資源,在此表示感謝!網絡
近年來,深度學習做爲機器學習中比較火的一種方法出如今咱們面前,可是和非深度學習的機器學習相比(我將深度學習歸於機器學習的領域內),還存在着幾點很大的不一樣,具體來講,有如下幾點:框架
綜上所述,其實咱們已經認識到了深度學習的本質,其實很簡單,就是數據和模型,二者之間相輔相成,相互促進。認識到了深度學習的本質和與通常意義上的機器學習的區別,你才能明白調參和訓練的技巧和建議對於深度學習而言是多麼的重要,絕不誇張的說,直接影響到咱們剛剛談到的模型的泛化能力,並且是根本緣由。機器學習
從咱們準備數據集到訓練到理想的模型的過程順序,咱們把其分紅以下幾個部分分別敘述。函數
(1) Normalization。能夠這樣認爲,歸一化主要在幹這樣一件事:把數據從一個通常的分佈,變成0均值、單位方差的分佈,爲何這麼幹呢?緣由是這麼作更容易收斂,這種方法在Caffe框架中廣泛使用(mean value或者mean binaryproto 文件)。Batch Normalization(BN)是一個升級版本,做者主要考慮當使用了飽和的激活函數時,例如sigmoid函數變成0均值、單位方差則會出如今該函數中間近似線性的那一段,這是很是糟糕的,中間線性的部分的擬合能力最差,所以下降了模型的表達capacity,因此BN應運而生,實驗代表,其效果sigmoid函數比Relu函數要好。性能
(2) PCA。研究如何以最少的信息丟失將衆多原有的變量信息濃縮到少數幾個維度上,即所謂的主成分。首先計算出協方差矩陣,而後求出協方差矩陣的特徵向量,並用其對原特徵進行線性變換,實現降維。學習
(3) Whitening。去除特徵向量中各個特徵之間的相關性,同時保證每一個特徵的方差一致。 設特徵向量 X = (X1,X2,X3),對於向量 X,能夠計算出相應的協方差矩陣(根據已有數據集來估計)。咱們但願協方差矩陣是一個對角矩陣,由於這意味着 X 的每一個元素之間都是互不關聯的,可是咱們的數據並不具有這樣的性質。爲了解耦數據,咱們須要對原始特徵向量執行一個變換,從而使得變換後的向量 Y 的各個特徵之間相關性爲0。設 Σ 是 X 的協方差矩陣,有:ΣΦ=ΦΛ, 那麼 Λ 中的每一個元素都是協方差矩陣的特徵值,Φ 的每一個列向量是相應的特徵向量。若是對特徵向量作變換:Y = XΦ = X(Φ1,Φ2,Φ3),此時根據向量 Y 計算出來的協方差矩陣是一個對角矩陣。對角矩陣 Λ 的特徵值就是 Y 的每一個元素的方差,能夠所有相同,也可能不相同,若是對變換後的特徵向量的某些維度進行縮放,使得 Λ 的每一個元素都相等,那麼整個過程就是 whitening。大數據
3. Initialization(初始化)。當前兩步完成以後,能夠考慮模型參數的初始化方式了。此處舉出實例,Caffe中的參數初始化方式有7種方法,分別爲:constant、gaussian、positive_unitball、uniform、xavier、msra和bilinear。用的較多的是xavier用在權重初始化上,constant用在偏置初始化上。人工智能
4. Activation Functions(激活函數)。深度學習之因此具備豐富的表達能力,很是關鍵的一點是激活函數,這就至關於一系列疊加在一塊兒的非線性處理單元,能夠想象出這一系列疊加的非線性處理單元原則上能夠逼近任意函數(這指的是從輸入到輸出效果)。幾種經常使用的激活函數:sigmoid、tanh和Relu,可是咱們又介紹過以前普遍使用的sigmoid和tanh等飽和激活函數,使用它們在很深網絡模型中的訓練效果每每很很差,由於存在梯度消失的問題,例以下圖中是一個sigmoid函數的例子,因爲神經網絡在反向傳播時,須要乘以激活函數的一階導數,這樣逐層往前傳,可想0.930=0.042,這就產生了兩個極端,出現了以下圖所示的梯度消失區,一旦梯度都已經很小了,還怎麼學習?咱們在Caffe中經常使用Relu函數有效地避免這一問題。spa
圖1 sigmoid函數
5. During training(訓練過程當中)。在訓練過程當中,要掌握學習率的變化策略,通常而言Caffe定義學習率在超參數配置文件中(solver.prototxt),並選擇了學習速率的衰減策略(學習速率都是開始的時候大,而後以後變小,如何變,怎麼變,咱們將其稱爲策略,因此在論文中通常都會談到這一問題),更爲重要的是,能夠在網絡層定義中指定lr_mult選擇某一層的學習率,該技巧也可爲以後的調參作準備。另一點很是重要的是fine-tune,微調的用處一般狀況下就是你選擇了一個較爲深的model,也就是較爲複雜的model,你並不須要把全部的layers都從新訓練,而只是訓練了其中的some layers,此時咱們徹底能夠站在巨人的肩膀上(利用預訓練模型的weights初始化),能夠省去不少工做,更爲重要的是,加上合適的調參還會提升模型的泛化能力(由於預訓練的模型每每還未收斂)。具體來講,存在如下幾種情形:
|
很是類似的數據集 |
很是不一樣的數據集 |
很是少的數據 |
在頂層調一層線性分類器 |
嘗試在不一樣的層訓練線性分類器 |
很是多的數據 |
可微調一些層 |
微調更多的層 |
注意微調的時候,在Caffe中操做須要改變微調的那些層的名字(同時根據本身的須要改變layer參數,例如圖片的通道、全鏈接層輸出的類別數目等)。
6. Regularizations(正則化)。正則化也稱爲Weight-decay(限制權值)。正則化應該講是一種避免over-fitting的有效方法,這裏咱們插入一段對over-fitting的分析,就個人認識而言,從事機器學習的工程師們常常會遇到不少問題,不少bug,可是能夠這樣說over-fitting是全部工程師都必須面對的一個問題,其具備很強的通用性,這是因爲方法自己所決定的。既然你們都會遇到這個問題,又該如何解決呢?回頭看,咱們說過深度學習的本質就是數據和模型,那解決過擬合的根本途徑也必須從這兩個方向出發,那什麼是過擬合呢?形象一點說就是你認爲你的model在訓練集上已經表現很好了,但是當你把它使用在驗證集上的時候,效果則不好,進一步說就是數據集太少或者模型太複雜,二者顯然不匹配。如今咱們開始從這兩個方向分析,解決方法兩個:增長數據集和減少模型的複雜度(限制網絡的capacity)。此處正則化就是從減少模型的複雜度出發的一項技術,其本質就是控制模型學習的特徵數目,使其最小化,從而防止在訓練過程當中引入訓練集的抽樣偏差,正則化包括L2正則化和L1正則化。
7. Dropout。Dropout是指在深度學習網絡的訓練過程當中,對於神經網絡單元,按照必定的機率將其暫時從網絡中丟棄,以下圖所示。對於隨機梯度降低來講,因爲是隨機丟棄,所以每個mini-batch都在訓練不一樣的網絡(對於一個有N個節點的神經網絡,採用dropout後,能夠認爲其是2n個模型的集合),同時每一個網絡只見過一個訓練數據(每次都是隨機的新網絡),從而將這些多個模型組合起來,以每一個模型的平均輸出做爲結果,caffe中也定義了Dropout層。
圖2 Dropout示例
8. Insights from Figures。若是說經過上面的方法,你都作了,仍是存在問題,那就須要仔細的檢查了,檢查的方法有不少,其中最爲形象生動的,也就是這裏要說的就是畫圖,從圖中進行推斷。咱們知道Caffe也給咱們提供了不少畫圖的tools(稱其爲可視化),這對寫論文、科研分析仍是挺好的。言歸正傳,下面從網上找到幾張圖片,這些圖片均可以從log中經過tools畫出,讓咱們來看一看。
圖3表示的是不一樣學習率下的loss變化曲線,很明顯圖中的四條曲線隨着迭代次數的增長表現出不一樣的性能,黃色的曲線隨着迭代次數的增長,loss先減小然後劇烈增長,每每引起loss等於Nan,這是因爲選擇的學習率太大的緣故(ps:本人親測,有幾回我在修改一些模型時,開始的loss就很大,而後選擇了較大的學習率,一會兒就Nan了);藍色的曲線隨着迭代次數的增長,loss的減小速率很慢很慢,並且設置的最大迭代次數已經很大,但網絡並無收斂,這說明選擇的學習率過小了;綠色的曲線隨着迭代次數的增長,loss的很快減小,而且網絡收斂在一個loss較高的地方居高不下,這說明選擇的學習率有點大了,已達到局部最優,可觀察在網絡loss不降時下降學習率;紅色的曲線隨着迭代的次數的增長,loss緩慢降低,曲線相對平滑,最終收斂在loss很低的水平上,說明選擇的學習率較好。固然圖中是理想的曲線,只能說明變化趨勢,實際狀況下曲線是有波動的,有些毛刺感(ps:大量的實踐證實能夠接受的就是局部最優和全局最優了,也就是紅色和綠色曲線表明的過程,固然大多數同志們遇到的都是局部最優,此時咱們考慮在局部最優的基礎上減少學習率繼續訓練,二者的區別就是局部最優會保持在一個較高的loss上,固然怎麼衡量loss高低沒有標準,因此局部最優不表明訓練結果就差,局部最優的結果也能夠媲美全局最優,由於咱們根本不知道全局最優在哪一個地方)。
圖3 學習率與loss的關係曲線
圖4表示的是不一樣迭代次數的loss變化曲線,從圖中能夠看到隨着迭代次數的增長,loss的變化趨勢是減少的,注意圖中標註出的「寬度」,若是曲線的寬度太大了,則說明有可能你選擇的batch過小了,而其實batch的選擇在深度學習中也不是隨便來的,太大了很差,過小了也很差,太大了會有顯存溢出的錯誤,過小了有可能某個label很難被學到,這每每致使模型不收斂,或者出現loss爲Nan等錯誤。這個時候能夠用accum_batch_size來解決因爲硬件不足不能選擇較大batch的問題。
圖4 迭代次數與loss的關係曲線
圖5是模型在訓練集和驗證集上的精度曲線。紅色曲線表示的是模型在訓練集上的分類精度,能夠看到,還不錯,隨着迭代次數增長,分類的精度也在增長,而且有收斂的趨勢;綠色曲線表示的是模型在驗證集上的分類精度,能夠看出,與訓練集的精度相比,差距很大,說明模型over-fitting了,應該運用上面說到過的解決方法解決。若是圖中二者之間沒什麼大的差距並且精度都很低,應該增長模型的capacity,提高性能。
圖5 模型在訓練集和驗證集上的精度曲線