為什麼我的模型沒效?
你有沒有訓練過一個你覺得不錯的模型,但應用到現實世界的數據時卻慘遭失敗?如果是這樣,你並不孤單。機器學習過程非常複雜,很容易在不明顯的情況下做出導致過擬合的事情。
你是否曾經訓練出一個自認為不錯的模型,但在應用於現實世界的數據時卻慘遭失敗?如果是這樣,你並不孤單。機器學習的過程非常複雜,很容易在不經意間做出導致過擬合(overfitting)的行為。在我從事機器學習研究的 20 多年裡,我看過許多這樣的例子,這促使我撰寫了《如何避免機器學習陷阱:學術研究人員指南》,試圖防止其他人掉入這些陷阱。
但你不需要只聽我的一面之詞。科學界和大眾媒體對這些問題的報導也日益增多。例如,觀察到 Covid 疫情期間開發的數百個模型根本無法運作,以及多倫多部署的一個水質監測系統經常 誤導民眾在危險的水域中洗澡是安全的。其中許多案例都記錄在 AIAAIC 數據庫中。甚至有人認為,這些機器學習的失誤正在 引發科學界的再現性危機 —— 鑑於當今許多科學家將機器學習視為關鍵工具,這導致了對已發表科學結果的信任缺失。
在本文中,我將探討一些可能導致模型「看起來很好但實際上並非如此」的問題。我也會討論一些預防這類錯誤的方法,包括使用最近推出的 REFORMS 機器學習科學研究檢核表。
被數據愚弄
誤導性的數據是一個很好的切入點,或者說是一個「不好」的起點,因為整個機器學習過程都建立在用於訓練和測試模型的數據之上。
在最糟糕的情況下,誤導性數據會導致所謂的「垃圾進,垃圾出」(garbage in garbage out)現象;也就是說,你可以訓練一個模型,並在測試集上獲得極佳的性能,但該模型在現實世界中完全沒有用處。這方面的例子可以在前述 Roberts 等人對 Covid 預測模型的評論中找到。在急於開發 Covid 預測工具的過程中,許多公共數據集變得可用,但後來發現這些數據集包含誤導性信號 —— 例如重複的記錄、錯誤的標籤和隱藏變量 —— 這些都幫助模型在沒有學到任何有用知識的情況下,準確地預測了類別標籤。
以隱藏變量(hidden variables)為例。這些是存在於數據中的特徵,它們恰好與數據中的類別標籤具有預測關係,但與標籤本身並無直接關聯。如果你的模型在訓練期間鎖定了這些特徵,它看起來會運作良好,但在新數據上可能失效。例如,在許多 Covid 胸部影像數據集中,身體姿勢是一個隱藏變量:患病的人更有可能是在躺著時接受掃描,而站立的人則往往是健康的。因為模型學到了這個隱藏變量,而不是疾病的真實特徵,許多 Covid 機器學習模型最終變成了「姿勢預測器」,而非「Covid 預測器」。儘管被稱為隱藏變量,它們通常就在顯眼處,已有許多分類器鎖定影像中嵌入的邊界標記、浮水印和時間戳記的例子,這些標記通常能區分類別,而無需查看實際數據。
另一個相關問題是虛假相關(spurious correlations)。與隱藏變量不同,這些與數據中的其他任何事物都沒有真實關係;它們只是恰好與類別標籤相關的模式。一個經典案例是 坦克問題,據稱美國軍方曾試圖訓練神經網絡識別坦克,但它實際上識別的是天氣,因為所有坦克的照片都是在同一時間段拍攝的。參考下圖:機器學習模型只需查看影像頂部的像素顏色,就能識別該數據集中所有的坦克照片,而無需考慮任何物體的形狀。模型的性能看起來會很棒,但在實踐中完全沒用。
(來源:作者提供) 許多(甚至是大多數)數據集都包含虛假相關,但它們通常不像這個例子這麼明顯。例如,常見的電腦視覺基準測試被 已知含有與類別標籤虛假相關的背景像素組。這對深度學習構成了特別的挑戰,因為深度學習有能力建模數據中的許多模式;各項研究表明,它們確實傾向於捕捉虛假相關的模式,這降低了它們的泛化能力。對對抗性攻擊(adversarial attacks)的敏感性就是後果之一:如果深度學習模型將預測建立在影像背景像素的虛假相關上,那麼對這些像素進行微小改動就能翻轉模型的預測。對抗性訓練(在訓練期間讓模型接觸對抗樣本)可以用來解決這個問題,但成本很高。一個更簡單的方法是觀察你的模型,看看它使用什麼信息來做決定。例如,如果由可解釋 AI 技術產生的顯著圖(saliency map)顯示你的模型正專注於背景中的某些事物,那麼它可能無法很好地泛化。
有時問題不在於數據本身,而在於數據的標籤。當數據由人工標註時,情況尤為如此,標籤最終可能會捕捉到標註者的偏見、錯誤假設或純粹的錯誤。這在 MNIST 和 CIFAR 等影像分類基準數據集中隨處可見,這些數據集通常有百分之幾的誤標率 —— 雖然比例不高,但當建模者在爭奪百分之零點幾的準確率時,這就變得非常重要。也就是說,如果你的模型比競爭對手好一點點,是因為真實的改進,還是因為對標註過程中的噪聲進行了建模?在處理具有隱含主觀性的數據(如情感分類)時,情況可能更麻煩,因為存在過擬合特定標註者的風險。
被洩漏誤導
壞數據不是唯一的問題。在機器學習流水線的後續環節中,還有很大的出錯空間。一個常見的問題是數據洩漏(data leakage)。當模型訓練流水線接觸到不該接觸的信息時,就會發生這種情況,特別是那些賦予模型優勢的信息。大多數時候,這表現為來自測試數據的信息洩漏 —— 雖然大多數人都知道測試數據應該保持獨立且不應在訓練中明確使用,但信息仍會通過各種微妙的方式洩漏出來。
一個例子是在劃分測試數據之前,對整個數據集執行依賴數據的預處理操作。也就是說,利用通過觀察所有數據而獲得的信息來更改所有數據。這類操作從簡單的(如數值特徵的中心化和縮放)到複雜的(如特徵選擇、降維和數據增強)不等 —— 但它們的共同點是都使用整個數據集的知識來引導結果。這意味著測試數據的知識已隱含地進入了模型訓練流水線,即使它沒有被明確用於訓練模型。因此,從測試集得出的任何性能衡量標準都可能高估了模型的真實性能。
讓我們考慮最簡單的例子:中心化和縮放。這涉及觀察每個特徵的範圍,然後使用此信息重新縮放所有值,通常使平均值為 0,標準差為 1。如果在劃分測試數據之前對整個數據集執行此操作,那麼訓練數據的縮放將包含有關測試集中特徵值範圍和分佈的信息。如果測試集的範圍比訓練集更廣,這會特別有問題,因為模型可能會從訓練數據中截斷的值範圍推斷出這一事實,並僅通過預測比訓練期間看到的更高或更低的值,就在測試集上表現良好。例如,如果你正在使用一個接收 0 到 1 範圍輸入的模型進行股票價格預測,但它在訓練期間只看到 0 到 0.5 範圍的值,那麼它不難推斷出未來股價會上漲。
事實上,預測(forecasting)是機器學習中特別容易受到數據洩漏影響的領域,這是由於所謂的「前瞻偏差」(look ahead bias)。當模型不應接觸的信息從未來洩漏並人為地提高了其在測試集上的性能時,就會發生這種情況。這通常發生在訓練集包含比測試集時間更晚的樣本時。我稍後會舉一個發生這種情況的例子,但如果你在這個領域工作,我也強烈建議看看這篇 關於評估時間序列預測模型的陷阱和最佳實踐的優秀評論。
一個更複雜的依賴數據預處理操作導致過於樂觀的性能指標的例子,可以在這篇 關於早產預測模型的評論中找到。基本上,許多論文報告了預測嬰兒是否早產的高準確率,但事實證明,它們都在劃分測試數據之前對數據集應用了數據增強。這導致測試集包含訓練數據的增強樣本,而訓練集包含測試數據的增強樣本 —— 這構成了非常嚴重的數據洩漏。當評論作者修正這一點後,模型的預測性能從接近完美下降到與隨機預測相差無幾。
(來源:https://arxiv.org/abs/2108.02497) 奇怪的是,最常見的數據洩漏例子之一並沒有統一的名稱(有人建議使用「過度炒作」[overhyping] 或「順序過擬合」[sequential overfitting] 等術語),但本質上它是「針對測試集進行訓練」(training to the test set)的一種形式。舉例來說,想像一下如上圖所示的情景:你訓練了一個模型並在測試集上進行了評估。然後你覺得它的性能不如預期,於是你調整了模型並重新評估。你還是不滿意,所以你一直重複這個過程,直到它在測試集上的性能足夠好。聽起來很熟悉嗎?這是一個常見的做法,但如果你反覆開發模型並在每次迭代後使用同一個測試集來評估,你基本上就是在利用該測試集來引導模型的開發。最終結果是你會對測試集產生過擬合,並可能得到一個關於模型泛化能力的過於樂觀的衡量標準。
有趣的是,當人們使用社群基準測試(如 MNIST、CIFAR 和 ImageNet)時,也會發生同樣的過程。幾乎每個從事影像分類的人都使用這些數據集來基準測試他們的方法;因此,隨著時間的推移,對這些基準測試產生某種程度的過擬合是不可避免的。為了緩解這種情況,始終建議使用多樣化的基準測試選擇,理想情況下,在其他人尚未使用的數據集上嘗試你的技術。
被指標誤導
一旦你穩健地構建了模型,接著就必須穩健地評估它。這裡也有很多可能出錯的地方。讓我們從不恰當的指標選擇開始。經典例子是在不平衡的數據集上使用準確率(accuracy)。想像一下,你訓練了一個模型,無論輸入是什麼,它總是預測同一個標籤。如果測試樣本中有一半的真實標籤是這個,那麼你會得到 50% 的準確率 —— 這沒問題,壞分類器得到壞準確率。但如果 90% 的測試樣本都是這個標籤,那麼你會得到 90% 的準確率 —— 壞分類器卻得到了好準確率。這種程度的不平衡在現實世界的數據集中並不罕見,而且在處理不平衡的訓練集時,得到一個總是預測多數類標籤的分類器也很常見。在這種情況下,使用 F-score 或馬修斯相關係數(Matthews correlation coefficient)會好得多,因為這些指標對類別不平衡較不敏感。然而,所有指標都有其弱點,因此最好使用一組指標組合,從不同角度反映模型的性能和失效模式。
時間序列預測的指標尤其麻煩。有很多選擇,而最合適的選擇可能取決於特定的問題領域和時間序列數據的確切性質。與用於分類的指標不同,時間序列預測中使用的許多回歸指標沒有自然刻度,這意味著原始數字可能具有誤導性。例如,均方誤差(MSE)的解釋取決於時間序列中存在的值範圍。因此,除了合適的指標外,使用合適的基準(baselines)也很重要。例如,這篇(已提到的)時間序列預測陷阱評論展示了在頂級 AI 會議上發表的許多深度學習模型實際上不如幼稚的基準模型。例如,他們顯示 Autoformer(一種專為時間序列預測設計的複雜 Transformer 模型)竟然會輸給一個預測「下一步不變」的平凡模型 —— 這一點僅看指標是看不出來的。
總體而言,目前有一種開發日益複雜的模型來解決困難問題的趨勢。然而,重要的是要記住,有些問題可能根本無法解決,無論模型變得多麼複雜。許多金融時間序列預測問題可能就是這種情況。在預測某些自然現象時也是如此,特別是那些包含混沌成分、導致無法預測超過一定時間跨度的現象。例如,許多人認為地震是無法預測的,但仍有大量論文報告在該任務上表現良好。這篇評論論文討論了這些正確的預測可能是由於一系列建模陷阱造成的,包括不恰當的基準選擇,以及由於數據稀疏、不必要的複雜性和數據洩漏導致的過擬合。
另一個問題是假設單次評估就足以衡量模型的性能。有時確實如此,但很多時候你會處理隨機或不穩定的模型;因此每次訓練它們時,都會得到不同的結果。或者你可能正在處理一個小型數據集,在這種情況下,你可能只是運氣好,分到了一個容易的測試集。為了應對這兩種情況,通常會使用交叉驗證(cross-validation)等重採樣方法,在數據的不同子集上訓練和測試模型,然後計算平均性能。然而,重採樣也會引入自身的風險。其中之一是數據洩漏風險增加,特別是當假設依賴數據的預處理操作(如中心化、縮放和特徵選擇)只需要做一次時。事實並非如此;它們需要在重採樣過程的每次迭代中獨立完成,否則會導致數據洩漏。下圖是一個例子,展示了特徵選擇應如何在交叉驗證的前兩次迭代中使用的兩個訓練集(藍色)上獨立進行,以及這如何導致每次選擇不同的特徵。
(來源:https://arxiv.org/abs/2108.02497) 正如我之前提到的,在處理時間序列數據時,數據洩漏的危險更大。使用標準交叉驗證,除了其中一次迭代外,每一次都會涉及使用至少一個比測試折(test fold)時間更晚的訓練折。例如,如果你想像上圖中的數據行代表按時間排序的多變量樣本,那麼兩次迭代中使用的測試集(粉紅色)在時間序列中都早於全部或部分訓練數據。這就是前瞻偏差的一個例子。可以使用替代方法(如分塊交叉驗證 [blocked cross-validation])來防止這種情況。
多次評估並非對每個人都是可行的選擇。例如,訓練一個基礎模型(foundation model)既耗時又昂貴,因此重複訓練是不可行的。根據你的資源,即使是相對較小的深度學習模型也可能面臨這種情況。如果是這樣,請考慮使用其他方法來衡量模型的穩健性。這包括使用可解釋性分析、執行消融研究(ablation studies)或增強測試數據。這些方法可以讓你超越可能具有誤導性的指標,深入了解模型的工作原理以及它可能如何失效,進而幫助你決定是否在實踐中使用它。
掉入更深處
到目前為止,我主要談論的是一般的機器學習過程,但在使用深度學習模型時,陷阱可能會更大。考慮潛在空間模型(latent space models)的使用。這些模型通常與使用它們的預測模型分開訓練。也就是說,訓練像自動編碼器(autoencoder)這樣的模型來進行特徵提取,然後在下游模型的訓練中使用該模型的輸出,這並不罕見。執行此操作時,必須確保下游模型中使用的測試集與自動編碼器中使用的訓練數據不重疊 —— 這在使用交叉驗證或其他重採樣方法時很容易發生,例如使用不同的隨機劃分或未選擇在相同訓練折上訓練的模型。
然而,隨著深度學習模型變得越來越大、越複雜,要確保不發生這類數據洩漏就變得更加困難。例如,如果你使用預訓練的基礎模型,可能無法判斷測試集中的數據是否曾被用於訓練該基礎模型 —— 特別是如果你使用來自互聯網的基準數據來測試模型。如果你使用複合模型,情況會變得更糟。例如,如果你在微調 GPT 型基礎模型時使用 BERT 型基礎模型來編碼輸入,除了你自己的微調數據外,你還必須考慮用於訓練這兩個基礎模型的數據集之間的任何交集。在實踐中,其中一些數據集可能是未知的,這意味著你無法確定你的模型是正確地泛化,還是僅僅在重現預訓練期間記住的數據。
避開深坑
這些陷阱非常普遍。那麼,避開它們的最佳方法是什麼?你可以做的一件事是使用檢核表(checklist),這基本上是一份正式文件,引導你了解機器學習流水線中的關鍵痛點,並幫助你識別潛在問題。在涉及高風險決策的領域(如醫學),已經有一些完善的檢核表,如 CLAIM,發表在這些領域的期刊通常會強制要求遵守這些標準。
不過,我想簡要介紹一個新成員:REFORMS,一個基於共識的機器學習科學研究檢核表。這是由來自電腦科學、數據科學、數學、社會科學和生物醫學領域的 19 位研究人員(包括我自己)共同編寫的,源於最近一次關於 機器學習科學研究再現性危機的研討會。它旨在以更獨立於領域的方式解決機器學習流水線中發生的常見錯誤,包括本文提到的許多錯誤。它由兩部分組成:檢核表本身,以及一份配套的指導文件,解釋了檢核表中每項內容的重要性。該檢核表貫穿機器學習研究的主要組成部分,鼓勵用戶驗證其機器學習過程的設計是否支持研究的總體目標,是否避開了常見陷阱,並使結果能被獨立研究人員驗證。雖然它專注於機器學習在科學背景下的應用,但其中涵蓋的許多內容具有更廣泛的適用性,因此即使你不認為自己的工作是「科學」,我也鼓勵你看一看。
另一種避免陷阱的方法是更好地利用工具。目前我對機器學習現狀的一個不滿是,常用工具在防止犯錯方面做得很少。也就是說,它們會任由你以各種方式濫用機器學習過程,而不會告訴你這樣做是錯的。儘管如此,實驗追蹤框架(experiment tracking frameworks)可以提供幫助,它們會自動記錄你訓練的模型以及訓練方式,這對於發現數據洩漏和針對測試集訓練等問題非常有用。開源選項有 MLFlow,但也有許多商業產品。MLOps 工具則更進一步,幫助管理機器學習工作流中的所有移動部件,包括人員。
最後的思考
訓練出一個能很好泛化到未見數據的好模型是可能的,但在你確信所有可能出錯的地方都沒出錯之前,我不會輕易相信結果。保持健康的懷疑態度是一件好事:務必觀察你訓練的模型以確保它在做合理的事情,務必分析你的指標以了解它在哪裡出錯,務必對照適當的基準校準你的結果,並務必考慮使用檢核表以確保你沒有忽略重要的細節。
作者簡介
Michael 是愛丁堡赫瑞瓦特大學(Heriot-Watt University)的副教授。他在機器學習和生物啟發計算領域從事了約 20 年的研究。更多信息請見其 學術網站。他也在其 Substack 專欄 Fetch Decode Execute 中撰寫更廣泛的電腦科學內容。
引用
在學術背景或書籍中引用時,請標註為:
Michael Lones, "Why Doesn’t My Model Work?", The Gradient, 2024.
BibTeX 引用格式:
@article{lones2024why,
author = {Michael Lones},
title = {Why Doesn’t My Model Work?},
journal = {The Gradient},
year = {2024},
howpublished = {\url{https://thegradient.pub/why-doesnt-my-model-work},
}
相關文章