基於Mutil-Scale CNN的圖片語義分割、法向量估計

基於Mutil-Scale CNN的圖片語義分割、法向量估計

原文地址http://blog.csdn.net/hjimce/article/details/50443995

作者:hjimce

一、相關理論

   2016年的第一篇博文,新的奮鬥征程。本篇博文主要講解2015年ICCV的一篇paper:《Predicting Depth, Surface Normals and Semantic Labels with a Common Multi-Scale Convolutional Architecture》,文獻的主頁:http://www.cs.nyu.edu/~deigen/dnl/一開始看到這篇文獻的名字,有點被嚇到了,我以爲作者要採用mutil-task多任務特徵學習的方法,用於估計單幅圖像的深度、法向量、語義分割三個任務。還以爲paper即將採用跟文獻《Facial Landmark Detection by Deep Multi-task Learning》一樣的思想,進行提高精度,最後仔細通讀全文才知道,其實這三個任務是獨立的,不是傳說中的“多任務特徵學習”,終於鬆了一口氣(因爲之前看《機器學習及其應用2015》這本書的第一章的時候,講到了“魯邦多任務特徵學習”,覺得好難,看不懂,所以就對多任務特徵學習有點害怕)。這篇paper的思想其實很簡單,說白了就是在文獻《Depth map prediction from a single image using a multi-scale deep network》的基礎上,改一改,精度稍微提高了一點點,就這樣。

   基於多尺度的語義分割在FCN網絡中,早有耳聞,所以如果學過paper:《Fully Convolutional Networks for Semantic Segmentation 》 ,在學習這篇文獻的網絡架構時會比較輕鬆。對於三維法向量估計,這個需要懂一點點三維圖像學的知識,一般只有搞到三維圖像的人才會去在意這篇paper的法向量估計算法,不然二維視覺很少用到,因爲我以前曾經搞過三維,所以對於三維的一些知識比較瞭解。還有另外一個是深度估計,深度估計基本上沒變,都是繼承了文獻《Depth map prediction from a single image using a multi-scale deep network》的方法。所以總得來說我感覺這篇文獻的創新點不是很明顯,新的知識點很少,我們學起來也會比較輕鬆。

學習建議:要學習這篇paper,我個人感覺還是先要學《Depth map prediction from a single image using a multi-scale deep network》,學了這篇文獻,那麼接着就非常容易了。

二、網絡架構

網格結構方面與文獻《Depth map prediction from a single image using a multi-scale deep network》基本相似,可以說是在這篇paper的基礎上做的修改,區別在於:

(1)採用了更深層的網絡;

(2)增加了第三個尺度的網絡,使得我們的輸出是更高分辨率的圖片(之前的paper輸出大小是55*77,現在最後網絡的輸出大小是109*147);

(3)與之前的思路有點不同,之前採用的方式是,先訓練scale1,訓練完成後,以scale 1的輸出作爲scale 2的輸入。現在所採用的方式是:scale 1和scale 2聯合訓練,最後固定這兩個尺度CNN,在訓練scale 3。

我們先大體看一下網絡的總體架構:


絡分成三個尺度的CNN模型,scale 1的輸入是原始圖片;scale 2 的輸入是原始圖片和scale 1的輸出;同樣,scale 3 的輸入是scale 2的輸出和原始圖片。可能網絡的結構,看起來有點龐大,其實不然,這個相比於前面的博文《基於DCNN的人臉特徵點定位》簡單多了。

 1、Scale 1 網絡架構

網絡的輸入:原始圖片,輸入圖片大小爲 三通道彩色圖片;

網絡的輸出:19*14大小的圖片;

下面是網絡第一個尺度的相關參數,這個和文獻《Depth map prediction from a single image using a multi-scale deep network》一樣,基本上是Alexnet。


本尺度的CNN不在細講,如果不知道怎麼架構,可以好好閱讀文獻:《Depth map prediction from a single image using a multi-scale deep network》

2、Scale 2 網絡架構

(1)第一層網絡

輸入:原始圖片304*228(輸入320*240後,訓練的時候,採用random crop到304*208),經過卷積後,得到74*55大小的圖片。相關參數如下:

[python] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. [conv_s2_1]  
  2. type = conv  
  3. load_key = fine_2  
  4. filter_shape = (96,3,9,9)  
  5. stride = 2  
  6. init_w = lambda shp: 0.001*np.random.randn(*shp)  
  7. init_b = 0.0  
  8. conv_mode = valid  
  9. weight_decay_w = 0.0001  
  10. learning_rate_scale = 0.001  
  11. [pool_s2_1]  
  12. type = maxpool  
  13. poolsize = (3,3)  
  14. poolstride = (2,2)  

也就是特徵圖個數爲96,卷積的stride大小爲2。池化採用重疊池化,池化stride大小爲2。這樣卷積步的stride=2,池化步的stride=2,圖片的大小就縮小爲原來的1/4(具體計算不再詳解,因爲這些計算是非常基礎的東西了)。

(2)第二層網絡輸入:除了第一層得到的特徵圖之外,還有scale 1的輸出(把scale1的輸出圖片由19*14,放大4倍,然後進行邊界處理,得到74*55的圖片)。

3、Scale 3 網絡結構

個人感覺多加了這個尺度的網絡,僅僅只是爲了獲得更高分辨率的輸出。

(1)第一層網絡與scale 2一樣,第一層網絡的輸入是原始圖片,然後進行卷積池化,因爲我們scale 3要得到更大分辨率的結果,於是作者就把池化的stride選擇爲1,具體代碼如下:

