當數據量不夠大的時候,有什麼方法可以提高CNN訓練效果?

手中的數據集大概四百張圖,用CNN去處理時錯誤率一直很高,懷疑是數據量太小,那麼,當數據集數據量不夠大(圖片不夠多的時候),有什麼方法可以提高改善卷積神經網路的訓練效果呢?


巧婦難為無米之炊。

數據往往比模型重要得多。採樣的範圍夠廣,採樣的密度夠密,模型學到的結果才可能趨近於真實分布的情況。

很多次有人跟我說模型不work,我看了他們的樣本之後,哪裡是模型的問題,根本就是他們的應用場景過於複雜而樣本極其不足。比如說一個判別某器件是否破損的應用,一看樣本就傻了,各種大小各種款式各種角度各種不同的破損位置,然後每種情況只有一兩張樣本,而且訓練集和測試集基本不相似,從我人眼的角度去看沒有經過認真研究分析都無法判別。拜託,不要以為模型是神,不是什麼都可以一套上去就能work的。

你需要去摸熟一個模型的能力可以到哪裡,給什麼樣的特徵有什麼優劣。最好的模型在模式識別的問題上都難以比得上人類一個小孩子的水平。

了解了模型的能力之外,更重要的是理解你的應用本身,去分析數據,儘可能去尋找數據的先驗知識。一方面用預處理做特徵變換,使得問題被簡化;一方面也可以將一些先驗知識告訴模型,讓模型更合乎應用特點。

讓一個小學生做區區幾道題就要求人家舉一反三熟練掌握高數,這種行為是極其過分的。

回到你的問題。在不增加樣本的條件下,你只能儘可能找先驗做人工的特徵變換設計,比如目標定位、摳出來、角度旋轉、尺度縮放,把對分類有用的關鍵信息突出來擺給模型看,讓無關的特徵儘可能少,有關的特徵儘可能多。「變換成這樣就算傻子都會判別了吧」,能達到這種效果,模型的效果就差不到哪裡去了。

找先驗,人工特徵工程,這件事是很低效的,是沒辦法的辦法。樣本多的時候,利用好機器學習,可以大大縮小人工設計的工作量,大大提高生產效率。這也正是深度學習對這個時代的真正偉大之處。


首先,數據量不夠,你就把1個當8、9、10······個用,裁剪裁剪,變換變換,翻轉翻轉。

其次,學習特徵不夠,人工先驗來湊。

最後,想到老闆以前提過的一個問題:咱們沒錢買數據沒錢買設備(沒錢你還做什麼DL!),那就想想別的辦法,試一試transfer learning嘛!遷移一下。


如果是為了訓練的話,不是有那麼多開放的圖片庫嗎……

如果你是想用卷積神經網路做圖片相關工作(我猜可能是分類),那麼我猜你一定看過Hinton 12年的那篇論文,那你一定知道裡面有一節就提到了怎麼擴大數據量(他是為了減小過擬合),他用的方法有:

1: 在256*256的圖片上截取224*224的圖片,做水平翻轉,數據量擴大了2048倍;

2、貌似首先做了個主成分分析,然後是在RGB的值上加了一個(0,0.1)的高斯分布…(躺床上手機碼記不太清…)


如 @Stark Einstein 的答案所說, 數據比模型重要的多. 如果先驗和人工特徵工程依然不夠用的話, 可以考慮以下四個trick, 效果有限不過可以一試.

1. @陳語 和 @名稱不重要 的答案中提到的人工增加訓練集的大小. 通過平移, 翻轉, 加雜訊等方法從已有數據中創造出一批"新"的數據.

2. Regularization. 數據量比較小會導致模型過擬合, 使得訓練誤差很小而測試誤差特別大. 通過在Loss Function 後面加上正則項可以抑制過擬合的產生. 缺點是引入了一個需要手動調整的hyper-parameter. 詳見 https://www.wikiwand.com/en/Regularization_(mathematics)

3. Dropout. 這也是一種正則化手段. 不過跟以上不同的是它通過隨機將部分神經元的輸出置零來實現. 詳見 http://www.cs.toronto.edu/~hinton/absps/JMLRdropout.pdf

4. Unsupervised Pre-training. 用Auto-Encoder或者RBM的卷積形式一層一層地做無監督預訓練, 最後加上分類層做有監督的Fine-Tuning. 參考 http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.207.1102rep=rep1type=pdf

*注: 以上四種方法效果有限, 選擇一個好的數據集才是正道.


數據的確太少,嘗試一下先做data augmentation,然後transfer learning


前幾天看個paper,直接考慮data similarity可以緩解sparsity,也許是個思路。


可以試一試generative model,產生一些模擬數據。


原來還是擺脫不了大數據。。。。有沒有一個標準,多少張訓練集才不算樣本少。


最好詳細說一下你要做的任務是什麼,以下幾點可供參考:

1.網路不要太深太大;

2.各種data augmentation;

3.可以考慮用別人在大數據集上訓練好的網路fine tune,如果網路結構不同,那就自己在大點的數據集上訓練一遍,畢竟底層學到的東西都差不多;

4.考慮多用幾種損失,可以協同訓練,也可以串列訓練,或者把幾種損失訓練出來的結果ensemble起來;

5.當然,想辦法收集更多的樣本是最有效的。


訓練集識別率如何?先確定是不是過擬合


當然是接著采數據啦


推薦閱讀:

研究linux kernel 0.11有哪些意義?
中國計算機專業留學生在美國現在的就業情況究竟怎樣?
大學學計算機為什麼必須要學演算法?
僅參考 C99 Standard 可以實現一個完整的 C99 編譯器嗎?
如何產生正態分布的隨機數?

TAG:人工智慧 | 機器學習 | 計算機科學 | 深度學習DeepLearning |