深度學習模型設計經驗分享

IT大咖說發表於2019-03-03

深度學習模型設計經驗分享

內容來源:2018 年 05 月 18 日,百度資深研發工程師劉凡平在“百度深度學習公開課·杭州站:AI工程師的快速進階之路”進行的《深度學習模型設計經驗分享》演講分享。IT 大咖說(微信id:itdakashuo)作為獨家視訊合作方,經主辦方和講者審閱授權釋出。

閱讀字數:3633 | 10分鐘閱讀

獲取嘉賓演講視訊及PPT:suo.im/5o3jWS

摘要

本次演講將從資料準備、模型結構、優化方法、計算效能這四個方面,來探討深度學習模型設計的一些經驗。

研發流程簡述

以個人經驗來看,一般性的研發流程大致可分為8步。

  1. 問題分析,確定需求

  2. 資料分析,確定現有資料的價值(主要依據特徵及分佈)

  3. 特徵抽取,根據資料的價值和需要解決的問題,確定特徵

  4. 資料準備,在前三步都完成的情況下,準備訓練集、測試集合、驗證集合

  5. 模型分析,根據問題的輸入和輸出,確定選擇的模型

  6. 引數訓練,不斷迭代模型直至收斂

  7. 驗證調優,驗證模型的各項指標,使模型達到最佳狀態

  8. 應用上線,以離線或線上的方式對外提供服務

整個流程中,模型設計的動機和目標非常重要。其中包括需求與問題的定義、建立問題的數學模型、確定資料與求解問題之間的關係、探索問題解的可能性、目標的可實現性與可評估性。

經驗之資料準備

充分的資料

對於模型設計首先要有充分的資料,分為兩個層面。第一是資料特徵,用於確定能否達成模型設計的目標,特徵應當具備一定的“因果關係”,分佈要有“導向性”。第二資料集應當儘可能多,DNN需要大量的資料,而且模型在小的資料集上容易過擬合。建議如果條件允許可以嘗試擴充套件原始的資料集合。

資料預處理

資料預處理對很多業內人員來說是個令人頭疼的問題,針對不同場景有不同的解決方案。

簡單介紹幾種常見的方式。首先是去均值處理,即用原始資料減去全部資料的均值,把輸入資料各個維度的資料都中心化為0。去均值處理後,特徵雖然明顯了,但是特徵之間的相互比較性尚未明確,因此要用到歸一化處理,把每個維度上的資料都除以這個維度上的資料的標準。另外還有一種適使用於影像處理的方式PCA/Whiteing(白化),影像中相鄰畫素點之間的特徵極為相似,無法輕易做到收斂。而PCA可以去除這些相鄰特徵的相關性,達到快速收斂的目的。

資料的shuffle

每次epoch的時候都會有很多的batch,一般情況下這些batch都是相同的,但理想狀態是每次epoch都有不同的batch。因此如果條件允許就應該在每次epoch的時候shuffle(隨機化)一次,以獲取不同的batch。

經驗之模型結構

隱藏層神經元估算

BP神經網路對於單層的感知器網路新增了隱藏層,隱藏層數量的選擇目前還不具備理論支援。

在多層感知器中,確定的是輸入和輸出層中的節點數量,隱藏層節點數量是不確定的,並對神經網路的效能有影響。對此我們可以使用經驗公式來計算

深度學習模型設計經驗分享

h表示隱藏層數量,m是輸入層,n是輸出層,a為取值1~10的範圍值。最後h的結果也在一個範圍值內,一般建議取該範圍中為2的n次方的值。

權重初始化策略

權重合理初始化能夠提升效能並加快訓練速度,對於權重而言,建議統一到一定區間內。

線性模型區間建議為[-v, v],v=1/sqrt(輸入層尺寸),sprt表示開根號。卷積神經網路的區間和公式同樣類似,不過最後的輸入層尺寸要改為卷積核的寬度*卷積核的高度*輸入深度。

有效調整啟用函式

Sigmoid以及Tanh函式的代價非常昂貴,容易飽和從而導致梯度消失,並且可能會停止方向傳播。實際上,網路模型的層級結構越深,就越應避免使用Sigmoid和Tanh函式。可以使用更簡單而且更高效的ReLU和PReLU的啟用函式。

ReLU是非常有用的非線性函式,可以解決很多問題。不過由於ReLU阻礙反向傳播,初始化不好,所以用它微調模型的時候,沒法得到任何微調效果。建議使用PReLU以及一個非常小的乘數(通常為0.1),這樣收斂會更快,而且不會像ReLU那樣在初始化階段被卡住。此外ELU也很好,但成本較高。

實際上ReLU是Maxout的一種特例。Maxout是一個可以學習的啟用函式,主要工作方式是選擇每組中最大的數作為輸出值。如下圖,以兩個元素為一組,5和7,-1和1,最終得到7和1。

