如何改善你的訓練資料集?(附案例)

資料派THU發表於2018-08-04

如何改善你的訓練資料集?(附案例)這張幻燈片是Andrej Karpathy 在Train AI 演講的一部分,我很贊同它表達的觀點。它充分體現了深度學習在研究和應用上的差異。學術論文幾乎全部集中在新的和改進的模型上,使用的資料集是從公共資料集中選出的一小部分。相反,我認識的將深度學習作為實際應用的一部分人,他們大部分時間都在思考如何改善訓練資料。

關於研究人員專注於模型架構有很多好的理由,但它確實意味著很少有資源可以引導那些專注於在生產中部署機器學習的人。我在會上的發言是“那些有效到不合常理的訓練資料”。在這裡我想稍微擴充套件一下,解釋訓練資料為什麼如此重要,以及一些改進它的實用技巧。

因為工作的原因,我需要與許多研究人員和產品團隊緊密合作。我對於改善資料可以帶來效果提升的信念來源於我看到它們在構建模型時取得了巨大的成果。現實世界的大部分應用中,運用深度學習的最大障礙就是沒有足夠高的精度,而我看到提高精度的最快的方法就是改善訓練資料集。即使你被困在延遲或儲存大小等其他約束上,你可以通過更小的架構來換取一些效能特徵,這樣可以提高特定模型的準確性。

語音指令

我不能分享我對生產系統的大部分觀察,但是我有一個開源例子可以證明同樣的道理。去年,我用Tensorflow建立了一個簡單的語音識別的例子,但是事實證明,沒有現有的資料集可以很容易地用於訓練模型。不過在很多志願者慷慨的幫助下,我收集了60000個由他們說的短語音訊片段。在此感謝“開放式語音錄製網站”(Open Speech Recording site)的AIY團隊幫我發起這個專案。最後得到的模型是可以使用的,但並沒有達到我所希望的精度。

如何改善你的訓練資料集?(附案例)

為了看看模型設計者的身份對我產生的侷限性有多大,我使用相同的資料集發起了一個Kaggle比賽。參賽者的結果要比我最初的模型好很多,但即使有很多團隊提出很多不同的方法,最後達到91%精度的只有很少的一部分人。對我來說,這意味著資料有一些根本上的錯誤,而且參賽者也確實發現了很多錯誤,比如不正確的標籤或者截斷的音訊。更多的樣本開始促使我關注資料集新版本中他們發現的固定的問題。

我檢視了錯誤評價指標,來了解模型中哪些詞的問題最多。結果發現“其它”類別(當語音被識別,但單詞表不在模型的有限詞彙表內)特別容易出錯。為了解決這個問題,我增加了我們正在捕獲的不同單詞的數量,以提供更多樣化的訓練資料。

因為Kaggle參賽者提出的標籤錯誤,我“眾包”了一個額外的驗證通道,要求人們聽每個剪輯,並確保它可以匹配到期望的標籤。另外,他們也發現了一些幾乎無聲或者被截斷的檔案,因此我編寫了一個實用工具來做一些音訊分析,並自動剔除糟糕的樣本。儘管刪除了一些糟糕的檔案,最後我還是將總的說話數量增加到了100000。這要感謝更多志願者和收費“眾包”者的幫助。

為了幫助別人使用這個資料集(並從我的錯誤中學習),我將所有相關的事情和最新的精度結果寫進了一篇論文。最重要的結論是,在不改變模型或測試資料的前提下,第一名的精度提高了4%,從85.4%提高到了89.7%。這個提高讓人很激動,並且當人們在Android 或 Raspberry Pi 演示應用中使用該模型時,反映了更高的滿意度。我相信如果我花時間在模型架構的調整上,儘管我知道我的模型不如最好的模型,最終我得到的精度的提高肯定沒有現在的多。

論文:

https://arxiv.org/abs/1804.03209

這就是在生產環境中一次又一次地產生偉大結果的過程。但是如果你想做同樣的事情,很難知道從哪裡開始,你可以從我處理語音資料所使用的技巧中得到一些啟發。為了更加明確,這裡有一些我發現的有用的方法。

