一網打盡!深度學習常見問題!

大數據文摘受權轉載自算法進階

1 前言

在傳統軟件工程中,程序問題(即Bugs)會導致程序崩潰,但開發人員可以通過檢查錯誤來了解原因。

然而,在深度學習中,代碼可能會在沒有明確原因的情況下崩潰。雖然這些問題可以手動調試,但深度學習模型通常會因爲輸出預測不佳而失敗。更糟糕的是,當模型性能較低時,通常沒有任何信號表明模型失敗的原因或時間。

開發過程中我們很經常要花80-90%的時間在數據處理及調試模型,而只花費10-20%的時間推導數學方程和實現功能。

2 爲什麼模型的問題排查困難

• 很難判斷是否有錯誤

• 造成相同性能下降的原因有很多

• 結果可能對超參數和數據集構成的微小變化很敏感

2.1 存在隱藏bugs

在深度學習中,大部分錯誤並不會被輕易察覺到,比如標籤順序錯誤。

2.2 超參數選擇

深度學習模型對超參數的選擇非常敏感。即使是微妙的調整,如學習率和權重的初始化,也會對結果產生顯著的影響。

2.3 數據/模型擬合

我們可以在ImageNet數據集上預訓練模型,然後將其應用到更爲複雜的自動駕駛汽車圖像數據集上進行擬合。

2.4 數據集構造

在此過程中,常見的問題包括:樣本數量不足、處理帶有噪聲的標籤和類別不平衡、以及在構建訓練集和測試集時未能確保數據的分佈一致性。

3深度學習故障排除指南

深度學習(DL)故障排除的關鍵思想:由於很難定位bugs的來源,因此最好從簡單開始,逐漸增加複雜性。

3.1 從簡單開始

架構選擇。深度學習架構選擇可遵循簡單規則:圖像數據,從類似LeNet開始,成熟時考慮ResNet;序列數據,從LSTM開始,問題成熟時轉向注意力模型或WaveNet;其他任務,從全連接神經網絡開始,再根據問題使用更高級網絡。

使用合理的超參數默認值。推薦的網絡/優化器默認值:Adam 優化器使用 3e-4 學習率;ReLU 激活用於全連接和卷積模型以及Tanh 激活用於 LSTM 模型;ReLU 激活函數採用 He 初始化,Tanh 激活函數採用 Glorot 初始化;模型未使用正則化或數據標準化。

歸一化輸入。對輸入數據進行歸一化,減去均值併除以方差;對於圖像,將值縮放爲 [0, 1] 或 [-0.5, 0.5](例如除以 255)。

簡化問題。使用小型訓練集(約10,000個示例),固定對象、類、輸入大小等,構建簡單的綜合訓練集,可以提高模型解決問題的信心和迭代速度。

3.2 運行和調試

五個最常見的DL錯誤:

網絡張量的形狀不正確:可以無聲地失敗。例如,無聲廣播,x.shape = (None,), y.shape =(None, 1), (x+y).shape = (None, None)

錯誤地預處理輸入:例如,忘記進行規範化,或進行過多的預處理;

模型損失函數的輸入不正確:例如,Softmax 輸出用於預期對數的損失;

忘記正確設置網絡的訓練模式:例如,切換訓練/評估模式或控制批次範數依賴;

數值不穩定-inf/NaN:通常源於使用exp、日誌或div操作。

關於實施模型的一般建議:

輕量級實現。第1個版本儘可能少的新代碼行,經驗法則是少於200行,不包括測試基礎組件或TensorFlow/PyTorch代碼;

使用現成的組件。使用Keras等現成組件,避免手動計算,以減少數值不穩定問題;

稍後構建複雜的數據管道。從可以加載到內存中的數據集開始。

運行模型常見問題及原因:

形狀不匹配/轉換問題:在調試器中逐步完成模型創建和推理,檢查張量的形狀和數據類型是否正確。

內存不足問題:逐個縮減內存密集型操作。例如,如果在代碼中的任何位置創建大型矩陣,可以減小其維度的大小或將批量大小減半。

其他問題:標準調試工具包( Stack Overflow + interactive debugger)

過度擬合單批數據常見問題及原因:

誤差上升:可能是由損失函數/梯度中的符號翻轉引起的、學習率過高、softmax使用了錯誤的維度;

誤差爆炸:數值問題,檢查所有的exp、日誌和div操作、學習率過高;

誤差振盪:數據或標籤有誤(例如,歸零或錯誤打亂)、學習率過高;

誤差不動:學習率過低、梯度沒有在整個模型傳播、過分正則化、損失函數的輸入錯誤、數據或者標籤有誤。

與已知結果進行比較(不斷迭代,直到模型執行得達到預期爲止):

