感受野表示输入空间中一个特定CNN特征的范围区域(The receptive field is defined as the region in the input space that a particular CNN’s feature is looking at)。一个特征的感受野可以采用区域的中心位置和特征大小进行描述。图1展示了一些感受野的例子,采用核大小(kernel size) k=3x3,填充大小(padding size) p=1x1,步长(stride)s=2x2的卷积核C对5x5大小的输入图进行卷积操作,将输出3x3大小的特征图(绿色图)。对3x3大小的特征图进行相同的卷积操作,将输出2x2的特征图(橙色)。输出特征图在每个维度上的大小可以采用下面的公式进行计算:
# [filter size, stride, padding]#Assume the two dimensions are the same#Each kernel requires the following parameters:# - k_i: kernel size# - s_i: stride# - p_i: padding (if padding is uneven, right padding will higher than left padding; "SAME" option in tensorflow)# #Each layer i requires the following parameters to be fully represented: # - n_i: number of feature (data layer has n_1 = imagesize )# - j_i: distance (projected to image pixel distance) between center of two adjacent features# - r_i: receptive field of a feature in layer i# - start_i: position of the first feature's receptive field in layer i (idx start from 0, negative means the center fall into padding)import math
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],[1,1,0]]
layer_names =['conv1','pool1','conv2','pool2','conv3','conv4','conv5','pool5','fc6-conv','fc7-conv']
imsize =227defoutFromIn(conv, layerIn):
n_in = layerIn[0]
j_in = layerIn[1]
r_in = layerIn[2]
start_in = layerIn[3]
k = conv[0]
s = conv[1]
p = conv[2]
n_out = math.floor((n_in - k +2*p)/s)+1
actualP =(n_out-1)*s - n_in + k
pR = math.ceil(actualP/2)
pL = math.floor(actualP/2)
j_out = j_in * s
r_out = r_in +(k -1)*j_in
start_out = start_in +((k-1)/2- pL)*j_in
return n_out, j_out, r_out, start_out
defprintLayer(layer, layer_name):print(layer_name +":")print("\t n features: %s \n \t jump: %s \n \t receptive size: %s \t start: %s "%(layer[0], layer[1], layer[2], layer[3]))
layerInfos =[]if __name__ =='__main__':#first layer is the data layer (image) with n_0 = image size; j_0 = 1; r_0 = 1; and start_0 = 0.5print("-------Net summary------")
currentLayer =[imsize,1,1,0.5]
printLayer(currentLayer,"input image")for i inrange(len(convnet)):
currentLayer = outFromIn(convnet[i], currentLayer)
layerInfos.append(currentLayer)
printLayer(currentLayer, layer_names[i])print("------------------------")
layer_name =raw_input("Layer name where the feature in: ")
layer_idx = layer_names.index(layer_name)
idx_x =int(raw_input("index of the feature in x dimension (from 0)"))
idx_y =int(raw_input("index of the feature in y dimension (from 0)"))
n = layerInfos[layer_idx][0]
j = layerInfos[layer_idx][1]
r = layerInfos[layer_idx][2]
start = layerInfos[layer_idx][3]assert(idx_x < n)assert(idx_y < n)print("receptive field: (%s, %s)"%(r, r))print("center: (%s, %s)"%(start+idx_x*j, start+idx_y*j))