輪廓檢測論文解讀 | 總體嵌套邊緣檢測HED | CVPR | 2015


主題列表:juejin, github, smartblue, cyanosis, channing-cyan, fancy, hydrogen, condensed-night-purple, greenwillow, v-green, vue-pro, healer-readable

貢獻主題:https://github.com/xitu/juejin-markdown-themes

theme: juejin
highlight:

0 輪廓檢測

輪廓檢測,對我這樣的初學者而言,與語義分割相似。分割任務是什麼我就再也不贅述了,輪廓檢測則是完成這樣的一個任務:
vue

瞭解傳統圖像處理或者opencv的朋友應該都不難看出(想到),「Canny」輪廓提取算子,這個算子簡單的說就是對圖像的像素值的變化(梯度)進行檢測,而後梯度變化大的地方認定爲輪廓(上圖就是用Canny算子提取的效果)。固然,最近也是用深度學習的方法來作這種輪廓提取,本問介紹的HED就是這樣的一個深度學習提取邊框的辦法,下圖是HED提取小狗輪廓的結果圖。
python

1 論文概述

今天解讀一篇論文,網上已經有一些的解讀了,不過講解的並不細緻,讓我難以理解,直到看了官方代碼才理理順,因此這篇文章部分搬運,再加上我的補充git

總體來講,這個HED邊緣檢測模型,與Unet分割模型相似,再加上年份較老,因此復現價值不大,你們當擴展知識看看就得了。github

Unet咱們直接已經講解過了,用簡單的文字來簡單的回顧一下:字母U的左半邊,是不斷卷積池化層進行特徵抽取,而後獲得不一樣尺度的特徵圖,而後U的右半邊,經過轉置卷積進行上採樣,而後與下采樣過程當中的同尺度拼接作特徵融合,而後最終模型輸出一個與輸入圖像相同大小的預測結果。markdown

HED,Holistically-Nested Edge Detection這個模型,其中的亮點在我看來,是對Deep supervision的一種應用。Deep supervision這個概念相比讀者應該不陌生,在上上上一篇文章《Unet++》那個文章中我已經提到了,簡單的說就是一個模型有多個輸出的結構。框架

2 HED結構

來看下論文中給出的HED的結構圖:ide

這個圖可能比較抽象,我來大概講解一下:函數

  • 能夠看到的是整個過程只有一個卷積+池化的過程,Unet還有上採樣的過程,這是不一樣點;
  • 圖中的有5個馬的圖片,從大到小,從淺到深,紋理愈來愈少,這分別是通過了maxpool和卷積獲得的不一樣尺寸的輸出。從圖中能夠看到,這些輸出叫作side-output 1到side-output 5。
  • 圖中這五個特徵圖通過虛線,獲得了一個Y,這個Y是通過「weighted-fusion」獲得了,簡單的說就是,五個圖通過一個能夠訓練的權重參數,融合成了最終的輸出

結構不難理解,可是到這裏讀者確定心中仍有疑惑,看完下面的損失函數的構成就通透了。學習

3 損失函數

這個損失函數算是deep supervision比較常見的損失函數了,就是每個side-output輸出都是損失函數的一部分spa

總體來講,這個損失函數是有兩個部分:

  • side-output:這個就是上圖中五個不一樣尺度的預測結果,經過上採樣成原圖大小,而後和mask作交叉熵。由於有5個圖,因此損失是五個的和;
  • fusion:五個圖fusion出得Y,這個Y與ground truth的交叉熵;

因此論文中有這樣的損失函數:

我也沒注意W,w,h的含義,可是看起來確實是side和fusion兩部分損失函數。

這裏的Dist其實使用的就是交叉熵

這個side中,除去這個\(\beta\)無論,剩下的內容就是二值交叉熵,也許和你常見的那種形式不太同樣,可是是同樣的。給個提示:看這裏的\(\Sigma\)的下標

如今咱們對損失函數應該有了一個大體的感受了,可是仍然有兩個疑問:

  1. \(loss_{side}\)中的\(\beta\)是什麼?怎麼算?
  2. \(loss_{fuse}\)中的\(\hat{Y}_{fuse}\)怎麼獲得,換言之,如何融合5個side-output?

對於第一個問題\(\beta\)是一個平衡係數,

\[\beta = \frac{|Y^-|}{|Y|} \]

其中\(|Y|\)表示圖像的像素的數量,也就是widthxheight;\(|Y^-|\)表示這個圖片中,ground truth的像素的數量,相似與解決預測像素不平衡的一個手段。

假設一張圖片中ground truth的像素量少,那麼意味着,\(\beta\)的值小,那麼公式(2)中的第一項的權重輕,而第一項的sigma的下標是\(Y^+\),說明這個是計算非目標,也就是groud truth=0的損失,也就是背景的損失,數量不少,因此權重輕損失少。 這一點實在很差講明白,但願你們沒理解的多讀兩遍。

對於第二個問題,論文中給出了公式:

這個h應該是一個能夠訓練的參數,而後加和以後用sigma歸一化。

4 損失函數 TF

如今萬事俱備,官方提供了代碼,來看一下這個損失函數的TF版本:

def class_balance_sigmoid_cross_entropy(logits,label,name='cross_entropy_loss'):
    y = tf.cast(label,tf.float32)

    count_neg = tf.reduce_sum(1.-y)
    count_pos = tf.reduce_sum(y)
    beta = count_neg/(count_neg+count_pos)

    pos_weight = beta/(1-beta)
    cost = tf.nn.weighted_cross_entropy_with_logits(logits,y,pos_weight)
    cost = tf.reduce_mean(cost*(1-beta),name=name)
    return  cost

cost = class_balanced_sigmoid_cross_entropy(dsn_fuse, annotation_tensor) + \
       class_balanced_sigmoid_cross_entropy(dsn1, annotation_tensor) + \
       class_balanced_sigmoid_cross_entropy(dsn2, annotation_tensor) + \
       class_balanced_sigmoid_cross_entropy(dsn3, annotation_tensor) + \
       class_balanced_sigmoid_cross_entropy(dsn4, annotation_tensor) + \
       class_balanced_sigmoid_cross_entropy(dsn5, annotation_tensor)

可能有的朋友看不懂TF的寫法,不過大概能看懂把,細節不懂可是英文單詞老是沒問題的,總體來看,跟咱們上面講解的差很少把。

5 總結

這裏談一談我看了這個2015年的老前輩模型的收穫把:

  1. HED是一個邊緣檢測模型,可是使用的和Unet的框架有些相似。HED使用了deep supervision的方法,而Unet並無,這裏我忽然想到Unet++ 的結構,Unet++的思想徹底能夠沿着Unet+HED這條線路誕生。
  2. 咱們學到了一個deep supervision的損失函數的寫法;
  3. 咱們學到了一個單詞Holistically-nested。holistically 總體地,nest 嵌套

參考文章:

  1. https://zhuanlan.zhihu.com/p/35694372
  2. https://zhuanlan.zhihu.com/p/36660932
  3. https://www.zhihu.com/question/31864895
  4. https://arxiv.org/abs/1504.06375
  5. https://blog.csdn.net/u014779538/article/details/92765963
相關文章
相關標籤/搜索