FCN-for-semantic-image-segmentation 訓練過程的一些坑記錄


(1)首先,出現layer registry error,提示convolutional layer已經注冊過了。網上大多的問題是提示unknown layer,並非already registed,大概有兩種針對前一種的解決方法:1.鏈接的caffe靜態庫和動態庫的區別,應該鏈接動態庫?2.caffe的注冊機制的問題,添加頭文件,外部強制注冊?感覺不太像是我這個問題的答案。查了谷歌,好像是我裝了兩個版本的caffe導致caffe的路徑並未完全設置成其中某個版本的。於是修改.bashrc中所有和caffe有關的路徑,修改完后並沒有用。但是第二天重新開始訓的時候,神奇的可以了。。。。神奇的可以了。。。

(2)第二,訓練了幾萬循環,發現loss一直沒有變化。查了查,據說是反卷積層沒有初始化weight,查看了代碼,代碼中有python接口的訓練和command line接口的訓練,其中我用的一直是command line接口的(就是--solver=。。。。sh train.sh)這個接口沒有初始化weight。於是在net.py中deconvolutional layer加入了weight filler 和 bias filler參數(net.py是網絡結構的生成文件,修改了以后要執行一下python net.py)。而另一個python接口的代碼,已經初始化了合適的weight,用的是VGG16訓出來的caffemodel,然而沒有成功運行python 接口。於是先自己把command line接口里的weight,初始化了一個高斯隨機生成,先跑跑看。

(3)果不其然,loss逐漸減小,但是隨着訓練次數的增加,其收斂性不是很好,幾乎一直處在震盪狀態,從3.x左右降到1.x,之后便震盪起來。考慮到沒有按照作者的要求初始化合適的weight,也許原因在此,因此還是要繼續試試python接口。

 

-----------------

最新更新:

提前說一點,這次訓練的是alexnet-FCN。之前用VGG16的caffemodel是不對的,另外下了caffe-net的caffemodel(也就是alexnet)。

之前的訓練過程,loss始終振盪,這肯定不對。於是開始處理python接口,把python接口改好后,傳入caffenet的caffemodel,使用pre-trained weight,應該可以。這里遇到的問題是python接口執行報錯:shape不匹配,即pre-trained的參數數量和訓練的alexnet-FCN參數數量不匹配。

這里的解決辦法是:http://blog.csdn.net/zouyu1746430162/article/details/53787706。使用神奇的surgery.transplant函數,把兩個網絡的參數統一起來。

另外注意的一點就是一定要把訓練數據,validation數據,test數據的路徑搞清楚,改對。

於是就可以了,訓練,到了8000輪的時候,一個統計結果是mIU達到41.8%,和程序說明里的48%還有一點差距,不過loss已經明顯收斂,達到0.45左右。

至此,這個demo算是真正跑通了。不容易!

總結:

兩次weight沒有准確初始化:第一次,loss不變,是因為反卷積層(原alexnet並沒有這一層)參數沒有初始化,並且錯誤的拿VGG16的參數給alexnet初始化(在command line接口的solver里面)。第二次,loss振盪,也是錯誤的拿VGG16的參數給alexnet初始化的鍋。

shape 不匹配:即然是把原始alexnet改成了alexnetFCN,如果不用transplant,會在fc6層之后,出現參數數量的不一致,因為后者網絡的輸入尺寸和經典alexnet的輸入尺寸不一定一樣,所以報錯也是出現在fc6層的shape。

 

-------------

后續疑問:

(1)FCN在網絡結構和參數定了之后,能接受任意尺寸的輸入圖片嗎?如果可以,最后的輸出尺寸肯定不一致,那么如何統一結果?

(2)FCN的全連接轉卷積層是怎么轉的?這個可以看http://blog.csdn.net/zizi7/article/details/49506979。基本明白了。

(3)FCN是怎么拿pre-trained的參數作為初始weights的?如何保證參數數量匹配?多出的deconvolutional layer怎么辦?這個要看surgery.transplant函數找啟發。

(4)如何能給FCN的結果加上CRF來refine邊緣?能試着寫寫嗎?

-------------

對於疑問(1)的一些想法:之所以說FCN的網絡結構和參數確定了以后,可以接受任意尺寸的輸入,是基於和傳統最后是全連接層的alexnet等比較;對於傳統網絡(最后是全連接層),一旦輸入尺寸有變化,則到達全連接層的前一個卷積層的輸出尺寸,必然會隨着改變,這個尺寸一改變,全連接的邊的數量就改變,總的訓練權值數量就改變,這樣,既定的權值數量就變化了。然而一旦網絡確定,這個權值數量在整個訓練過程是不能變的,因此才說傳統網絡有這個缺陷。

對於FCN,所有的權值參數,都是基於卷積核的參數,下一層是由卷積核作用於上一層產生,而非單純通過全連接相連。因此,只要每層的卷積核大小定了,在保證stride滿足條件的情況下,的確可以使網絡接收任何可能大小的輸入,也就是說整個訓練過程,總的權值數量是不變的。其結果的唯一區別也是最后的feature map大小不同。然而feature map是需要再進行deconv的,deconv又是基於卷積核的參數,最終通過crop,生成和原始圖像大小一致的結果,因此也不存在統一結果的問題,因為結果最終都是和原始輸入大小一致。

 

----------------

對於疑問(3),通過分析surgery_transplant函數,外加http://www.cnblogs.com/zjutzz/p/6185452.html這篇對於caffemodel文件的結構分析,可知,權重賦值只作用於新舊網絡中重合的層和相應參數,對於非重合的層及參數,簡單的drop。這也是為什么deconv層需要單獨初始化權值的原因,因為傳統alexnet是完全沒有deconv層的,新網絡里面這個層的參數就無從而來。但這也啟發了我fc6、fc7、以及score_fr這三層也是新層,其參數也沒有初始化,看來這一點之前訓練的時候是做的不對的。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM