第十一章 實踐方法論 (開篇引言)

2017-06-09

Practical Methodology

https://www.youtube.com/live/gjca8HvfyLM?si=k5Iz-aT6AyLHCuP8

重點摘要: 要成功地使用深度學習技術,僅僅知道有哪些算法和解釋它們為何有效的原因是不夠的。一個優秀的機器學習實踐者還需要知道如何針對具體應用挑選一個合適的算法以及如何監控,並根據反饋改進機器學習系統。在機器學習系統的日常開發中,實踐者需要決定是否收集更多數據、增加或減少模型容量、添加或刪除正則化項、改進模型的優化、改進模型的近似推斷或調試模型的軟件實現。這些操作都需要大量時間,因此確定正確做法至關重要。 本章的大部分內容都是關於不同的機器學習模型、訓練算法和目標函數。這可能給人一種印象——成為機器學習專家的最重要因素是了解各種各樣的機器學習技術,並熟悉各種不同的數學。在實踐中,正確使用一個普通算法通常比草率地使用一個不清楚的算法效果更好。正確應用一個算法需要掌握一些相當簡單的方法論。本章的許多建議都來自 Ng (2015)。 建議參考以下幾個實踐設計流程:

Q: 除了了解算法和數學原理,一個優秀的機器學習實踐者還需要具備哪些能力?

A: 一個優秀的機器學習實踐者還需要知道如何:

  1. 針對具體的應用挑選一個合適的算法。
  2. 監控機器學習系統的性能。
  3. 根據反饋和觀察結果來改進機器學習系統。
  4. 有效地決定開發過程中的下一步行動,例如是否收集更多數據、調整模型容量、修改正則化、優化算法等。

Q: 本章提出的實踐設計流程包含哪些主要步驟?

A: 主要步驟包括:

  1. 確定目標: 明確任務的誤差度量和目標性能值。
  2. 建立端到端工作流程: 盡快搭建一個可以運行的完整系統,包括性能評估。
  3. 性能分析與瓶頸定位: 監控系統性能,找出表現不佳的部分,並分析原因(如過擬合、欠擬合、數據或軟件問題)。
  4. 迭代改進: 根據觀察結果,進行增量式的改進,例如收集新數據、調整超參數或改進算法。

Q: 為什麼說「正確使用一個普通算法通常比草率地使用一個不清楚的算法效果更好」?

A: 這句話強調了實踐方法論的重要性。即使一個算法在理論上非常先進或複雜,如果不能正確地應用、調試和評估它,其效果可能還不如一個更簡單但被正確理解和使用的算法。良好的實踐方法論有助於系統性地發現問題、優化性能,並確保算法在其預期的方式下工作。


11.1 性能度量

重點摘要: 確定目標,即使用什麼誤差度量,是必要的第一步,因為誤差度量將指導接下來的所有工作。同時我們也應該了解大概能得到什麼級別的目標性能。 值得注意的是對於大多數應用而言,不可能實現絕對零誤差。即使你有無限的訓練數據,並且恢復了真正的概率分布,泛化誤差仍定義了僅能達到的最小錯誤率。這是因為輸入特征可能無法包含輸出變量的完整信息,或是因為系統可能本質上是隨機的。 訓練數據的數量會因為各種原因受到限制。當目標是打造現實世界中最好的產品或服務時,我們通常需要收集更多的數據,但必須確定進一步減少誤差的價值,並與收集更多數據的成本做權衡。 除了一開始設定的性能度量之外,另一個需要考慮的是度量的選擇。不同的應用可能需要不同類型的性能度量。例如,對於不平衡類別問題,準確率可能不是最佳指標。有時,一種錯誤可能會比另一種錯誤更嚴重。 例如,在垃圾郵件檢測中,將正常郵件錯誤地標記為垃圾郵件(假陽性)的代價通常遠高於將垃圾郵件錯誤地標記為正常郵件(假陰性)的代價。因此,查準率 (precision) 和召回率 (recall),以及它們的組合 F-score (公式 11.1),可能是比準確率更合適的度量。覆蓋率 (coverage) 也是一個重要的指標,尤其是在系統需要人工介入時。

Q: 為什麼在開始一個機器學習項目時,確定性能度量是必要的第一步?

