1. 程式人生 > >影象語義分割學習筆記~心得

影象語義分割學習筆記~心得

影象語義分割(Image sematic segmentation)學習了將近一年,日常學習中遇到的問題,都喜歡記錄到有道雲筆記裡,一年下來,列表裡全是yyyy-mm-dd的筆記名。趁著這段時間空閒整理下,也方便共享和志同道合的小夥伴交流。由於基礎不好,加上本人是一枚“較真”的小碩,因此,多數筆記均是關於細節性,當然更多的可以給入門的同胞一些借鑑,大牛們可以繞道~

1.論文

前提:當然需要深度學習的一些基礎知識啦~可以從UFLDL開始。
對於準備入門的小夥伴,建議從具體的一篇paper開始,有兩條思路:

1、從最基礎的開始,比如FCN《Fully Convolutional Networks for Semantic Segmentation》,後期的很多論文都是在這個基礎上進行改進的,在整體瞭解pixel-level,end to end的是怎樣實現的後,再看後期改進的論文比如:DeepLab-CRF 、CRFasRNN 等,可以參考

多篇用DL做Semantic Segmentation的文章總結 【雙手合十感謝博主!(•̀∀•́)棒】

2、從最新的論文開始,然後根據論文中的參考文獻追溯以前的論文,哪一點不理解就去看哪一篇論文,引用我導師經常說的一句話“順藤摸瓜,早晚能搞透徹”。

以下是在看論文的時候幾點建議:
1、明白論文的創新點所在,這點對所有的科研論文都適用;
2、分析清楚網路結構,可以藉助Quick Start實現,可以通過手動畫圖,來看自己是否理解的透徹;
3、各種型別層的具體運算是如何實現的,引數配置,寫法;
4、看FCN的時候,弄明白論文最後的幾個分割評估指標mean IU等。否則在以後的實驗中,看著終端刷刷的資料,卻不知道哪個是你想要的。明白目標很重要。
5、做好筆記、做好筆記、做好筆記!重要的事情說三遍,在總結的的過程中,結合自己的課題會激發自己的思維,總結多了,會發現牛人是怎麼去找創新點的,就會有點靈感了。
另外自己一點點感悟,適當的結合下傳統影象處理方法,不知道指引的方向是否妥當,總感覺傳統的影象處理方法才是本。(灬°ω°灬)

2、實驗

 千萬不要以為有了思路後再去做實驗,紙上談兵永遠不靠譜,做實驗的過程也會激發自己的思維,但是也不要拿到一個論文就迫不及待的去實現,畢竟需要時間,在結合自己的課題覺得有所幫助後,再去實驗,從實驗總髮現問題,然後改進。(o゜▽゜)o
[BINGO!]做筆記,做筆記,做筆記!總結真的很重要!

 對於基礎比較弱的同志,往往會在試驗的時候懊悔自己程式設計程式碼能力太渣,於是乎~掉頭專門去學習基礎語法比如Python,matlab,真的不要這樣,用的時候不會就去查,及時的解決問題才是關鍵的。專門去學習需要有計劃,有系統的時間安排,千萬不要頭腦一熱就去學習。另外大家會在選擇python和matlab之間動搖,建議Python。

 遇見問題的第一時間是想辦法百度谷歌自己找辦法解決,而不是截圖貼出來問別人,畢竟授人魚不如授之以漁,所以簡單的自己解決,有深度的可以拿出來探討一下。

哈哈~~~~~~是不是有點偏題了。本是想把自己的學習筆記總結一下的。但是這些東西也是蠻重要的喲!

—————————————————————–不知所云分割線—————————————————————————-

本喵去吃飯了,回來繼續敲…(ΦωΦ)

好了,今天520,學校食堂的飯竟然買一送一,吃飽飽回來繼續咯(✪ω✪)

—————————————————————–不知所云分割線—————————————————————————-
以下為FCN實驗中遇到的瑣碎的小問題(歡迎大家拍磚指正):

2、FCN作者給出的開原始碼中網路結構中資料層是Python型別的,檔案voc_layer.py中作者寫的類VOCSegDataLayer、SBDDSegDataLayer實現了接受圖片和標籤的輸入。
從網路結構看起

train.prototxt
layer {
  name: "data"
  type: "Python"
  top: "data"
  top: "label"
  python_param {
    module: "voc_layers" 
    layer: "VOCSegDataLayer"
    param_str: "{\'voc_dir\': \'/home/caffe-master/fcn_example/voc\', \'seed\': 1337, \'split\': \'train\', \'mean\': (181.731, 178.280, 177.170)}"
  }
}

module:為你自己的資料接受檔名稱,作者為voc_layers.py
layer:voc_layers.py中選擇接收資料定義的類,有VOCSegDataLayer、SBDDSegDataLayer兩種
param_str中是鍵值對的方式出現的,其中voc_dir對應的是資料集的路徑,split指明是訓練資料還是驗證(train,val),mean是資料集在RGB三個通道的均值。

