caffe下用FCN做圖像分割,如何製作訓練集?

新人求指導!

caffe做圖像分類,我知道是用準備好的label中是分類標號的數字和對應圖像進行生成lmdb;但是做圖像分割,label中好像得是 map. 網上其他地方沒有找到合適的教程,所以對這一問題沒有概念,希望有朋友可以指點一下,謝謝!


鑒於有太多人詢問具體細節, 末尾更新了一下

----------

原答案:

直接調用GitHub - shelhamer/fcn.berkeleyvision.org: Fully Convolutional Networks for Semantic Segmentation by Jonathan Long*, Evan Shelhamer*, and Trevor Darrell. CVPR 2015.源代碼啊,走python layer。

用net.py生成train和test的prototxt,根據自己的數據調整輸出層的參數,不要手動設置prototxt。

網路數據輸入參考voc_layers.py調入自己的數據,寫自己的python layer,可以用h5py,也可以用任何能用python處理的數據格式,直接對口到input和label。

考慮到FCN這篇文章對deconv和upsampling的特殊處理(線性初始化,learning rate 等於0)。建議不要用命令行載入lmdb的方法。

具體就看上面github鏈接和論文原文吧。

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

更新:

voc-fcn32s為例shelhamer/fcn.berkeleyvision.org

net.py是生成prototxt用的

def fcn(split):

n = caffe.NetSpec()

pydata_params = dict(split=split, mean=(104.00699, 116.66877, 122.67892),

seed=1337)

if split == "train":

pydata_params["sbdd_dir"] = "../data/sbdd/dataset"

pylayer = "SBDDSegDataLayer"

else:

pydata_params["voc_dir"] = "../data/pascal/VOC2011"

pylayer = "VOCSegDataLayer"

n.data, n.label = L.Python(module="voc_layers", layer=pylayer,

ntop=2, param_str=str(pydata_params))

這段最後說的就是數據輸入部分,網路的第一層,data和label來自一個python layer,這個python layer有四個參數,一個module叫voc_layers, 一個layer叫"SBDDSegDataLayer",一個ntop表示這層輸出兩個blob(data 和 label),還有一個parame_str就是把上面那些地址,mean值等等以str的形式傳參給輸入層去解析。

翻譯過來就是來自一個voc_layers.py的文件,裡面有一個類叫SBDDSegDataLayer。這個voc_layers.py的文件就在根目錄下,打開就可看到裡面有幾個特定的函數。包括set_up,load_imageload_label,然後就可以到caffe是如何一步一步讀取原始數據文件的。

  • set_up 就是處理一下mean值等等一些初始化工作
  • load image 和 load label就是從自己的文件里讀取這兩個數據
  • 輸入層不用定義backward,沒有梯度計算
  • forward記得要更新下一次迭代的數據index。

很多人問mat文件是怎麼生成的那個mat也在這個文件里可以看到,是voc保存label的矩陣形式,應該是用matlab生成的。voc用mat不代表我們必須用mat,可以用任何形式的文件在對應自己定義的python layer里自己定義load_image和load_label的形式就好了。

最後,net.py里的loss層是SoftmaxWithLoss,這個默認如果你要分五類的話,你的標記就得是0,1,2,3,4。voc數據集一共20類,加背景是21類,所以label文件就得是0-20。如果你有一些背景部分不想用來參與loss的計算,這裡提供一個ignore_label的參數,可以把背景標記成255,然後這個參數設置成255,之後所有被標記為255的點雖然參與了forward計算,但是不會參與loss的計算,也就不會有反向傳播的效果。


有兩種方法:

1)可製作兩個lmdb文件,一個Data項是原始圖像,Label可為0,另一個Data項為分割後的標註圖像,Label為0。使用中caffe是支持多個lmdb輸入的。

2)將原始圖像(如3通道),標註圖像(1通道),合在一起成4通道,然後寫在一個lmdb中,然後導入後使用Slice層將其切開。這種方法就不能直接使用現有的convert_imageset來轉換了,可參考其實現自己寫一下。


看到一直沒什麼人答,索性自己答一下吧,畢竟當初也是在鐵膽火車俠那個答案下受到啟發的。

強烈建議按照voc2012的數據集形式來設置自己的數據集,這裡需要注意的一點是voc數據的標籤雖然看著是有顏色的,但其實是單通道圖像,也就是說你自己的圖像標籤也一定要是單通道的,這是個比較大的坑!

然後在voc-8s那的net.py下把路徑改了,把輸出層的輸出改成自己的類別數(把所有的21都改了),然後把對應的層名字改掉,運行net.py生成protxt文件。

然後把solve.py做一下相應的改動,可以把微調模型改為voc-8.caffemodel(具體名字記不清了),運行solve.py進行訓練,用這個訓練的時候可能測試會有點問題,不過只要訓練出模型就行,可以借鑒infer.py來測試,記得改deploy文件。

手機碼字就先寫這麼多吧,等考完試再寫個詳細點的博客……


用過一個同學改造的層,input和label都直接是圖片,方便簡單,親測可用,需要就取走吧

https://github.com/qichenaj/caffe_dev

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

不常上知乎,抱歉私信沒及時回復,fcn的example已經上傳到github


如果是linux系統的話建議使用nvidia的digits。這是一個基於caffe和torch的界面。可以很方便的建立數據和網路。例如建立fcn所需的資料庫時,只需要將圖像和文件分別存在兩個文件夾中,然後將這兩個路徑填寫在界面的指定位置中,digits就可以自己生成所需的數據文件。


https://simon32.github.io/2018/01/08/caffe%20lmdb/simon32.github.io

自己總結了一下放在了博客中希望可以幫到你


方法有多種

(1)本人常用的一種做法是,由於caffe可以有多個輸入(參見caffe tutorial,google即可),所以使用一個輸入來輸入原圖,另一個輸入輸入ground truth(分割圖),這樣就可以進行分割了。兩個輸入在loss層匯合,計算softmax loss,就可以實現反向傳播了。

(2)使用Slice層也是一種做法,這種方法個人感覺並不常用

(3)使用類似FCN(caffe model zoo)中的Python層是一種很常用的方法,這種方法自己寫python層,使用起來很靈活,功能很強大,是caffe可擴展性的一大表現.


您好!想問下,您知道如何生成label的圖片用於semantic labeling或者semantic segmentation嗎?


剛在自己數據集上訓練了 可私信啊


推薦閱讀:

怎樣在windows下輸出訓練caffemodel的log日誌並畫出accuracy和loss曲線?
caffe 每個樣本對應多個label?
caffe的finetuning是如何更新網路參數的?
caffe如何進行數據集測試??
caffe怎麼test訓練好的model?

TAG:圖片處理 | Caffe深度學習框架 |