SSD檢測幾個小細節

以前感受SSD很簡單,這兩天從頭至尾把論文和源碼都看了一下,發現以前不少細節都沒掌握。python

這篇文章只說一些以前遺漏的點,讀者閱讀有必定基礎ios

@算法

一. 拋磚引玉的Faster-RCNN

1.1 候選框的做用

以前看Fast-RCNN代碼對Selective Search的操做一直有很大的疑惑?網絡

圖1-1

爲何一張圖會分割成這樣大大小小的區域?分割後有啥意義呢?app

  • 第一個問題很簡單,使用了貪心算法圖論方面的知識,區域合併等算法。
  • 第二個問題到後來才明白,是深度學習的學習成本的問題。。。

圖1-2

看上圖的resnet核心模塊,就是下降了學習成本,使得網絡更容易學習ide

下面這張圖預測區域經過兩次平移到達目標區域函數

圖1-3

下面這張圖預測區域先經過放大再作兩次平移到達目標區域學習

圖1-4

下面這張圖經過多個預測區域對不一樣的目標進行預測spa

圖1-5

經過上面的三幅圖能夠發現,迴歸的方式須要付出不一樣的代價

固然代價越低越容易迴歸,能夠看我以前的文章EAST和改進的EAST,就是經過迴歸的代價不一樣,最後效果提高挺大的。

最後一幅圖,經過打不一樣的迴歸點(Anchor),比盲目的迴歸效果好不少

那麼咱們怎麼知道目標在哪?怎麼打候選框(Anchor)呢?

圖1-6

假設上圖是一個4 * 4feature map,咱們既然不知道實際目標在哪,那就以每一個像素爲中心生成不少個候選框

上面生成的候選框數量也就是4 * 4 * 2=32個

會不會以爲那麼多框進行迴歸效率很低?

首先那麼多框都是固定的,好比上圖的32個,迴歸的時候SSD也考慮到了這些,hard sample才須要迴歸,easy sample是不須要回歸的

1.2 下采樣問題

  • RoIPooling

圖1-7

img

這個比較簡單了,就是一個讓輸出對稱的pooling操做。

  • ROIAlign

圖1-8

這個也比較簡單,就是利用雙線性差值對中心的座標進行計算出來

二. SSD細節理解

2.1 六個LOSS

這是筆者沒看源代碼,比較糊塗的想法,問了其餘在跑ssd的人也沒回答出來。。。

圖2-1

筆者大概畫了一個上圖,這個問題很簡單,想不通就很麻煩。。。

  • 在六個feature迴歸六個圖信息
  • 六個信息映射到原圖大小
  • 六個原圖大小的信息合併成一個圖(一個圖6個通道,和一個圖RGB通道同樣)

2.2 Anchor生成細節