首先,瞭解你的資料

這似乎是顯而易見的,但你的第一步應該是隨機瀏覽你將要開始使用的訓練資料。複製一些資料檔案到你本地的機器上,然後花費幾個小時預覽它們。如果你的資料集是圖片,可以使用類似MacOS’s的查詢器來滾動縮圖檢視,可以很快的檢查完數千張圖片。

對於音訊,可以使用取景器播放預覽,對於文字可以將隨機片段轉存到終端上。

在第一個版本的語音指令中,我沒有花費足夠的時間來做這些。這也是為什麼Kaggle參賽者一開始使用這個資料集就會發現很多問題。經歷這個過程我總覺得有點傻,但事後我再也沒有後悔過。每次我做完這個過程,我都會從資料中發現一些重要的事情。比如是否各類別中例子的數量不均衡,損壞的資料(例如,用JPG檔案擴充套件標記的PNG),不正確的標籤,或者只是令人驚訝的組合。

Tom White通過觀察ImageNet得到了一些奇妙的發現,包括“太陽鏡”標籤實際上是一個古老的放大陽光的裝置,用於“垃圾車”的魅力鏡頭,對不死女性的“斗篷”偏見。Andrej’s的工作是手工從ImageNet中分類照片,這也教會我關於資料集的很多東西。包括即使對於一個人來說,將所有不同品種的狗區分出來是有多難。

如何改善你的訓練資料集?(附案例)

你將要做什麼取決於你發現了什麼。你應該在清洗資料之前總是進行一次這種資料觀察,因為,對資料集的直觀認識將會有助於你在接下來的流程中做決策。

快速選擇一個模型

