如何计算感受野大小?
How to calculate receptive field size?
我正在阅读有关使用 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.
我的问题是:
- 感受野的定义是什么?
- 他们如何计算感受野的大小和位置?
- 我们如何使用caffe/pycaffe计算感受野的边界矩形?
1) 影响最后一个卷积输出的是像素区域的大小。
2) 对于每个卷积和池化操作,计算输出的大小。现在找到导致输出大小为 1x1 的输入大小。那就是感受野的大小
3) 您不需要使用库来完成它。对于每个 2x2 池,输出大小沿每个维度减少一半。对于步幅卷积,您还可以将每个维度的大小除以步幅。您可能需要削减一些维度,具体取决于您是否对卷积使用填充。最简单的情况是使用 padding = floor(kernel size/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])
如上所述,可能正确计算了 RF:
#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)
这是另一种直接计算感受野的方法。 Whosebug不支持数学公式,更易读的版本请参考Calculating Receptive Field of CNN
第$k$层的感受野(RF)$l_k$是:
$$ l_k = l_{k-1} + ((f_k - 1) * \prod_{i=1}^{k-1}s_i) $$
其中$l_{k-1}$是第$k-1$层的感受野,$f_k$是filter size
(高度或宽度,但假设它们在这里相同),$s_i$ 是步幅
第 $i$ 层。
上面的公式是自下而上计算感受野(from layer
1).直观上,$k$ 层中的 RF 覆盖了 $(f_k - 1) * s_{k-1}$ 个像素
与层 $k-1$ 相关。但是,增量需要转换为
第一层,所以增量是一个阶乘——$k-1$ 层的步幅是
下层的步幅呈指数增长。
希望这对您有所帮助。
2019 年 12 月 11 日更新:
TF 库已移至 https://github.com/google-research/receptive_field
另请参阅 Distill 论文 "Computing Receptive Fields of Convolutional Neural Networks":https://distill.pub/2019/computing-receptive-fields/
旧:
Tensorflow 现在支持感受野计算,只需使用 tf.contrib.receptive_field
详情见https://github.com/tensorflow/tensorflow/tree/master/tensorflow/contrib/receptive_field。
假设我们的网络架构仅包含多个卷积层。对于每个卷积层,我们定义一个平方核大小和一个扩张率。另外,假设步幅为1。因此,您可以通过以下python代码段计算网络的感受野:
K=[3,3] # Kernel Size
R=[1,2] # Dilation Rate
RF=1
d=1 # Depth
for k,r in zip(K,R):
support=k+(k-1)*(r-1) # r-dilated conv. adds r-1 zeros among coefficients
RF=support+(RF-1)
print('depth=%d, K=%d, R=%d, kernel support=%d'%(d,k,r,support))
d=d+1
print('Receptive Field: %d'%RF)
例如,让我们计算著名的 DnCNN(去噪卷积神经网络)[1] 的感受野 (RF)。
使用上面的代码段和以下输入来计算该网络的 RF。 (你会得到 RF=35)。
# In DnCNN-S, the network has 17 convolution layers.
K=[3]*17 # Kernel Size
R=[1]*17 # Dilation Rate
[1]张凯等。 "Beyond a gaussian denoiser: Residual learning of deep cnn for image denoising." IEEE 图像处理汇刊 26.7 (2017):3142-3155。
我正在阅读有关使用 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.
我的问题是:
- 感受野的定义是什么?
- 他们如何计算感受野的大小和位置?
- 我们如何使用caffe/pycaffe计算感受野的边界矩形?
1) 影响最后一个卷积输出的是像素区域的大小。
2) 对于每个卷积和池化操作,计算输出的大小。现在找到导致输出大小为 1x1 的输入大小。那就是感受野的大小
3) 您不需要使用库来完成它。对于每个 2x2 池,输出大小沿每个维度减少一半。对于步幅卷积,您还可以将每个维度的大小除以步幅。您可能需要削减一些维度,具体取决于您是否对卷积使用填充。最简单的情况是使用 padding = floor(kernel size/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])
如上所述,可能正确计算了 RF:
#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)
这是另一种直接计算感受野的方法。 Whosebug不支持数学公式,更易读的版本请参考Calculating Receptive Field of CNN
第$k$层的感受野(RF)$l_k$是:
$$ l_k = l_{k-1} + ((f_k - 1) * \prod_{i=1}^{k-1}s_i) $$
其中$l_{k-1}$是第$k-1$层的感受野,$f_k$是filter size (高度或宽度,但假设它们在这里相同),$s_i$ 是步幅 第 $i$ 层。
上面的公式是自下而上计算感受野(from layer 1).直观上,$k$ 层中的 RF 覆盖了 $(f_k - 1) * s_{k-1}$ 个像素 与层 $k-1$ 相关。但是,增量需要转换为 第一层,所以增量是一个阶乘——$k-1$ 层的步幅是 下层的步幅呈指数增长。
希望这对您有所帮助。
2019 年 12 月 11 日更新:
TF 库已移至 https://github.com/google-research/receptive_field
另请参阅 Distill 论文 "Computing Receptive Fields of Convolutional Neural Networks":https://distill.pub/2019/computing-receptive-fields/
旧:
Tensorflow 现在支持感受野计算,只需使用 tf.contrib.receptive_field
详情见https://github.com/tensorflow/tensorflow/tree/master/tensorflow/contrib/receptive_field。
假设我们的网络架构仅包含多个卷积层。对于每个卷积层,我们定义一个平方核大小和一个扩张率。另外,假设步幅为1。因此,您可以通过以下python代码段计算网络的感受野:
K=[3,3] # Kernel Size
R=[1,2] # Dilation Rate
RF=1
d=1 # Depth
for k,r in zip(K,R):
support=k+(k-1)*(r-1) # r-dilated conv. adds r-1 zeros among coefficients
RF=support+(RF-1)
print('depth=%d, K=%d, R=%d, kernel support=%d'%(d,k,r,support))
d=d+1
print('Receptive Field: %d'%RF)
例如,让我们计算著名的 DnCNN(去噪卷积神经网络)[1] 的感受野 (RF)。 使用上面的代码段和以下输入来计算该网络的 RF。 (你会得到 RF=35)。
# In DnCNN-S, the network has 17 convolution layers.
K=[3]*17 # Kernel Size
R=[1]*17 # Dilation Rate
[1]张凯等。 "Beyond a gaussian denoiser: Residual learning of deep cnn for image denoising." IEEE 图像处理汇刊 26.7 (2017):3142-3155。