• 在相似數據集上評估的官方模型實施;

• 根據基準評估官方模型實施(例如 MNIST);

• 非官方模型實施;

• 論文結果(無代碼);

• 基準數據集(例如 MNIST)上的模型結果;

• 類似數據集上的類似模型的結果;

• 超級簡單的基線(例如,輸出平均值或線性迴歸)。

3.3 評估

偏差-方差分解

測試誤差 = 不可約誤差 + 偏差 + 方差 + 驗證集過擬合

不可約誤差是基線誤差,可通過強有力的基線來估計。可避免偏差是欠擬合的衡量標準,是訓練誤差與不可約誤差之間的差異。方差是過擬合的度量,是驗證錯誤和訓練錯誤之間的差值。驗證集過擬合是測試誤差與驗證錯誤之間的差異。

隨分佈變化的偏差-方差

在實際的ML應用中,訓練、驗證和測試樣本可能來自不同的分佈。爲了解決這個問題,可以創建兩個驗證集,分別來自訓練分佈和測試分佈。通過比較測試驗證錯誤和測試錯誤,可以估計分佈偏移,這對於ML實際應用非常有用。

測試誤差 = 不可約誤差 + 偏差 + 方差 + 分佈偏移 + 驗證集過擬合

3.4改進模型和數據

解決欠擬合問題(即減少偏差):優先級別遞減

使模型更大(即添加層或每層使用更多單元)

減少正則化

誤差分析

選擇不同的(更接近最先進的)模型架構(例如,從 LeNet 遷移到 ResNet)

調整超參數(例如學習率)

添加特徵

解決過擬合問題(即減少差異):優先級別遞減

添加更多訓練數據(如果可能!)

添加歸一化(例如批量歸一化、層歸一化)

添加數據增強

增加正則化(例如,dropout、L2、權重衰減)

誤差分析

選擇不同的(更接近最先進的)模型架構

調整超參數

提前停止(不推薦)

刪除特徵(不推薦)

減小模型尺寸(不推薦)

解決

分析測試-驗證集錯誤並收集更多訓練數據進行補償

分析測試-驗證集錯誤並綜合更多訓練數據進行補償

將領域適應技術應用於訓練

誤差分析示例如下:

領域適配:僅使用未標記數據或有限標記數據來訓練“源”分佈並推廣到另一個“目標”的技術。當對測試分發中的標記數據的訪問受到限制及可以獲得大量相對相似的數據時要考慮領域適配。包括自監督領域適配和無監督領域適配。

重新

如果 (test)-val 看起來明顯比 test 好,則說明驗證集過度擬合

這種情況發生在小驗證集或大量超參數調整時

當它發生時,重新收集驗證集數據

3.5超參數優化

超參數優化面臨如下問題:

網絡:ResNet——多少層?如何參數初始化?卷積核大小?

優化器:Adam——batch size?學習率?beta1,beta 2?

正則化:用哪種正則化方式?

? 首選 模型更敏感的參數; 與選擇的模型相關; 經驗法則; 靈敏度與默認值相關。 有關超參數及其對模型的影響如下:

方法1 手動超參數優化

步驟:瞭解算法(例如,更高的學習率意味着更快、更不穩定的訓練);訓練和評估模型;猜測更好的超參數值並重新評估;可以與其他方法結合使用(例如,手動選擇要優化的參數範圍)。

優點:對於經驗豐富的人,只需要最少的計算就能獲得良好的結果。

缺點:需要對算法有深刻的見解且費時。

方法2 網格搜索

優點:實施起來超級簡單;可以產生好的效果

缺點:效率不高(需要對超參數的所有交叉組合進行訓練);可能需要有關參數的先驗知識才能獲得良好的結果

方法3 隨機搜索

優點:易於實施;通常會產生比網格搜索更好的結果

缺點:不太好解釋;可能需要有關參數的先驗知識才能獲得良好的結果

方法4由粗到細搜索

步驟:定義一個大範圍進行隨機搜索,然後在結果池中找到N個最佳結果,並重復這個過程。

優點:可以縮小性能非常高的超參數範圍;實踐中最常用的方法

缺點:有點手動過程

方法5 貝葉斯超參數優化

步驟:從參數分佈的預先估計開始;維護超參數值與模型性能之間關係的概率模型;交替使用最大化預期改進的超參數值進行訓練並根據訓練結果來更新概率模型。

優點:選擇超參數最有效的hands-of 方式。

缺點:很難從頭開始實施;可能很難與現成的工具集成。

總之,超參數方面應該從粗到細的隨機搜索,隨着項目代碼完備後,再考慮貝葉斯等方法做更細緻的超參數優化。