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 | 机器学习 |