深度學習模型設計經驗分享

模型擬合能力驗證

模型過擬合相信很多人都遇到過,也由此引出了很多問題,不過從另一個及角度來看過擬合是有必要存在的——可以用它來做模型的驗證。因為複雜模型下大規模樣本的訓練需要耗費大量的時間,從而導致開發成本上升。

我們可以在使用全量資料集上訓練之前,先在隨機抽樣的子集上進行過擬合驗證,如果過擬合現象發生,則可以推斷網路模型收斂的可能性較高。

注重Loss的設計

Loss的設計要注重其合理性,簡單直接的體現模型的終極目標,有合理的梯度,能夠被求解。另外不要過於關注Accuracy(評測指標),而忽視了訓練過程中Loss的設計。

經驗之優化方法

學習速率優化方法

深度學習模型設計經驗分享

已知調節學習速率也能帶來效果的提升,上圖是不同速率下Loss曲線的情況,很明顯最優的速率應該是讓Loss曲線平滑向前(紅色曲線)。在對學習速率進行調參的時候可以參考這張圖。

卷積核大小優化

幾個小的卷積核疊加在一起,相比一個大的卷積核,與原圖的連通性不變,但卻大大降低了引數的個數以及計算複雜度。因此我們推薦“小而深”的模型,避免“大而短”。小的卷積核還能代替大的卷積核,比如一個5*5的卷積核可以用兩個3*3的卷積核代替,一個7*7的卷積核可以用三個3*3的卷積核代替。

一般優化方法選擇

學習率與訓練步驟、batch大小和優化方法都有耦合關係,常見的優化方案是自適應學習速率(RMSProb、Momentum、Adam等),使用自適應優化演算法,自動更新學習速率。也可以使用SGD手動選擇學習率和動量引數,此時隨著時間的推移學習率會降低。實際使用中,自適應優化傾向於比SGD更快收斂,最終表現通常相對較差。

一般而言,對於高效能訓練較好的做法是從Adam切換到SGD。不過由於訓練的早期階段是SGD對引數調整和初始化非常敏感的時候,因此可以使用Adam進行最初的訓練,這樣不僅節約時間,且不必擔心初始化和引數調整。當Adam執行一段時間後,再切換到SGD加動量優化,以達到最佳效能。

當然對於稀疏資料,建議應儘量使用學習可自適應的優化方法。

效果視覺化

通常卷積神經網路的卷積層的weight視覺化出來會具備smooth的特性。下面兩者圖都是將一個神經網路的第一層卷積層的filter weight視覺化出來的效果。如果出現左邊的這種情況,可能就需要考慮下模型有哪些地方設計的有問題。

深度學習模型設計經驗分享

經驗之計算效能

計算效能分析方法

計算平臺有兩個重要的指標,算力和頻寬。算力表示計算平臺的效能上限,指的是一個計算平臺傾盡全力每秒鐘所能完成的浮點運算數,單位是FLOP/s。頻寬指的是計算平臺傾盡全力每秒鐘所能完成的記憶體交換量,單位是Byte/s。算力除以頻寬可得到計算平臺的強度上限,即單位記憶體交換最多用來進行多少次計算,單位是FLOP/Byte。

模型同樣有兩個重要指標,計算量和訪存量。計算量指的是輸入單個樣本,模型進行一次完整的前向傳播所發生的浮點運算個數,也即模型的時間複雜度,單位是FLOPS。訪問量指的是輸入單個樣本,完成一次前向傳播過程中發生的記憶體交換量,即模型的空間複雜度,資料型別通常為float32。

我們來看一個模型計算效能示例。假設有兩個矩陣A、B,它們均是1000*1000,資料型別為float32,計算C=A*B。則該計算會進行1000*1000*1000的浮點乘、加,約2G FLOPS的計算量。該過程中會讀A、B兩個矩陣,寫C矩陣,至少要訪問三次儲存器,約12MB。

這樣簡單的1000*1000的矩陣就要花費12MB,可以想象更復雜的模型會耗費多少資源。正是基於這種對計算效能的考慮,在選擇模型的時候不一定非要選深度學習的,空間和時間的複雜度對模型也有很大的影響。在模型選擇上,可以先嚐試線性模型、樹相關的模型,不適合的話再使用傳統機器學習中的經典模型,最後才是神經網路模型。

Dropout & 分散式訓練

根據我們的經驗,在單層節點數量大於256個時,無論是全連線層或卷積層都建議使用Dropout。

以個人接觸過的開發者來看,很多人並不是特別重視分散式訓練,大部分情況都是單機執行高效能顯示卡,但分散式的訓練效率可能會更高些,可以考慮向這方面靠攏。

相關文章