內容來源:2018 年 05 月 18 日,百度資深研發工程師劉凡平在「百度深度學習公開課·杭州站:AI工程師的快速進階之路」進行的《深度學習模型設計經驗分享》演講分享。IT 大咖說(微信id:itdakashuo)做爲獨家視頻合做方,經主辦方和講者審閱受權發佈。算法
閱讀字數:3633 | 10分鐘閱讀微信
本次演講將從數據準備、模型結構、優化方法、計算性能這四個方面,來探討深度學習模型設計的一些經驗。網絡
以我的經驗來看,通常性的研發流程大體可分爲8步。機器學習
問題分析,肯定需求分佈式
數據分析,肯定現有數據的價值(主要依據特徵及分佈)函數
特徵抽取,根據數據的價值和須要解決的問題,肯定特徵性能
數據準備,在前三步都完成的狀況下,準備訓練集、測試集合、驗證集合學習
模型分析,根據問題的輸入和輸出,肯定選擇的模型測試
參數訓練,不斷迭代模型直至收斂優化
驗證調優,驗證模型的各項指標,使模型達到最佳狀態
應用上線,以離線或在線的方式對外提供服務
整個流程中,模型設計的動機和目標很是重要。其中包括需求與問題的定義、創建問題的數學模型、肯定數據與求解問題之間的關係、探索問題解的可能性、目標的可實現性與可評估性。
對於模型設計首先要有充分的數據,分爲兩個層面。第一是數據特徵,用於肯定可否達成模型設計的目標,特徵應當具有必定的「因果關係」,分佈要有「導向性」。第二數據集應當儘量多,DNN須要大量的數據,並且模型在小的數據集上容易過擬合。建議若是條件容許能夠嘗試擴展原始的數據集合。
數據預處理對不少業內人員來講是個使人頭疼的問題,針對不一樣場景有不一樣的解決方案。
簡單介紹幾種常見的方式。首先是去均值處理,即用原始數據減去所有數據的均值,把輸入數據各個維度的數據都中心化爲0。去均值處理後,特徵雖然明顯了,可是特徵之間的相互比較性還沒有明確,所以要用到歸一化處理,把每一個維度上的數據都除以這個維度上的數據的標準。另外還有一種適使用於圖像處理的方式PCA/Whiteing(白化),圖像中相鄰像素點之間的特徵極爲類似,沒法輕易作到收斂。而PCA能夠去除這些相鄰特徵的相關性,達到快速收斂的目的。
每次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的設計要注重其合理性,簡單直接的體現模型的終極目標,有合理的梯度,可以被求解。另外不要過於關注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,能夠想象更復雜的模型會耗費多少資源。正是基於這種對計算性能的考慮,在選擇模型的時候不必定非要選深度學習的,空間和時間的複雜度對模型也有很大的影響。在模型選擇上,能夠先嚐試線性模型、樹相關的模型,不適合的話再使用傳統機器學習中的經典模型,最後纔是神經網絡模型。
根據咱們的經驗,在單層節點數量大於256個時,不管是全鏈接層或卷積層都建議使用Dropout。
以我的接觸過的開發者來看,不少人並非特別重視分佈式訓練,大部分狀況都是單機運行高性能顯卡,但分佈式的訓練效率可能會更高些,能夠考慮向這方面靠攏。