A: 因為性能度量(或誤差度量)將指導整個項目的開發和優化方向。它定義了「成功」的標準,並幫助我們客觀地評估不同模型、算法或超參數設置的好壞。沒有明確的性能度量,就很難判斷模型的改進方向以及何時達到了可接受的性能水平。

Q: 為什麼說在大多數實際應用中,不可能實現絕對零誤差?

A: 主要原因有:

  1. 數據本身的局限性: 輸入特征可能沒有包含預測輸出變量所需的全部信息(即存在潛在的不可約誤差,也稱為貝葉斯誤差)。
  2. 系統的隨機性: 某些系統本質上就帶有隨機性,即使模型完美,也無法完全消除誤差。
  3. 數據採集的限制: 訓練數據的數量和質量總是有限的,可能無法完全代表真實的數據分布。
  4. 模型的局限性: 任何模型都是對現實的簡化,可能無法完美捕捉所有複雜的模式。

Q: 在評估分類器性能時,除了準確率 (accuracy),還有哪些常用的性能度量?它們各自關注什麼方面?

A: 除了準確率,常用的性能度量還包括:

  1. 查準率 (Precision): 在所有被模型預測為正例的樣本中,真正是正例的比例。關注的是模型預測為正例的結果有多「準確」。 Precision = TP / (TP + FP) (TP: 真陽性, FP: 假陽性)
  2. 召回率 (Recall) / 查全率 / 敏感度 (Sensitivity): 在所有真實為正例的樣本中,被模型成功預測為正例的比例。關注的是模型能「找出」多少真實的正例。 Recall = TP / (TP + FN) (FN: 假陰性)
  3. F-score (通常是 F1-score): 查準率和召回率的調和平均數,用於綜合評價模型的性能,特別是在類別不平衡或對查準率和召回率都有要求的情況下。 F1 = 2 * (Precision * Recall) / (Precision + Recall) (公式 11.1)
  4. PR 曲線 (Precision-Recall Curve): 以查準率為縱軸,召回率為橫軸繪製的曲線,用於展示在不同分類閾值下查準率和召回率的變化關係。曲線下面積 (AUC-PR) 也是一個重要的匯總指標。
  5. ROC 曲線 (Receiver Operating Characteristic Curve): 以真正例率 (TPR,即召回率) 為縱軸,假正例率 (FPR) 為橫軸繪製的曲線。曲線下面積 (AUC-ROC) 也是一個常用的分類器性能度量。

Q: 什麼是「覆蓋率 (coverage)」?在什麼情況下它是一個重要的性能度量?

A: 「覆蓋率」通常指的是系統能夠自動處理(即給出一個高置信度的預測)的樣本比例。對於那些系統無法高置信度處理的樣本,可能需要人工介入。 在以下情況下,覆蓋率是一個重要的性能度量: * 當人工干預成本很高時: 如果系統的覆蓋率低,意味著大量樣本需要人工處理,會增加成本。 * 當錯誤的自動化決策後果嚴重時: 在這種情況下,寧願系統對某些情況表示「不知道」(低置信度,不覆蓋),交由人工判斷,也不願做出錯誤的自動化決策。 * 衡量系統的適用範圍: 覆蓋率可以反映系統在多大程度上能夠獨立有效地解決問題。


11.2 默認的基准模型

重點摘要: 確定性能度量和目標後,任何實際應用的下一步是盡快建立一個合理的端到端系統的基線。本節提供了一些關於在不同情況下使用哪種算法作為第一基准方法的推薦。

Q: 在開始一個新的機器學習項目時,建立一個「默認的基准模型」有什麼好處?

A: 建立一個默認的基准模型的好處包括:

  1. 快速驗證端到端流程: 可以快速搭建一個完整的工作流程,從數據加載、預處理、模型訓練、評估到結果分析,確保整個系統是可運行的。
  2. 提供性能下限: 基准模型的性能可以作為一個參考點,後續更複雜的模型需要超越這個性能才算有實質性的改進。
  3. 幫助理解問題的難度: 如果一個簡單的基准模型就能達到不錯的性能,可能說明問題本身相對簡單,或者數據質量較好。反之,則可能意味著問題更具挑戰性。
  4. 指導後續模型選擇和優化方向: 通過分析基准模型的不足之處,可以為後續選擇更複雜的模型或改進方向提供線索。

