深入理解anchor
在博客SSD原理解讀-從入門到精通中提到了anchor作用:通過anchor設置每一層實際響應的區域,使得某一層對特定大小的目標響應。很多人肯定有這么一個疑問:那anchor到底可以設置到多大呢?,本文嘗試對anchor的大小進行了一系列的探索,同時借鑒了SSD的anchor機制,提出了MTCNN中的anchor機制,能夠顯著提高MTCNN的精度。
文章目錄
- 理論感受野大小的計算
- 經典SSD網絡anchor的設置
- anchor大小的探索
- AP
- loss
- 實驗分析
- 滑動窗口,感受野與anchor的關系
- MTCNN中的anchor機制
- MTCNN訓練機制的問題
- MTCNN中的anchor機制
- 實驗結果與分析
- 結束語
理論感受野大小的計算
由于本文在討論anchor大小的時候,都是與理論感受野大小相關的,這里有必要說一下理論感受野大小的計算。關于理論感受野大小的計算,有一篇很好的文章:A guide to receptive field arithmetic for Convolutional Neural Networks,國內也有這篇文章的翻譯,在網上都可以找到。關于這篇文章就不展開說了。這里直接給出我用的計算感受野大小的python代碼,直接修改網絡參數就可以計算理論感受野大小,非常方便。
def outFromIn(isz, net, layernum):totstride = 1insize = iszfor layer in range(layernum):fsize, stride, pad = net[layer]outsize = (insize - fsize + 2*pad) / stride + 1insize = outsizetotstride = totstride * stridereturn outsize, totstridedef inFromOut(net, layernum):RF = 1for layer in reversed(range(layernum)):fsize, stride, pad = net[layer]RF = ((RF -1)* stride) + fsizereturn RF# 計算感受野和步長,[11,4,0]:[卷積核大小,步長,pad] def ComputeReceptiveFieldAndStride():net_struct = {'PNet': {'net':[[3,2,0],[2,2,0],[3,1,0],[3,2,0],[1,1,0]],'name':['conv1','pool1','conv2','conv3','conv4-3']}}imsize = 512print ("layer output sizes given image = %dx%d" % (imsize, imsize))for net in net_struct.keys():print ('************net structrue name is %s**************'% net)for i in range(len(net_struct[net]['net'])):p = outFromIn(imsize,net_struct[net]['net'], i+1)rf = inFromOut(net_struct[net]['net'], i+1)print ("Layer Name = %s, Output size = %3d, Stride = %3d, RF size = %3d" % (net_struct[net]['name'][i], p[0], p[1], rf))運行結果如下
除了通過公式計算,還有一種更加方便的可以用于手工計算的方式。這里給出幾條規則:
具體在計算的時候,采用bottom-up的方式。
要計算哪一層的感受野,就將該層的輸出設置為1,然后依次向前計算,比如下圖中的網絡結構中,要計算pool3的感受野,將pool3的輸出設置為1,就可以得到conv1的輸入大小為30x30,也就是P3的感受野大小為30。
按照這個算法,我們可以算出SSD300中conv4-3的理論感受野:
r =(((1 +2 +2+2+2 )x2 +2+2+2 )x2 +2+2 )x2 +2+2 = 108
注意:由于conv4-3后面接了3x3的卷積核做分類和回歸,所以在計算感受野大小的時候,需要將用于分類和回歸的3x3的卷積核也考慮進去。
經典SSD網絡anchor的設置
下面我們來看一下經典網絡中anchor大小是如何設置的
其中( )中的數字表示:anchor/理論感受野,下文中使用該數值表示anchor的大小。
注:SFD:Single Shot Scale-invariant Face Detector
于老師開源的檢測器:ShiqiYu/libfacedetection中anchor的設置
觀察SSD,SFD,YuFace,RPN中的anchor設計,我們可以看出anchor的大小基本在[0.1,0.7]之間。RPN網絡比較特別,anchor的大小超出了感受野大小。
anchor大小的探索
下面我做了一系列實驗探索anchor大小的范圍,分別在數據集A和數據集B上,使用SFD_VGG16和SSD_YuFaceNet兩個模型,所有層的anchor大小分別設計為0.1~0.9,觀察模型的AP和loss大小。
注:SFD_VGG16和SSD_YuFaceNet分別使用的是SFD開源的網絡和ShiqiYu/libfacedetection開源的網絡
AP
數據集A:
數據集B:
loss
數據集A:
數據集B:
實驗分析
通過對經典網絡的分析,以及實驗的結果,可以觀察到以下現象:
注:由于目前實驗數據還不夠充分,這個范圍可能并不準確,歡迎大家留言討論。
滑動窗口,感受野與anchor的關系
首先區分一下這幾個比較容易混淆的概念:
滑動窗口大小和理論感受野是一個網絡的固有屬性,一旦網絡結構確定了,這兩個參數就確定了,有效感受野是可以通過訓練改變的,anchor是通過人工手動設置的。理論感受野,有效感受野,滑動窗口是對齊的, anchor設置過程中也要與感受野對齊,否則會影響檢測效果。檢測層上每個像素點都會對應一個理論感受野,滑動窗口以及anchor。
MTCNN中的anchor機制
MTCNN訓練機制的問題
熟悉MTCNN的朋友應該都知道,訓練MTCNN的時候需要事先生成三類樣本:positive,part,negative.這三類樣本是根據groundtruth的IOU來區分的,原論文中的設置是IOU<0.3的為negative,IOU>0.65的為positve,0.4<IOU<0.65的為part。
上圖中生成的positive樣本為,圖中紅色框為groundtruth,藍色框為候選框
其中回歸任務回歸的就是兩者之間的offset
回歸的4個偏移量(公式不唯一):
(x1?x1’)/w(x1-x1’)/w(x1?x1’)/w
(y1?y1’)/h(y1-y1’)/h(y1?y1’)/h
(x2?x2’)/w(x2-x2’)/w(x2?x2’)/w
(y2?y2’)/h(y2-y2’)/h(y2?y2’)/h
對于小目標或者類似頭肩這種目標,會出現一些問題
生成的positive樣本如下:
基本上是一塊黑色區域,沒有太多有效信息。
對于小目標:
生成的positive是
這樣的圖像,這些圖像是非常不利于訓練的,而且MTCNN在訓練的時候輸入分辨率都比較小(比如12,24,48),將這些生成的圖像resize到12,24或者48之后會導致有效信息更少,為了解決這個問題,我們需要包含目標更多的上下文信息,會更加容易識別。
MTCNN中的anchor機制
借鑒SSD中anchor的思想,提出了MTCNN中的anchor
SSD在訓練過程中通過anchor與groundtruth的匹配來確定每一個anchor的類別,具體匹配過程:計算與每個anchor的IOU最大(>閾值)的那個groundtruth,如果找到了,那么該anchor就匹配到了這個groundtruth,該anchor就是positive樣本,anchor的類別就是該groundtruth的類別,回歸的offset就是anchor與groundtruth之間的偏移量。由于SSD的anchor通常都比理論感受野小,所以SSD會包含較多的上下文信息,如下圖所示。
聯想到MTCNN,在生成訓練樣本的時候,我們可以將候選框當成anchor,生成positive的過程就是SSD中的匹配過程,由于需要包含更多上下文信息,最后會對anchor進行擴邊生成最后的訓練樣本 。
紅色區域就是anchor也就是生成的positive樣本,整個黑色區域就是對anchor做擴邊后生成的訓練樣本,可以看到包含了更多的上下文信息。
實驗結果與分析
在多種數據集上對anchor機制進行了實驗。
數據集1:
數據集2:
從實驗結果我們可以看出,anchor機制可以顯著提高檢測器的精度。
結束語
關于anchor其實還有很多地方值得探索,本文只是總結了一下最近工作中對anchor的一些最新的認識,就當拋磚引玉,大家如果有關于anchor更好的解讀歡迎一起討論。
非常感謝您的閱讀,如果您覺得這篇文章對您有幫助,歡迎掃碼進行贊賞。
總結
以上是生活随笔為你收集整理的深入理解anchor的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: sqlServer服务器名称
- 下一篇: 需要类型转换时请为模板定义非成员函数——