2016-02-23 5 views
8

Я читаю статью об использовании CNN (сверточной нейронной сети) для обнаружения объекта.Как рассчитать размер приемного поля?

Rich feature hierarchies for accurate object detection and semantic segmentation

Вот цитата о рецептивного поля:

The pool5 feature map is 6x6x256 = 9216 dimensional. Ignoring boundary effects, each pool5 unit has a receptive field of 195x195 pixels in the original 227x227 pixel input. A central pool5 unit has a nearly global view, 
while one near the edge has a smaller, clipped support. 

Мои вопросы:

  1. Что такое определение рецепторного поля?
  2. Как они вычисляют размер и местоположение восприимчивого поля?
  3. Как мы можем вычислить ограничивающий прямоугольник восприимчивого поля, используя кофе/пикаф?

ответ

5

1) Это размер области пикселей, которая влияет на выход последней свертки.

2) Для каждой операции свертки и объединения, вычислите размер выходного сигнала. Теперь найдите размер ввода, который приведет к размеру вывода 1x1. Это размер восприимчивого поля

3) Вам не нужно использовать библиотеку для этого. Для каждого объединения 2x2 выходной размер уменьшается на половину по каждому измерению. Для чередующихся сверток вы также разделяете размер каждого измерения по шагу. Возможно, вам придется сбрить часть измерения в зависимости от того, используете ли вы прописку для своих сверток. Простейшим случаем является использование padding = floor (размер ядра/2), так что доза свертки не будет иметь никаких дополнительных изменений размера вывода.

2

Вот скрипт python, который вычисляет размер RF в дополнение к шагу и размеру вывода.

# [filter size, stride, padding] 

convnet =[[11,4,0],[3,2,0],[5,1,2],[3,2,0],[3,1,1],[3,1,1],[3,1,1],[3,2,0],[6,1,0]] 
layer_name = ['conv1','pool1','conv2','pool2','conv3','conv4','conv5','pool5','fc6-conv'] 
imsize = 227 


def outFromIn(isz, layernum = 9, net = convnet): 
    if layernum>len(net): layernum=len(net) 

    totstride = 1 
    insize = isz 
    #for layerparams in net: 
    for layer in range(layernum): 
     fsize, stride, pad = net[layer] 
     outsize = (insize - fsize + 2*pad)/stride + 1 
     insize = outsize 
     totstride = totstride * stride 

    RFsize = isz - (outsize - 1) * totstride 

    return outsize, totstride, RFsize 

if __name__ == '__main__': 

    print "layer output sizes given image = %dx%d" % (imsize, imsize) 
    for i in range(len(convnet)): 
     p = outFromIn(imsize,i+1) 
     print "Layer Name = %s, Output size = %3d, Stride = % 3d, RF size = %3d" % (layer_name[i], p[0], p[1], p[2]) 
+1

Я думаю, что это неправильно. –

+0

который часть? Пожалуйста, будьте конкретны. Я был бы признателен за сообщение об ошибке, если есть – GieBur

4

Как и выше, возможно, с правильным вычислением РФ:

#Compute input size that leads to a 1x1 output size, among other things 

# [filter size, stride, padding] 

convnet =[[11,4,0],[3,2,0],[5,1,2],[3,2,0],[3,1,1],[3,1,1],[3,1,1],[3,2,0],[6,1,0]] 
layer_name = ['conv1','pool1','conv2','pool2','conv3','conv4','conv5','pool5','fc6-conv'] 
imsize = 227 

def outFromIn(isz, layernum = 9, net = convnet): 
    if layernum>len(net): layernum=len(net) 

    totstride = 1 
    insize = isz 
    #for layerparams in net: 
    for layer in range(layernum): 
     fsize, stride, pad = net[layer] 
     outsize = (insize - fsize + 2*pad)/stride + 1 
     insize = outsize 
     totstride = totstride * stride 
    return outsize, totstride 

def inFromOut(layernum = 9, net = convnet): 
    if layernum>len(net): layernum=len(net) 
    outsize = 1 
    #for layerparams in net: 
    for layer in reversed(range(layernum)): 
     fsize, stride, pad = net[layer] 
     outsize = ((outsize -1)* stride) + fsize 
    RFsize = outsize 
    return RFsize 

if __name__ == '__main__': 

    print "layer output sizes given image = %dx%d" % (imsize, imsize) 
    for i in range(len(convnet)): 
     p = outFromIn(imsize,i+1) 
     rf = inFromOut(i+1) 
     print "Layer Name = %s, Output size = %3d, Stride = % 3d, RF size = %3d" % (layer_name[i], p[0], p[1], rf) 
3

Вот другой способ вычисляет восприимчивое поле непосредственно. Stackoverflow не поддерживает математическую формулу, для более читаемой версии, пожалуйста, обратитесь к http://shawnleezx.github.io/blog/2017/02/11/calculating-receptive-field-of-cnn/

восприимчивой области (РФ) $ l_k $ из слоя $ K $ является:

$$ 
    l_k = l_{k-1} + ((f_k - 1) * \prod_{i=1}^{k-1}s_i) 
$$ 

где $ l_ {k- 1} $ - восприимчивое поле слоя $ k-1 $, $ f_k $ - размер фильтра (высота или ширина, но при условии, что они здесь одинаковы), а $ s_i $ - это шаг слоя $ i $ ,

Формула выше вычисляет восприимчивое поле снизу вверх (от уровня 1). Интуитивно, RF в слое $ k $ покрывает $ (f_k - 1) * s_ {k-1} $ больше пикселей относительный со слоем $ k-1 $. Тем не менее, приращение необходимо перевести на первый уровень , поэтому приращения являются факториалами - шаг в слое $ k-1 $ равен экспоненциально больше шагов в нижних слоях.

Надеюсь, это полезно.

Смежные вопросы