Q: 針對不同類型的輸入數據和任務,有哪些推薦的默認基准模型?

A:

Q: 在訓練深度學習模型時,常用的默認優化算法、激活函數和正則化方法是什麼?

A:


11.3 決定是否收集更多數據

重點摘要: 在建立第一個端到端系統的基線後,就可以度量算法性能並決定如何改進算法。一個常見的問題是判斷是否需要收集更多數據。

Q: 在什麼情況下,收集更多訓練數據通常是一個好的策略來提升模型性能?

A: 收集更多訓練數據通常在以下情況下是好的策略:

  1. 模型過擬合 (Overfitting): 當模型在訓練集上表現很好,但在未見過的測試集(或驗證集)上表現明顯較差時,表明模型學習了訓練數據中的噪聲或特定細節,而不是泛化的模式。增加更多多樣化的訓練數據可以幫助模型學習更魯棒的特征,減少過擬合。
  2. 學習曲線顯示潛力: 如果繪製的學習曲線(性能 vs. 訓練數據量)顯示,隨著數據量的增加,驗證集(或測試集)的性能仍在持續提升,並且與訓練集性能之間的差距在縮小,那麼進一步增加數據量很可能會帶來性能的提升。
  3. 數據本身信息量不足: 如果現有的訓練數據量相對於問題的複雜性或輸入特征的維度來說太少,模型可能無法學到足夠的模式。

Q: 在什麼情況下,僅僅收集更多數據可能無法解決模型性能不佳的問題?

A: 僅僅收集更多數據可能無法解決問題的情況包括:

  1. 模型欠擬合 (Underfitting): 如果模型在訓練集上的性能就已經很差,表明模型的容量(表達能力)不足以捕捉數據中的基本模式。此時,需要改進模型架構(例如,增加層數、增加隱藏單元數量)或使用更強大的特征,而不是簡單地增加數據。
  2. 數據質量差或標籤錯誤: 如果現有數據中存在大量噪聲、錯誤標籤或系統性偏差,那麼增加更多類似質量的數據可能幫助不大,甚至可能加劇問題。此時,清理數據或改進標註質量可能更重要。
  3. 算法或優化問題: 如果模型的優化過程存在問題(例如,學習率設置不當、陷入差的局部最優),或者選擇的算法本身不適合該問題,那麼增加數據也無法解決根本問題。
  4. 特征不足: 如果輸入特征本身沒有包含足夠的預測信息,無論多少數據,模型都無法學到好的預測。

Q: 什麼是學習曲線 (learning curve)?它如何幫助我們判斷是否需要收集更多數據?

A: 學習曲線是描繪模型性能(例如,準確率、損失函數值)隨訓練數據量(或訓練迭代次數)變化而變化的圖表。通常會同時繪製模型在訓練集上的性能曲線和在獨立的驗證集(或測試集)上的性能曲線。 學習曲線可以幫助判斷是否需要收集更多數據: * 高偏差 (High Bias) / 欠擬合: 如果訓練集性能和驗證集性能都很差,並且隨著數據量的增加兩者都趨於平緩且相差不大,這通常意味著模型欠擬合(容量不足)。此時,增加更多數據可能幫助不大,需要改進模型。 * 高方差 (High Variance) / 過擬合: 如果訓練集性能很好,但驗證集性能較差,並且兩者之間存在較大的差距,這通常意味著模型過擬合。如果隨著數據量的增加,驗證集性能持續提升並且與訓練集性能的差距在縮小,那麼增加更多數據通常是有益的。 * 理想情況: 訓練集性能和驗證集性能都很好,並且兩者比較接近。


11.4 選擇超參數

重點摘要: 大部分深度學習算法都有一組超參數來控制不同方面的算法表現。這些超參數的選擇對模型性能至關重要,但通常沒有直接的、理論指導的選擇方法,需要通過實驗來確定。


11.4.1 手動調整超參數

重點摘要: 手動調整超參數需要理解每個超參數的作用以及它們如何影響模型的學習和泛化能力。

Q: 在手動調整超參數時,哪些超參數通常被認為是最重要的,需要優先調整?

