如何使用來自不同分佈的資料,進行訓練和測試
深度學習演算法對訓練資料的胃口很大,當收集到足夠多帶標籤的資料構成訓練集時,演算法效果最好,這導致很多團隊用盡一切辦法收集資料,然後把它們堆到訓練集裡,讓訓練的資料量更大,即使有些資料,甚至是大部分資料都來自和開發集、測試集不同的分佈。在深度學習時代,越來越多的團隊都用來自和開發集、測試集分佈不同的資料來訓練,這裡有一些微妙的地方,一些最佳做法來處理訓練集和測試集存在差異的情況。
假設在開發一個手機應用,使用者會上傳他們用手機拍攝的照片,想識別使用者從應用中上傳的圖片是不是貓。現在有兩個資料來源,一個是真正關心的資料分佈,來自應用上傳的資料,比如右邊的應用,這些照片一般更業餘,取景不太好,有些甚至很模糊,因為它們都是業餘使用者拍的。另一個資料來源就是可以用爬蟲程式挖掘網頁直接下載,就這個樣本而言,可以下載很多取景專業、高解析度、拍攝專業的貓圖片。如果應用使用者數還不多,也許只收集到10,000張使用者上傳的照片,但透過爬蟲挖掘網頁,可以下載到海量貓圖,也許從網際網路上下載了超過20萬張貓圖。而真正關心的演算法表現是最終系統處理來自應用程式的這個圖片分佈時效果好不好,因為最後使用者會上傳類似右邊這些圖片,分類器必須在這個任務中表現良好。現在就陷入困境了,因為有一個相對小的資料集,只有10,000個樣本來自那個分佈,而還有一個大得多的資料集來自另一個分佈,圖片的外觀和真正想要處理的並不一樣。但又不想直接用這10,000張圖片,因為這樣訓練集就太小了,使用這20萬張圖片似乎有幫助。但是,困境在於,這20萬張圖片並不完全來自想要的分佈,那麼可以怎麼做呢?
這裡有一種選擇,可以做的一件事是將兩組資料合併在一起,這樣就有21萬張照片,可以把這21萬張照片隨機分配到訓練、開發和測試集中。為了說明觀點,假設已經確定開發集和測試集各包含2500個樣本,所以訓練集有205000個樣本。現在這麼設立資料集有一些好處,也有壞處。好處在於,訓練集、開發集和測試集都來自同一分佈,這樣更好管理。但壞處在於,這壞處還不小,就是如果觀察開發集,看看這2500個樣本其中很多圖片都來自網頁下載的圖片,那並不是真正關心的資料分佈,真正要處理的是來自手機的圖片。
所以結果資料總量,這200,000個樣本,就用\(200k\)縮寫表示,把那些是從網頁下載的資料總量寫成\(210k\),所以對於這2500個樣本,數學期望值是:\(2500\times \frac{200k}{210k} =2381\),有2381張圖來自網頁下載,這是期望值,確切數目會變化,取決於具體的隨機分配操作。但平均而言,只有119張圖來自手機上傳。要記住,設立開發集的目的是告訴團隊去瞄準的目標,而瞄準目標的方式,大部分精力都用在最佳化來自網頁下載的圖片,這其實不是想要的。所以真的不建議使用第一個選項,因為這樣設立開發集就是告訴團隊,針對不同於實際關心的資料分佈去最佳化,所以不要這麼做。
建議走另外一條路,就是這樣,訓練集,比如說還是205,000張圖片,訓練集是來自網頁下載的200,000張圖片,然後如果需要的話,再加上5000張來自手機上傳的圖片。然後對於開發集和測試集,這資料集的大小是按比例畫的,開發集和測試集都是手機圖。而訓練集包含了來自網頁的20萬張圖片,還有5000張來自應用的圖片,開發集就是2500張來自應用的圖片,測試集也是2500張來自應用的圖片。這樣將資料分成訓練集、開發集和測試集的好處在於,現在瞄準的目標就是想要處理的目標,告訴團隊,開發集包含的資料全部來自手機上傳,這是真正關心的圖片分佈。試試搭建一個學習系統,讓系統在處理手機上傳圖片分佈時效果良好。缺點在於,當然了,現在訓練集分佈和開發集、測試集分佈並不一樣。但事實證明,這樣把資料分成訓練、開發和測試集,在長期能給帶來更好的系統效能。以後會討論一些特殊的技巧,可以處理訓練集的分佈和開發集和測試集分佈不一樣的情況。
來看另一個樣本,假設正在開發一個全新的產品,一個語音啟用汽車後視鏡,這在中國是個真實存在的產品,它正在進入其他國家。但這就是造一個後視鏡,把這個小東西換掉,現在就可以和後視鏡對話了,然後只需要說:“親愛的後視鏡,請幫找找到最近的加油站的導航方向”,然後後視鏡就會處理這個請求。所以這實際上是一個真正的產品,假設現在要為自己的國家研製這個產品,那麼怎麼收集資料去訓練這個產品語言識別模組呢?
嗯,也許已經在語音識別領域上工作了很久,所以有很多來自其他語音識別應用的資料,它們並不是來自語音啟用後視鏡的資料。現在講講如何分配訓練集、開發集和測試集。對於訓練集,可以將擁有的所有語音資料,從其他語音識別問題收集來的資料,比如這些年從各種語音識別資料供應商買來的資料,今天可以直接買到成\(x\),\(y\)對的資料,其中\(x\)是音訊剪輯,\(y\)是聽寫記錄。或者也許研究過智慧音響,語音啟用音響,所以有一些資料,也許做過語音啟用鍵盤的開發之類的。
舉例來說,也許從這些來源收集了500,000段錄音,對於開發集和測試集也許資料集小得多,比如實際上來自語音啟用後視鏡的資料。因為使用者要查詢導航資訊或試圖找到通往各個地方的路線,這個資料集可能會有很多街道地址,對吧?“請幫導航到這個街道地址”,或者說:“請幫助導航到這個加油站”,所以這個資料的分佈和左邊大不一樣,但這真的是關心的資料,因為這些資料是產品必須處理好的,所以就應該把它設成開發和測試集。
在這個樣本中,應該這樣設立訓練集,左邊有500,000段語音,然後開發集和測試集,把它簡寫成\(D\)和\(T\),可能每個集包含10,000段語音,是從實際的語音啟用後視鏡收集的。或者換種方式,如果覺得不需要將20,000段來自語音啟用後視鏡的錄音全部放進開發和測試集,也許可以拿一半,把它放在訓練集裡,那麼訓練集可能是51萬段語音,包括來自那裡的50萬段語音,還有來自後視鏡的1萬段語音,然後開發集和測試集也許各自有5000段語音。所以有2萬段語音,也許1萬段語音放入了訓練集,5000放入開發集,5000放入測試集。所以這是另一種將資料分成訓練、開發和測試的方式。這樣訓練集大得多,大概有50萬段語音,比只用語音啟用後視鏡資料作為訓練集要大得多。
見到幾組樣本,讓訓練集資料來自和開發集、測試集不同的分佈,這樣就可以有更多的訓練資料。在這些樣本中,這將改善學習演算法。