(No.36)深度學習實踐經驗匯總

(No.36)深度學習實踐經驗匯總

來自專欄 Gryffindor6 人贊了文章

寫在前面:

本文原載於how-to-start-a-deep-learning-project,並且在機器之心上有翻譯(如何從零開始構建深度學習項目?這裡有一份詳細的教程)。

忽略中英文的標題,因為這並非是一個入門的詳細教程,而是在深度學習應用中各個步驟階段上經驗匯總,寫的很不錯,在這裡推薦一下。

文章具體的應用的是採用生成對抗網路,給日本漫畫上色。雖然領域小眾,但內容上還是有很多通用意義的。下面開始應用經驗的給出:

實踐經驗:

  • 深度學習模型查找 bug 的過程非常艱難。因此要從簡單的地方著手,循序漸進,例如模型的優化(如正則化)始終可以在代碼調試完成後進行。
  • 我們還需要經常可視化預測結果和模型度量標準,並且我們首先需要令模型先跑起來,這樣就有一個可以後退的基線。我們最好不要陷在一個很大的模型,並嘗試將所有的模塊都弄好。
  • 項目研究階段:先對現有產品進行研究,以探索它們的弱點。
  • 站在巨人的肩膀上。閱讀研究論文可能會很痛苦,但非常有意義。
  • 數據的質量要重視起來:類別均衡,數據充足,數據和標記中有高質量信息,數據和標記錯誤非常小,與你的問題相關。
  • 與學術數據集相比,小型項目收集的樣本很少,在適當情況下可以應用遷移學習。
  • 避免隨機改進:首先分析自己模型的弱點,而不是隨意地改進。
  • 建立深度學習並不是簡單的把網路層堆在一起。增加好的限制(constraints)能使得學習更為有效,或者更智能。例如,應用注意機制,能讓網路知道注意哪裡,在變分自編碼器中,我們訓練隱藏因子使其服從正態分布。
  • 許多預訓練模型可用於解決深度學習難題。(這一點深有體會,在NLP上如此,在看到的圖像處理、機器翻譯領域亦是如此。)
  • L1 正則化和 L2 正則化都很常見,但 L2 正則化在深度學習中更受歡迎。L1 正則化可以產生更加稀疏的參數,然而,L2 正則化仍然更受歡迎,因為解可能更穩定。
  • 梯度下降:始終密切監視梯度是否消失或爆炸,梯度下降問題有許多可能的原因,這些原因難以證實。不要跳至學習速率調整或使模型設計改變太快。
  • 縮放輸入特徵。我們通常將特徵縮放為以零為均值在特定範圍內,如 [-1, 1]。特徵的不適當縮放是梯度爆炸或降低的一個最常見的原因。有時我們從訓練數據中計算均值和方差,以使數據更接近正態分布。如果縮放驗證或測試數據,要再次利用訓練數據的均值和方差。(其實還可以通過分布,來check訓練樣本和真實樣本分布diff)
  • 批量歸一化也有助於解決梯度下降問題,因此它逐漸取代了 Dropout。結合 Dropout 和 L2 正則化的好處是領域特定的。通常,我們可以在調優過程中測試 dropout,並收集經驗數據來證明其益處。
  • 激活函數:在 DL 中,ReLU 是最常用的非線性激活函數。如果學習速率太高,則許多節點的激活值可能會處於零值。如果改變學習速率沒有幫助,我們可以嘗試 leaky ReLU 或 PReLU。在 leaky ReLU 中,當 x < 0 時,它不輸出 0,而是具有小的預定義向下斜率(如 0.01 或由超參數設置)。參數 ReLU(PReLU)往前推動一步。每個節點將具有可訓練斜率。
  • 確保樣本在每個數據集和每批訓練樣本中被充分打亂。
  • 用小量的訓練數據使模型過擬合是 debug 深度學習的最好方式。如果在數千次迭代內,損失值不下降,進一步 debgug 代碼。準確率超越瞎猜的概念,你就獲得了第一個里程碑。然後對模型做後續的修改:增加網路層和自定義;開始用完整訓練數據做訓練;通過監控訓練和驗證數據集之間的準確率差別,來增加正則化控制過擬合。
  • 前期的問題主要來自於 bug,而不是模型設計和精調問題。(贊)
  • 把權重全部初始化到 0 是最常見的錯誤,深度網路也學不到任何東西。權重要按照高斯分布做初始化。
  • 檢查和測試損失函數的準確性。模型的損失值一定要比隨機猜測的值低。例如,在 10 類別分類問題中,隨機猜測的的交叉熵損失是-ln(1/10)。
  • 避免使用多個數據損失函數。每個損失函數的權重可能有不同的數量級,也需要一些精力去調整。如果我們只有一個損失函數,就可以只在意學習率了。
  • 數據增強:收集有標籤的數據是一件昂貴的工作。對於圖片來說,我們可以使用數據增強方法如旋轉、隨機剪裁、移位等方式來對已有數據進行修改,生成更多的數據。顏色失真則包括色調、飽和度和曝光偏移。(在NLP領域中應用到少些。
  • Mini-batch 尺寸:通常的批尺寸是 8、16、32 或 64。如果批尺寸太小,則梯度下降不會很順暢,模型學習的速度慢,損失可能會振蕩。如果批尺寸太大,則完成一次訓練迭代(一輪更新)的時間太長,得到的返回結果較小。在我們的項目中,我們降低批尺寸,因為每次訓練迭代時間太長。我們密切監控整個學習速度和損失。如果損失振蕩劇烈,則我們會知道批尺寸降低的幅度太大了。批尺寸影響正則化因子等超參數。一旦我們確定好批尺寸,我們通常就鎖定了值。
  • 學習率和正則化因子高度相關,有時需要一起調。不要太早進行精細調整,有可能浪費時間。設計改變的話這些努力就白費了。
  • Dropout 率通常在 20% 到 50% 之間。我們先從 20% 開始。如果模型出現過擬合,則提高值。
  • 網格搜索的計算量很大。對於較小的項目,它們會被零星使用。我們開始用較少的迭代來調整粗粒度參數。在後期的細調階段,我們會使用更長的迭代,並將數值調至 3(或更低)。
  • kaggle是一個很棒的學習,討論的地方。畢竟紙上得來終覺淺,須知此事要躬行。

推薦閱讀:

TAG:深度學習DeepLearning | 自然語言處理 |