最近須要用到FCN來分割一些物體,因此一直在苦苦學習中,光是跑FCN就用了挺久的時間,最重要的是在數據集的格式上。如今作一下總結,針對小白。若是有錯誤但願能及時指出。謝謝!html
我用的是caffe和fcn,caffe能夠從這裏得到git
git clone https://github.com/BVLC/caffe.git
caffe的安裝能夠根據個人另外一片博客深度學習ssd配置並在VGG模型上訓練本身的數據來安裝。github
fcn使用這個fcn.berkeleyvision.orgubuntu
git clone https://github.com/shelhamer/fcn.berkeleyvision.org.git
把fcn這個文件放在caffe目錄中就能夠了,如圖:網絡
如今準備用voc-fcn32s這個來訓練。先把預先須要的模型下載了。在voc-fcn32s/solve.py中能夠看到: app
因此我下載了一個vgg16的模型,地址:VGG_ILSVRC_16_layers。函數
這個是最重要的,大部分不成功的緣由都來自這裏。 在voc-fcn32/train.prototxt中: 在val.prototxt中 學習
能夠看到是使用sbd這個數據集進行訓練,使用voc的數據集進行測試。在這裏咱們只須要更換'../data/sbdd/dataset'和'../data/pascal/VOC2011'就能夠了。測試
**注意: **若是不想使用sdb那種存放數據格式的話,咱們可使用本身的數據格式。ui
打開voc_layers.py文件,能夠看到有兩個類,一個是處理voc數據集格式的,一個是處理sbd數據集格式的。 對於voc格式來講,目錄的大概結構是這樣的
VOC2011 |____JPEGImages |____SegmentationClass |____ImageSets |______Segmentation
a bb ccc
這些目錄結構能夠對應代碼中的:
# load indices for images and labels split_f = '{}/ImageSets/Segmentation/{}.txt'.format(self.voc_dir,self.split) self.indices = open(split_f, 'r').read().splitlines() self.idx = 0 ... ... ... def load_image(self, idx): im = Image.open('{}/JPEGImages/{}.jpg'.format(self.voc_dir, idx)) in_ = np.array(im, dtype=np.float32) in_ = in_[:,:,::-1] in_ -= self.mean in_ = in_.transpose((2,0,1)) return in_ def load_label(self, idx): im = Image.open('{}/SegmentationClass/{}.png'.format(self.voc_dir, idx)) label = np.array(im, dtype=np.uint8) label = label[np.newaxis, ...] return label
若是想要把sbd的數據集像voc的同樣簡單的話能夠按照這個代碼把SBDDSegDataLayer類中的load_label函數改爲
def load_label(self, idx): im = Image.open('{}/SegmentationClass/{}.png'.format(self.sbdd_dir, idx)) label = np.array(im, dtype=np.uint8) label = label[np.newaxis, ...] return label
在load_image函數中的圖片路徑也須要改一改,還有加載txt的地方也要改一下。
所有改完後就能夠開始訓練了。若是爆出一下文件找不到問題,那就本身修改下路徑。 若是說surger,score找不到 那麼修改solve.py文件,把import sys提早,並加入路徑,以下:
import sys sys.path.append('/your-path-to-caffe/caffe/fcn.berkeleyvision.org') import caffe import surgery, score import numpy as np import os
而後開心的運行這個文件開始訓練:
loss有點大,先觀望一下,若是有錯誤我會及時更新。
後繼 發現loss一直很到,直到結束依舊這樣。
網上查了下緣由,是說deconvolution layer沒有初始化什麼的,要加入weight filler 和bias filler,http://www.cnblogs.com/lvlvlvlvlv/p/6353637.html。 fcn中有提示說若是輸出或者參數是0的話,能夠加個surgery.transplant()
。
Why are all the outputs/gradients/parameters zero?: This is almost universally due to not initializing the weights as needed. To reproduce our FCN training, or train your own FCNs, it is crucial to transplant the weights from the corresponding ILSVRC net such as VGG16. The included surgery.transplant() method can help with this.
而後這個帖子 中發現使用規則
base_net = caffe.Net('vgg16.prototxt', 'vgg16.caffemodel', caffe.TEST) surgery.transplant(solver.net, base_net) del base_net
具體實現能夠參考這個帖子,對於處理voc-fcn寫的很詳細。參照這個改完後200次迭代loss就降低了一半。
圖像分割實驗:FCN數據集製做,網絡模型定義,網絡訓練(提供數據集和模型文件,以供參考)
FCN-for-semantic-image-segmentation 訓練過程的一些坑記錄