[python] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. [conv_s3_1]  
  2. type = conv  
  3. load_key = fine_3  
  4. filter_shape = (64,3,9,9)  
  5. stride = 2  
  6. init_w = lambda shp: 0.001*np.random.randn(*shp)  
  7. init_b = 0.0  
  8. conv_mode = valid  
  9. weight_decay_w = 0.0001  
  10. learning_rate_scale = 0.001  
  11.    
  12. [pool_s3_1]  
  13. type = maxpool  
  14. poolsize = (3,3)  
  15. poolstride = (1,1)  

這樣經過這一層的操作,我們可以得到147*109的圖片。

(2)第二層網絡輸入第一層的特徵圖,還有scale 2的輸出圖,在進行卷積池化。相關參數如下:

[python] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. [depths_conv_s3_2]  
  2. type = conv  
  3. load_key = fine_3  
  4. filter_shape = (64,64,5,5)  
  5. init_w = lambda shp: 0.01*np.random.randn(*shp)  
  6. init_b = 0.0  
  7. conv_mode = same  
  8. weight_decay_w = 0.0001  
  9. learning_rate_scale = 0.01  

(3)第三層網絡。後面都差不多,大同小異,具體就不在詳解了,看一下網絡的相關配置參數:

[python] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. [depths_conv_s3_3]  
  2. type = conv  
  3. load_key = fine_3  
  4. filter_shape = (64,64,5,5)  
  5. init_w = lambda shp: 0.01*np.random.randn(*shp)  
  6. init_b = 0.0  
  7. conv_mode = same  
  8. weight_decay_w = 0.0001  
  9. learning_rate_scale = 0.01  

(4)第四層網絡

[python] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. [depths_conv_s3_4]  
  2. type = conv  
  3. load_key = fine_3  
  4. filter_shape = (64,1,5,5)  
  5. transpose = True  
  6. init_w = lambda shp: 0.01*np.random.randn(*shp)  
  7. init_b = 0.0  
  8. conv_mode = same  
  9. weight_decay_w = 0.0001  
  10. learning_rate_scale = 0.001  

四、損失函數構建

我覺得文獻的提出算法,如何構造損失函數也是一大創新點,所以我們還是要好好閱讀對於深度、法向量、語義分割這些損失函數是怎麼構建的。

(1)深度估計損失函數

這個與之前的那篇paper的構造方法相同,也是採用作者所提出的縮放不變損失函數,同時後面又加了一項elementwise L2:

 

其中D和D*分別表示網絡深度預測值、實際的深度值。然後d=D-D*。

(2)法矢估計損失函數

因爲法向量是三維的,因此我們每層scale的輸出,就不應該是一個單通道圖片了,而應該改爲3通道,用於分別預測一個三維向量的(x,y,z)值。同時我們要知道法向量指的是長度爲1的歸一化向量,因此在輸出三維V向量後,我們還需要把它歸一化,然後接着才能定義計算損失函數:

 

因爲預測值N和真實值N*向量的模長都爲1,所以其實上面的損失函數說白了就是以兩個向量的角度差,作爲距離度量。

真實的法向量的獲取方法:可能是沒有訓練數據的原因,所以文獻法向量訓練數據的獲取方法,是通過每個像素點的深度值,獲得三維空間中每個像素點的位置,也就是相當於點雲。然後採用最小二乘平面擬合,擬合出每個點鄰域範圍內平面,以平面的法向量作爲每個像素點的法矢(這個因爲我之前搞過三維的重建、點雲處理,所以對於三維點雲法向量的求取會比較熟悉,如果沒有接觸過三維圖形學的,可以跳過不看,或者可以學一學我的博客: http://blog.csdn.net/hjimce/article/category/5570255 關於三維圖形學的知識,可以直接看點雲重建)

(3)語義分割損失函數

因爲語義分割,就相當於給每個像素點做分類,也就是相當於一個多分類問題,所以自然而然採用softmax,損失函數採用交叉熵:

 

其中:

 

這個是softmax的相關知識了,不熟悉的趕緊補一下。不然後面遇到CNN圖片分類,就要抓狂了,softmax是基礎知識。

五、網絡訓練

(1)訓練流程

訓練方法採用的都是隨機梯度下降法,首先我們訓練把scale 1和scale 2 聯合起來訓練,也就是說我們在訓練scale 2的時候,scale1的參數也是要更新的,這個與另外一篇paper:《Depth Map Prediction from a Single Image using a Multi-Scale Deep Network》的訓練方法不同。然後scale 3的訓練和前面兩個尺度的訓練是分開的,我們先訓練完了scale 1、scale 2,訓練完畢後,固定這兩個尺度的參數,然後繼續訓練scale 3(換一種說法就是訓練scale 3的時候,scale 1\2的參數是不更新的)。

(2)訓練參數

具體的訓練參數,還是參考作者給的代碼中的conf網絡配置文件,裏面可以看到每層的學習率,以及其它的一些相關參數。參數初始化:除了scale 1前面幾層卷積層是用了Alexnet訓練好的參數,作爲初始值。其它的全部採用隨機初始化的方法。Batch size大小選擇32。

參考文獻:

1、Predicting Depth, Surface Normals and Semantic Labels with a Common Multi-Scale Convolutional Architecture

2、http://www.cs.nyu.edu/~deigen/dnl/

3、《Depth map prediction from a single image using a multi-scale deep network》

**********************作者:hjimce   時間:2016.1.1  聯繫QQ:1393852684   地址:http://blog.csdn.net/hjimce   原創文章,轉載請保留原文地址、作者信息************

發佈了8 篇原創文章 · 獲贊 10 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章