不要在選擇模型上花費太多時間。如果你在做圖片分類,可以參考AutoML,或者看看類似Tensorflow的模型庫,再或者從Fast.AI蒐集的例子中找一個解決類似問題的模型(http://www.fast.ai/)。重要的是儘快開始迭代,這樣你就可以提前和真實使用者一起嘗試你的模型。你總是可以在以後得出一個改進的模型,並且也許可以得到更好的結果,但是你首先要得到資料。深度學習仍然遵循‘垃圾入,垃圾出’(“garbage in, garbage out”)的基本計演算法則,所以即使是最好的模型也會受到訓練集缺陷的限制。通過挑選一個模型並測試它,你將能夠得知這些缺陷是什麼並且開始改進它們。

AutoML

https://cloud.google .com/automl/

Fast.AI:

http://www.fast.ai/

為了加快你的迭代速度,可以嘗試從一個已經在一個大的現有資料集上預先訓練的模型開始,然後使用遷移學習在你收集的資料集(可能很小)上進行微調。

這通常比只在較小的資料集上進行訓練的效果要好得多,而且速度快得多,並且你可以快速地瞭解如何調整資料收集策略。最重要的是,你可以把你的結果反饋到你的收集過程中,以適應你學習的情況,而不是在訓練之前把收集資料作為一個單獨的階段來進行。

成為它之前先假裝它

研究模型和生產模型的最大區別在於研究通常在開始時有明確的問題陳述,但是實際應用的要求被鎖定在使用者的意識行為中,並且只能隨著時間的推移而被提取。

例如,在Jetpac中我們想要找到一張好的照片去展現在城市自動旅行指南中。我們開始時要求評價人給他們認為好的照片打一個標籤,但最後我們看到了很多微笑的人的照片,因為他們就是這樣解釋這個問題的。我們把這些放在產品的模型中,看看測試使用者是如何反應的。結果是他們沒有留下深刻的印象,也沒有被這些照片所鼓舞。

為了解決這個問題,我們重新定義了提問的問題:“這張照片會讓你想去它所展示的地方嗎?”。這使我們得到了更好的結果,但也反應出我們使用的工人是東南亞人,他們認為會議照片看起來令人很驚異,因為大飯店裡充滿了穿西裝和拿紅酒杯的人。

這種不匹配及時提醒了我們生活在“泡沫”裡,但這也確實是一個現實的問題,因為我們美國的目標觀眾看到這些會議照片會感到沮喪和沒有理想。最後,我們在JETPAC團隊中的六個人手動評估了超過二百萬張照片,因為我們比我們可以訓練的任何人都要熟悉標準。

這是一個極端的例子,但是它證明了標記過程很大程度上取決於應用的需求。對大多數生產用例來說,存在一個要為模型找合適的問題去回答的過程,而且這才是關鍵所在。如果你用你的模型回答了錯誤的問題,你將永遠無法在這個糟糕的基礎上建立一個可靠的使用者體驗。

如何改善你的訓練資料集?(附案例)

Thomas Hawk拍攝

我已經告訴你詢問正確問題的唯一方法就是模仿你的應用,而不是一個人陷在機器學習迴圈中。因為有一個人在幕後,這有時被稱為‘Wizard-of-Oz-ing’。我們讓人們手動選擇一些旅行指南的樣本照片,而不是訓練一個模型,然後使用來自測試使用者的反饋來調整我們挑選圖片的標準。

一旦我們從測試使用者那裡得到可靠的正向反饋,為了得到數百萬張照片的訓練集,我們會把制定的挑選照片的規則轉換為標籤集。然後,它訓練了能夠預測數十億張照片質量的模型,但是它的DNA來自我們開發的原始手工規則。

在真實的資料上訓練

在Jetpac,我們用來訓練我們模型的影象來自相同的資料來源(大部分來自Facebook和Instagram) ,也是我們想用在模型上的影象。我所看到的一個常見問題是訓練資料集在重要的方面與模型最終會在生產中看到的輸入不同。

如何改善你的訓練資料集?(附案例)

目前世界上影象識別最大的資料庫ImageNet

例如,我經常會看到團隊在ImageNet上訓練一個模型,但當他們試圖在無人機或機器人中使用時就會碰到問題。原因ImageNet都是人拍攝的照片,這些照片有很多共同之處。它們是用手機或靜態相機拍攝的,使用中性透鏡,在大致的高度,白天或人工照明的條件下,把物件標記在中心突出的位置。

機器人和無人機使用的攝像機通常是高視野鏡頭。無論是從地面還是從上方,照明都很差,沒有任何物件的智慧框架,因此它們通常被裁剪。這種差異意味著如果你只接受一個從ImageNet的照片中訓練出來的模型,並將其部署在這些裝置上,那麼你就會發現精確度不高。

有關你的訓練資料偏離模型本來應該需要的訓練資料,還存在很多微妙的形式。想象一下,你正在建造一個相機來識別野生動物,並利用世界各地的動物資料集進行訓練。如果你只在Borneo叢林中部署,那麼企鵝標籤的正確率肯定是極低的。

如果南極照片被包含在訓練資料中,那麼它將有更高的機率將其他東西誤認為企鵝,所以你的總錯誤率會比你排除那些訓練中的影象更糟糕。有一些方法可以根據已知的先驗資訊來校準你的結果(例如,在叢林環境下大規模的企鵝的概率),但是使用一個反映產品實際遇到的情況的訓練集更容易和更有效。

我發現,最好的方法是使用直接從實際應用程式得到的資料,這些資料與上面提到的Wizard of Oz方法很好地聯絡在一起。迴圈中的人成為初始資料集的打標籤者,即使收集的標籤數量很小,它們也會反映實際使用情況,並且對於遷移學習的一些初步實驗應該是足夠的。

遵循指標

當我在做語音指令的例子時,看到的最頻繁的報告就是訓練過程中的混淆矩陣。這裡有一個例子,展示瞭如何在控制檯中顯示:

如何改善你的訓練資料集?(附案例)

這看起來可能很嚇人,但實際上它只是一張表格,顯示了網路所犯的錯誤的細節。這裡有一份更漂亮的標籤版本:

如何改善你的訓練資料集?(附案例)

表格中的每一行代表一組樣本,其中真實的標籤是相同的。每一列代表樣本被預測為對應標籤的次數。例如,高亮顯示的一行代表所有實際上是無聲的音訊樣本,如果你從左讀到右,你可以看到那些預測正確的標籤,每一個都落在預測無聲的列中。

這告訴我們,這個模型可以很好地發現真正的無聲樣本,並且沒有負樣本。如果我們看一下展示有多少將音訊預測為無聲的一整列,就可以發現一些音訊片段實際上是誤分到無聲的一列中的,這一列有很多假正例。

事實證明這個是很有幫助的,因為它可以讓我更加仔細地分析那些被錯誤地歸類為無聲的片段,從而發現他們大部分是極其安靜的錄音。根據混淆矩陣提供的線索,我清除了低音量的音訊片段,這幫助我提高了資料質量。

雖然大多數結果是有用的,但是我發現混淆矩陣是一個很好的折衷,因為它比僅僅一個精確值給的資訊要多,卻又沒有呈現太多複雜的細節。在訓練過程中觀察數字的變化是很有用的,因為它可以告訴你模型正在努力學習的類別,並且可以讓你在清理和擴充套件資料集時集中精力。

相似的方法

我最喜歡的一種理解我的模型如何解釋訓練資料的方法就是視覺化。TensorBoard可以很好的支援這種探索,雖然它經常用來視覺化詞嵌入,但是我發現它幾乎對每一層都很有用,工作原理也像詞嵌入。例如,影象分類網路通常在最後一層的全連線層或者softmax之前有一層網路可以用來作為嵌入(這就是簡單的遷移學習的例子,和TensorFlow for Poets(地址如下)工作流程很像)。

這些並不是嚴格意義上的嵌入,因為在訓練過程中並沒有任何機制去保證真正的嵌入佈局中有理想的空間屬性,但是對它們的向量進行聚類確實可以產生很多有趣的東西。

連結:

https://codelabs.developers.google.com/codelabs/tensorflow-for-poets/#2

舉一個實際的例子,我合作的一個團隊對某些動物的影象分類模型的高錯誤率感到很困惑。他們使用聚類視覺化去觀察訓練資料中不同的類別是如何分佈的。當他們在看“捷豹”這個類別時,很清楚的看到資料被分為兩組之間的距離。

如何改善你的訓練資料集?(附案例)

圖片來自djblock99Dave Adams

這是他們看到的一幅圖,一旦每個聚類的照片都顯示出來,就可以很明顯的發現許多捷豹品牌的汽車都被錯誤地貼上了捷豹貓的標籤。如果團隊成員知道了這些,那麼就會去關注標註過程,並且可以意識到工人的方向和用於標註的使用者介面不夠完善。

有了這些資訊,他們就能夠改進標註者(人)的培訓過程並且去修復標註工具。這可以將所有的汽車影象從捷豹類別中移除,併為這一類別提供了一個更好的模型。

聚類通過讓你對訓練集進行深刻的瞭解,可以讓你得到與你探索資料相似的好處。但是,網路實際上是按照它自己的學習理解將輸入資料排序分組,然後指導你探索資料。

人類很擅長在視覺資訊中發現異常,因此將我們的直覺和計算機處理大量資料的能力結合起來是一種非常靈活的追蹤資料集質量的解決方案。關於如何使用TensorBoard來做這件事超出了本文的範圍(文章已經足夠長了,我很感激你還在繼續讀下去)。但是如果你真的想提高你的結果,我強烈建議你熟悉這個工具。

收集資料不能停

我從來沒有見過收集更多的資料不能提高模型準確性的例子,而且也有很多研究可以支援我的經驗。

如何改善你的訓練資料集?(附案例)

這張圖片來自“重新審視那些有效到不合常理的訓練資料”,並且展示了即使資料集已經增長到了數億,影象分類模型的精度依然不斷增加。

Facebook最近更加深入的使用大資料量,例如,在ImageNet分類中使用了數十億個帶有標籤的Instagram圖片,以達到新的記錄精度。這表明,即使對於大型、高質量資料集的問題,增加訓練集的大小仍然可以提高模型結果。

這意味著只要使用者可以從更高精度的模型中受益,你就需要一個不斷改善資料質量的策略。如果可以的話,找到一種創造性的方法,利用即使微弱的訊號也可以得到更大的資料集。Facebook使用Instagram標籤就是一個很好的例子。

還有一種方法是提高標註“管道”的智慧性,例如通過增加由初始模型預測的建議標籤的工具,這樣可以使打標籤的人快速做決定。這在剛開始可能有風險,但是在實際應用中受益往往超過了這種風險。

通過僱傭更多的人來給新的訓練資料貼上標籤來解決這個問題通常也是一項有價值的投資。不過因為這種花費通常沒有預算,組織過程中會有很多困難。如果是一個非盈利的組織,則可以讓你的支持者通過某種公共工具自願貢獻資料,這是一種在不花費錢的同時提高資料集規模的好方式。

當然任何組織都希望有一個產品,當它在正常使用時可以生成標註資料。

我不會太執著於這樣的想法,它不符合很多現實世界的用例。即人們只是想盡快得到一個答案而並不涉及標籤的複雜問題。如果你是一家創業公司,這是一個很好的投資專案,因為它就像是一臺用於改進模型的永動機。

但是在清理或增加你接收到的資料時,幾乎總是會有一些單位成本,因此,最後花的錢往往最終看起來更像是一個廉價版的商業眾包,而不是真正免費的東西。

通往危險區域的高速公路

模型錯誤對產品使用者的影響往往要大於由損失函式捕捉到的錯誤。你應該提前想到可能發生的最糟糕的結果,併為模型設計一個輔助程式來避免發生。這也許是一個你永遠都不想預測的類別黑名單,因為假正例的代價太大。

或者你僅僅有一套簡單演算法去保證發生的結果不會超過你已經設定的引數邊界。例如,你可能會保留一個永遠不希望文字生成器輸出的粗俗語言的列表,即使它們在訓練集中,因為它們不適合出現在產品中。

因為我們不能總是知道未來可能會出現什麼不好的結果,所以學習現實世界中的錯誤是很重要的。如果你有了合適的產品或市場,那麼從現實中學習最簡單的辦法就是使用錯誤報告。

另外,當使用者使用你的應用程式出現他們不想要的東西時,應該給使用者一個便捷的反饋路徑。如果可以的話,獲取模型的全部輸入,但是如果資料是敏感資料,那麼僅僅知道錯誤的輸出是什麼也可以幫助你調查原因。這些類別可以用來決定收集更多什麼樣的資料,並且這些類別可以讓你理解當前標籤的質量。

一旦你對模型進行了新的修改,就會有一組先前產生了壞結果的輸入,並且除了正常的測試集之外,還對它們進行單獨的評估。這個有點像一個迴歸測試,並給你一個方法追蹤你改進使用者體驗的效果如何,因為單一的模型精度度量永遠不會完全捕捉到人們關心的一切。

通過看一些過去引起強烈反應的例子,你就有了一些獨立證據表明你實際上是在為你的使用者做得更好。如果在一些情況下因為資料太敏感而不能得到輸入資料,可以使用內部測試或者內部實驗來確定什麼樣的輸入會產生這些錯誤,然後代替迴歸資料集中的那些資料。

故事是什麼,曇花一現?

我希望我已經說服你花更多的時間在你的資料上,並且給你了一些關於如何投入精力改進它的想法。對資料領域的關注並沒有它值得的那麼多,而且我真的覺得我在這裡的建議僅僅是涉及資料表面。

我很感謝所有與我分享他們的策略的人,另外我希望我可以從更多的人那裡聽到你已經取得成功的方法。我認為會有越來越多的機構將工程師團隊專門用於資料集的改進,而不是讓機器學習研究人員來推動進展。我期待著看到整個領域的發展。

我總是驚歎於即使是在有著嚴重缺陷訓練資料的情況下模型依然可以運作良好。因此我迫不及待的想看看隨著我們資料集質量的提高我們可以做些什麼。

相關文章