Anchor的特徵主要包括幾個方面:ratio(長寬比例)、scale(面積開根號,也就是正方形邊長)、step/stride(步長,也就是原圖和feature的比例)

  • ratio:固定的包括幾個{1,2,3,1/2,1/3},還有一個1是不一樣的面積scale
  • scale:經過不一樣的feature map計算出來的(由於不一樣的特徵圖確定得設置不一樣大小的scale
  • step/stride:兩個表示都是一個含義,不一樣的卷積核(步長、padding)生成的步長不一樣

必定要理解上面幾個參數的含義,具體公式的計算就很簡單了,讀者能夠本身跑一下源代碼

def default_prior_box():
    mean_layer = []
    for k,f in enumerate(Config.feature_map):
        mean = []
        for i,j in product(range(f),repeat=2):
            f_k = Config.image_size/Config.steps[k]#當前feature map 的大小(經過步數從新計算)
            #anchor中心點座標(cx / cy已經歸一化操做)
            cx = (j+0.5)/f_k
            cy = (i+0.5)/f_k

            s_k = Config.sk[k]/Config.image_size
            mean += [cx,cy,s_k,s_k]

            s_k_prime = sqrt(s_k * Config.sk[k+1]/Config.image_size)
            mean += [cx,cy,s_k_prime,s_k_prime]
            for ar in Config.aspect_ratios[k]:
                mean += [cx, cy, s_k * sqrt(ar), s_k/sqrt(ar)]
                mean += [cx, cy, s_k / sqrt(ar), s_k * sqrt(ar)]
        if Config.use_cuda:
            mean = torch.Tensor(mean).cuda().view(Config.feature_map[k], Config.feature_map[k], -1).contiguous()
        else:
            mean = torch.Tensor(mean).view( Config.feature_map[k],Config.feature_map[k],-1).contiguous()
        mean.clamp_(max=1, min=0)
        mean_layer.append(mean)

2.3 Encode&&Decode

疑點:剛開始看網上說的:

  1. prior box是:(中心X,中心Y,寬,高)
  2. 實際邊界是(中心X,中心Y,寬,高)
  3. 學習的參數是(中心X偏移,中心Y偏移,寬比例,高比例)

按照這個推理:
\[ l^{cx}= b^{cx} - d^{cx} \]

\[ l^{cy}= b^{cy} - d^{cy} \]

\[ l^{w}= b^{w} / d^{w} \]

\[ l^{h}= b^{h} / d^{h} \]

其中\(b\)表明實際框,\(d\)表明default box\(l\)表明迴歸參數

而實際的表達式以下所示:
\[ l^{cx}= (b^{cx} - d^{cx})/d^w \]

\[ l^{cx}= (b^{cx} - d^{cx})/d^h \]

\[ l^{w}= log(b^{w}/d^{w}) \]

\[ l^{h}= log(b^{h}/d^{h}) \]

筆者認爲無論迴歸什麼東西,只要是一種映射關係便可

定義完LOSS,神經網絡會幫咱們完成這種表達式的關係

因此這裏做者也是爲了方便,因此使用了除以d,又使用log函數

2.4 負樣本挖掘

有專門的論文會解釋這類事件,筆者這裏只關注SSD的作法

SSD生成8732prior box框,而實際的一張圖中目標只有幾個

圖2-2

有無數個預先設定的框,而實際和目標相交大於閾值的框不多

假設直接進行迴歸操做?

全部的框都進行迴歸=正樣本的框+負樣本的框

由於後者佔比很是大,LOSS基本由負樣本控制,最後的訓練的結果以下:

圖2-3

目標能檢測到,可是對於邊界的處理很是很差,由於細節基本由負樣本控制

SSD如何進行操做?

迴歸分爲兩個部分=位置迴歸+類別迴歸

  • 位置迴歸按照上述方式進行

  • 種類按照1 :3的方式進行

  1. 首先計算出種類的loss

  2. 把正樣本的loss置0(正樣本所有保留)
  3. 負樣本進行排序,按照3倍的正樣本保留(保留大的loss屬於hard sample)
  4. 最後正負樣本疊加

loss_c = utils.log_sum_exp(batch_conf) - batch_conf.gather(1, target_conf.view(-1, 1))

    loss_c = loss_c.view(batch_num, -1)
    # 將正樣本設定爲0
    loss_c[pos] = 0

    # 將剩下的負樣本排序,選出目標數量的負樣本
    _, loss_idx = loss_c.sort(1, descending=True)
    _, idx_rank = loss_idx.sort(1)

    num_pos = pos.long().sum(1, keepdim=True)
    num_neg = torch.clamp(3*num_pos, max=pos.size(1)-1)

    # 提取出正負樣本
    neg = idx_rank < num_neg.expand_as(idx_rank)
    pos_idx = pos.unsqueeze(2).expand_as(conf_data)
    neg_idx = neg.unsqueeze(2).expand_as(conf_data)

    conf_p = conf_data[(pos_idx+neg_idx).gt(0)].view(-1, Config.class_num)
    targets_weighted = target_conf[(pos+neg).gt(0)]
    loss_c = F.cross_entropy(conf_p, targets_weighted, size_average=False)

圖2-4

圖畫的很差,由於正好疊合就看不到效果了

參考文獻

https://arxiv.org/pdf/1512.02325.pdf

http://www.javashuo.com/article/p-eimmbhyo-bu.html

https://blog.csdn.net/u010167269/article/details/52563573

http://www.javashuo.com/article/p-mnvbeznb-hv.html

http://www.javashuo.com/article/p-nrkqcogz-x.html

https://blog.csdn.net/u010712012/article/details/86555814

https://deepsense.ai/satellite-images-semantic-segmentation-with-deep-learning/

https://www.jianshu.com/p/8b7d7036d715

侵權請告知刪除

相關文章
相關標籤/搜索