A: 通常,以下超參數被認為是最重要的,需要優先調整:

  1. 學習率 (Learning Rate): 這是幾乎所有基於梯度下降的優化算法中最重要的超參數。它直接影響模型的收斂速度和最終性能。
  2. 模型容量相關的超參數:
    • 對於 MLP:隱藏層的數量和每個隱藏層的單元數量。
    • 對於 CNN:卷積層的數量、每個卷積層的濾波器數量、濾波器大小。
    • 對於 RNN:循環單元類型(LSTM, GRU)、隱藏狀態的維度、層數。
  3. 正則化相關的超參數:
    • 權重衰減係數(L2 正則化)。
    • Dropout 的保留機率(或丟棄機率)。
  4. 批量大小 (Batch Size): 雖然有時也被視為訓練設置的一部分,但它會影響梯度估計的質量和訓練的穩定性。

Q: 為什麼說學習率可能是最重要的超參數?如何有效地調整學習率?

A: 學習率之所以重要,是因為它控制了模型參數在每次迭代中更新的步長。

Q: 表 11.1 總結了一些常見超參數的調整如何影響模型性能,請舉例說明一個超參數及其可能的影響。

A: (參見表 11.1 的內容,這裡舉一個例子)


11.4.2 自動超參數優化算法

重點摘要: 由於手動調整超參數耗時且依賴經驗,自動超參數優化算法應運而生。

Q: 什麼是網格搜索 (grid search)?它有哪些優點和缺點?

A: 網格搜索是一種自動超參數優化的方法。

Q: 什麼是隨機搜索 (random search)?為什麼它通常比網格搜索更有效?

A: 隨機搜索是另一種自動超參數優化的方法。

Q: 什麼是基於模型的超參數優化(例如,貝葉斯優化)?它與網格搜索和隨機搜索有何不同?

A: 基於模型的超參數優化(其中貝葉斯優化是最流行的一類方法)是一種更智能的自動超參數搜索策略。


11.5 調試策略

重點摘要: 當機器學習系統效果不好時,很難判斷效果不好的原因是算法本身,還是實現中的錯誤。調試策略對於診斷和解決這些問題至關重要。

Q: 當一個深度學習模型表現不佳時,有哪些常見的調試策略可以幫助我們找出問題所在?

A: 常見的調試策略包括:

  1. 從簡單開始: 先嘗試在一個非常小的、可控的數據集(甚至只有幾個樣本)上訓練模型,看它是否能夠過擬合這個小數據集。如果不能,通常意味著代碼實現、模型架構或優化設置存在根本性問題。
  2. 可視化:
    • 數據可視化: 檢查輸入數據和標籤是否正確加載和預處理。
    • 激活值可視化: 觀察網路中間層激活值的分布和範圍,可以幫助發現飽和的神經元(例如,sigmoid 或 tanh 單元的輸出接近其邊界值,導致梯度很小)或死亡的 ReLU 單元。
    • 權重和梯度可視化: 觀察權重的大小和分布,以及梯度的大小和流動情況。梯度過大或過小都可能指示問題。
    • 損失曲線可視化: 繪製訓練損失和驗證損失隨迭代次數的變化曲線,觀察其趨勢(是否下降、是否震盪、是否過擬合等)。
  3. 梯度檢查 (Gradient Checking): 使用數值方法(如有限差分)來近似計算梯度,並將其與反向傳播算法計算得到的解析梯度進行比較。如果兩者差異很大,說明反向傳播的實現可能存在錯誤。
  4. 檢查模型實現:
    • 仔細檢查每一層的實現是否正確,特別是維度匹配、激活函數的使用、損失函數的計算等。
    • 使用標準的、經過驗證的庫和組件,而不是從頭實現所有東西(除非有特殊需求)。
  5. 檢查超參數: 不合理的超參數設置(如學習率過大或過小、正則化係數不當)是導致模型表現不佳的常見原因。
  6. 逐步增加複雜性: 從一個已知的、能工作的簡單模型開始,然後逐步引入更複雜的組件或修改,並在每一步都進行測試和驗證。
  7. 比較與已知良好實現的差異: 如果可能,將自己的實現與一個已知的、在類似任務上表現良好的開源實現進行比較。

Q: 什麼是梯度檢查?它是如何工作的?為什麼它對調試反向傳播算法很重要?

A: 梯度檢查是一種驗證反向傳播算法實現是否正確的方法。


