kaggle首戰,踩坑?學習?

前段時間刷了kaggleCarvana Image Masking Challenge,剛好top10%。第一次刷,這樣的分數,意料之中也是情理之中。閑暇之餘,分享下在比賽中做過的一些嘗試,希望前人踩坑,後人避坑。

首先,先說下「放諸四海皆準」的感悟(這是多麼痛的領悟啊)。

好記性不如爛筆頭,一般人是很難記住這次煉了哪些丹(調參),所以每次提交完結果,最好備註這次具體做了什麼實驗,結果是否有所提升,對後續的查閱真的很有幫助啊。(不要問我為什麼把這條放在第一位,畢竟現在流的淚都是當時xx進的水)

接下來,將會按照「做了什麼,為什麼要這樣做,這樣做的實驗結果」的形式展開敘述(好一本正經啊)。

看下數據集:

全都是豪車啊,是不是有想買的衝動,正所謂香車美人……(啊呸,跑題了跑題了)

(拉回正文)

比賽給的是1918x1280的圖片,要求將車(前景分割出來)。

這樣大的圖片,讓人望文生畏啊,尤其是對於硬體條件有限的學生黨(一張1080Ti)來說。

不怕,正所謂「上有政策,下有對策」,提供的這麼大,但是可以resize之後再餵給網路啊,說干就干。

所以,做的第一個嘗試就是:

調整圖片尺寸

對比了512x512、1024x1024、1280x1280的結果,還是1280的圖片更勝一籌啊。

既然input size越大,dice係數(模型評價指標)越高,那索性就輸入原圖試試。果不其然,1920x1280的分數更高。

(咦,不對啊,原圖不是1918x1280嗎,怎麼變成了1920呢?因為在conv之後使用了2x2的maxpooling,這樣可以保證池化得到的特徵圖依舊是偶數,下文的原圖即為該尺寸)

一定要輸入這麼大的圖片嗎?(嗚嗚嗚……)input size變大,batch size就要減小,這樣iteration次數就增加,訓練時間也就成倍的增加了。

難道就沒有別的門道嗎?

of course有!運用簡單的目標檢測演算法,將前景所在的矩形框提取(crop)出來,將crop之後的圖片作為input,這樣就相當於去掉一些無用的背景。

效果有所提升嗎?

當然沒有!

為什麼?

我以為啊(你以為你以為的就是你以為的啊)

我想:對比下crop前後的圖像(下圖為crop之後的圖片)就應該知道了。

crop之前,前景都位於圖片的中央,網路其實只需要關注圖像中部就可以了。而crop之後,前景的位置是不固定的,這時候網路就要關注圖像的各個方位,也就是對網路提出了更高的要求。而這裡只使用了u-net,所以效果較差。

還是老老實實用原圖作為輸入吧(心痛)

batch size太小?

雖說濃縮的都是精華,但是精華是需要花時間滴。既然batch size的小(比賽時,batch size=2)已成事實,那就讓它發揮小的價值。

隨機梯度下降法是每batch size個數據對參數進行一次更新,那麼keras有沒有辦法在n個batch size之後再對參數進行更新呢?

說有它就有!

小二,上菜——例子,keras討論區已經有人給出了相應的解釋。

這菜怎麼樣?

這菜好像不太合口。

為什麼?

分割問題輸入的是整張圖片,所以小batch size對結果影響不大。而對於其他問題,如分類識別問題,可能這道菜就很合口了。

看來它不是我的菜啊。

再去嘗嘗別的菜系……

「小batch size啊,你可以試試BatchRenormalization啊。」

不信啊,有圖為證:

你試了嗎?

試了啊

效果如何?

分數明顯提高了

為什麼可以提高呢?

可以去瞅瞅論文

看不懂?不怕,告訴你一個秘密:在小batch size時該方法較好,大batch size則不然,而且收斂速度還會變慢。

看來挑食的我終於找到了一道適合我的菜。

數據增強

數據增強不是你想做,想做就能做。還是要看測試集嘞,亂做數據增強可能會適得其反。

測試集和訓練集相似,所以只是做了簡單的數據增強:

  • 水平反轉
  • 對比度變換
  • 平移

還不夠,想要更多?不急,在上篇文章,聊了聊深度學習常用的數據增強

合適的數據增強,有利於提高模型的泛化能力,降低過擬合。

空洞卷積

為什麼要嘗試空洞卷積呢?

在圖像分割中,經過池化操作減小圖像尺寸,增大感受野。隨後用unsampling擴大圖像尺寸。但在減小在增大尺寸的過程中,有一些信息損失掉了,而空洞卷積就是不通過池化也能有較大的感受野,感知更多的信息。

還不懂?可以參閱論文

更重要的是,空洞卷積還不額外增加參數,這麼好的東西為啥子不嘗試呢?

而且,設置還很簡單,只需要在keras的卷積層中設置dilation_rate這個參數就可以了。

高高興興的完成了訓練和預測,等待勝利的果實時……上帝告訴你,小子,不要高興的太早。

提交時,文件不可讀!(來寫段程序,求下此時的心理陰影面積)

百思不得其解,還特意打開提交的csv文件,也是沒有發現任何異常。

終究還是竹籃打水一場空啊

帶權重的損失函數

所謂帶權重,就是讓前景的比重更大,這樣在理論上會得到更好的分割效果。

理論上是如此,可實際上呢?

實際上,在訓練集和驗證集都得到了更高的分數,但是在測試集上分數並沒有有所提升。

懷疑有點過擬合啊……

看來,加權重,還是要謹慎啊。

不同激活函數

對於激活函數,現在relu其實就足以(當然,這裡僅限於CNN網路,RNN用的是tanh)。

但是有更好的時候,為啥不去嘗試呢?

呃,有道理,話粗理不粗。試試更高級的激活函數:elu。

嗯……不錯,效果提升了。

趁熱打鐵,再試試更高級的激活函數?

上PRelu……

呀,上不去了

為啥?

OOM了。(嘆息心有餘而力不足啊)

不同的損失函數、不同的優化器

不同的優化器?不是每次訓練時候,設置不同優化器嗎?

僅僅是這樣嗎?非也。可以在訓練的前部分使用一個損失函數(優化器),後半段使用一個新的損失函數(優化器)。

這樣,在理論上,不同的損失函數/優化器,會找到不同的最優點。換一個優化器,興許會找到比之前更好的點。

但是,這也僅僅是興許,還是要看具體問題的,比如這次比賽的任務,分數就沒有提升。但是在之前的圖像分類任務中,使用該法,效果就提升了。

具體問題具體分析哈(好冠冕堂皇的話啊),這也算是其中一個trick了,畢竟都是在煉丹啊。

模型集成

好菜永遠不怕晚。

引磚先拋玉。看看cs231n對模型集成的說明:

這麼多口味供你選擇,還怕吃不飽?

時間所剩不多(難道不是偷懶?)模型集成部分就將同一個網路不同初始化、不同優化器、不同損失函數的預測結果做了平均處理。

結果提升了?

那是自然,這樣還可以降低模型過擬合的風險嘞。

為啥不試試不同的模型嘞,比如稠密連接?不同的模型做集成,準確率豈不是會更高?

只嘆息,心有餘而力不足,奈何因為硬體條件的緣故,前面花費了太多的時間。


就這樣,第一次就給了top10%,無遺也無憾。再說,一次是二次他媽,期待這次的比賽可以取得更好的成績……

落幕……

(等等……說了這麼多,我們還不知道你是如何用代碼實現的。

想知道嗎?

當然想知道。而且是想不用做夢就可以知道的那種。

哈哈哈哈,城市套路深啊,代碼可詳見github,有問題還可私戳哈。揮手


推薦閱讀:

如何評價重磅論文《Stopping GAN Violence》?
resnet(殘差網路)的F(x)究竟長什麼樣子?
如何評價amd的Radeon開放計算平台直接將CUDA編譯代碼直接轉換過來。?
請問如何將深度學習Caffe做成一個動態庫,方便在其他應用程序中調用?

TAG:Kaggle | 深度学习DeepLearning | 机器学习 |