再看voc_layers.py

由於我只用了VOCSegDataLayer,因此把另外一個class直接刪掉了。

class VOCSegDataLayer(caffe.Layer):
          ...
        # load indices for images and labels
        # 這裡的{self.voc_dir}/ImageSets/{self.split}.txt是讀取image和label時用到的路徑,其中voc_dir是train.prototxt中資料集路徑,split是指定訓練或者驗證資料集,train.txt或者val.txt.
        split_f  = '{}/ImageSets/{}.txt'.format(self.voc_dir,
                self.split)
        self.indices = open(split_f, 'r').read().splitlines()
        self.idx = 0

   ...

# 讀入的時候是影象,轉換成神經網路可以接受的blob,
    def reshape(self, bottom, top):
        # load image + label image pair
        self.data = self.load_image(self.indices[self.idx])
        self.label = self.load_label(self.indices[self.idx])

        # reshape tops to fit (leading 1 is for batch dimension)
        # 這裡的top[0]/top[0]分別為影象和標籤,reshape(1,..)中的1位batchsize,這裡的batchsize自己可以修改,只要視訊記憶體允許,當然是越大越好啦~
        top[0].reshape(1, *self.data.shape)
        top[1].reshape(1, *self.label.shape)
   ...
       #讀入image
    def load_image(self, idx):
       ...

    def load_label(self, idx):
       ....

程式碼中load_image中對影象進行格式轉換的具體每一步的意義可以參考薛的筆記
遇到no module named voc_layer。這個問題之前遇到過,將voc_layers.py檔案拷貝到voc-fcn8s資料夾下即可解決。

3、[Caffe]: Check failed: ShapeEquals(proto) shape mismatch (reshape not set)
原因:是因為用自己的資料進行fine-tune的時候,沒有更改網路各層引數的名字,導致載入caffemodel的時候載入了pre-train的引數,從而導致引數和資料不匹配。 解決辦法:http://www.it610.com/article/5029969.htm

4、訓練方式:python solve.py >& fcn.log &
其中‘>&’表示所有的標準輸出(stdout)和標準錯誤輸出(stderr)都將被重定向,fcn.log為重定向後log儲存的檔案,最後的&表示將命令放入後臺執行。
為了觀察是否正常執行,可以在執行階段,使用’tail -f fcn.log‘連續觀測log檔案的更新,退出請使用Ctrl+C

不要用caffe train –solver=xxx這種方式來跑程式碼,說是會導致後邊的deconvolution層沒有辦法初始化,會造成引數都為0,從而導致loss一直保持很大的數值不變動 ,所以如果loss的數值不變的情況下,。請改用sovle.py檔案來呼叫caffe訓練,裡邊會有一些初始化這些引數的過程。

寶寶沒有午休,有些累了,回更………………..(бвб))zzz

—————————————————————–課間操分割線—————————————————————————-

6、通過訓練曲線,可以評估當前訓練狀態:

  • train loss不斷下降,test loss不斷下降,說明網路仍在認真的學習
  • train loss 不斷下降,test loss 區域不變,說明網路過擬合
  • train loss趨於不變,test loss趨於不變,說明學習遇到瓶頸,需減小學習速率或批量資料尺寸
  • train loss趨於不變,test loss不斷下降,說明資料集100%有問題
  • train loss不斷上升,test loss不斷上升(最終變為NAN),可能是網路結構設計不當,訓練超引數設定不當,程式bug等某個問題引起的,需要進一步定位。

附上Matlab程式碼用來畫訓練曲線:

clear;
clc;
close all;
% 這個引數用來指定 Caffe 執行 log 檔案
% 生成 log 檔案方法:./examples/cifar10/train_quick.sh  >& cifar.log&
train_log_file = 'cifar.log';
% 這個引數相當於 solver.prototxt 中的 display 值
train_interval = 100;
% 這個引數相當於 solver.prototxt 中的test_interval 值
test_interval = 500;


[~, string_output] = dos(['cat ', train_log_file, ' | grep ''Train net output #0'' | awk ''{print $11}''']);
% fid = fopen('matlab_train_loss', 'r');
% train_loss = fscanf(fid, '%f\n');
% fclose(fid);
train_loss = str2num(string_output);
n = 1:length(train_loss);
idx_train = (n - 1) * train_interval;

% fid = fopen('matlab_test_loss', 'r');
% test_loss = fscanf(fid, '%f\n');
% fclose(fid);
[~, string_output] = dos(['cat ', train_log_file, ' | grep ''Test net output #1'' | awk ''{print $11}''']);
test_loss = str2num(string_output);
m = 1:length(test_loss);
idx_test = (m - 1) * test_interval;
figure;plot(idx_train, train_loss);
hold on;
plot(idx_test, test_loss);

grid on;
legend('Train Loss', 'Test Loss');
xlabel('iterations');
ylabel('loss');
title(' Train & Test Loss Curve');