11.6 示例:多位數字識別

重點摘要: 本節以街景地址號碼 (Street View House Numbers, SVHN) 數據集的轉錄任務為例,詳細展示了應用上述實踐方法論的過程。

  1. 確定性能度量和目標: 目標是將街景圖像中的數字序列轉錄為正確的數字字符串。性能度量是序列級別的準確率。目標是達到或超過人類水平的準確率(約 98%)。
  2. 建立端到端基線:
    • 最初嘗試了一個包含多個 softmax 輸出(每個對應序列中的一個數字位置)的卷積網路。這個初始模型性能不佳(覆蓋率低,準確率約 90%)。
    • 問題診斷: 發現主要問題是定位數字困難,模型難以判斷序列的長度。
  3. 迭代改進:
    • 改變模型架構: 引入一個額外的 softmax 輸出來預測序列的長度。這改進了性能,但仍然不高。
    • 數據預處理/增強: 考慮了更複雜的數據預處理和增強方法,但決定先不投入過多精力。
    • 增加模型容量: 嘗試增加模型深度和寬度。發現適度增加容量有益,但過度增加則幫助不大。
    • 調整超參數: 手動調整學習率、動量等。
    • 使用更強的正則化: Dropout 被證明非常有效。
    • 改變損失函數: 考慮了不同的損失加權方案。
    • 集成模型 (Ensemble): 訓練多個獨立模型並對其預測進行平均,顯著提升了性能。
    • 預訓練: 考慮了在更大的字符級數據集上進行預訓練。 最終通過一系列的迭代和改進,包括模型架構調整、超參數優化、正則化、集成等,達到了超過 96% 的序列級別準確率。這個案例強調了系統性的實驗、性能監控和迭代改進在實踐中的重要性。

Q: 在 SVHN 數字轉錄任務的案例研究中,最初的基線模型遇到了什麼主要問題?

A: 最初的基線模型(一個帶有多個 softmax 輸出的卷積網路,每個 softmax 對應序列中的一個數字位置)遇到的主要問題是難以準確地定位圖像中的數字序列並確定序列的長度。這導致模型的覆蓋率很低(即很多圖像模型無法給出完整的轉錄),即使在給出轉錄的情況下,序列級別的準確率也不高。

Q: 為了改進 SVHN 任務的性能,案例中提到了哪些迭代改進的策略?請列舉至少三種。

A: 案例中提到的迭代改進策略包括:

  1. 改變模型架構以處理序列長度: 引入了一個額外的 softmax 輸出來明確地預測數字序列的長度,試圖解決定位和長度判斷的困難。
  2. 增加模型容量和調整超參數: 實驗了不同深度和寬度的卷積網路,並手動調整了學習率、動量等超參數。
  3. 使用更強的正則化方法: 發現 Dropout 對於提高模型性能和泛化能力非常有效。
  4. 集成模型 (Ensemble): 訓練多個獨立訓練的相同(或不同)架構的模型,然後將它們的預測結果進行平均或投票,這通常能帶來顯著的性能提升。
  5. (隱含的) 錯誤分析和問題分解: 雖然沒有明確作為一個獨立步驟,但從描述中可以看出,團隊通過分析模型的失敗案例(例如,定位困難)來指導後續的改進方向。

Q: 這個案例研究如何體現了本章前面討論的實踐方法論的重要性?

A: 這個案例研究很好地體現了本章實踐方法論的重要性:

  1. 確定目標和性能度量: 明確了任務是序列轉錄,性能度量是序列級別的準確率,目標是達到人類水平。
  2. 建立端到端基線: 快速搭建了一個初始模型並評估其性能,從而暴露了主要問題。
  3. 性能分析與瓶頸定位: 通過分析基線模型的表現,識別出數字定位和序列長度預測是主要的性能瓶頸。
  4. 迭代改進: 系統性地嘗試了多種改進策略(模型架構、超參數、正則化、集成等),並根據實驗結果不斷調整方向。
  5. (隱含的) 監控和調試: 雖然細節不多,但可以推斷團隊在每次改動後都會評估模型的性能變化,以判斷改動是否有效。 這個案例表明,解決複雜的機器學習問題通常不是一蹴而就的,而是需要一個系統性的、迭代的實驗和優化過程。