keras Mask Rcnn代码走读(二)-RPN
RPN-Region proposal Net,主要作用为通过得到所有anchors的score(前景概率)及box初步矫正信息,及NMS来实现对anchors的筛选。找到规定数量且满足条件的anchors。数量不足的填0处理,确保每张图的筛选anchors数量相等,便于tensor计算。
1.RPN score(前景概率)及box初步矫正信息生成:
网络的输入为rpn_feature_maps,p2-p6 五个特征map。by 特征map进行相关处理。
rpn_feature_maps = [P2, P3, P4, P5, P6]
# Anchors
if mode == "training":
……
else:
anchors = input_anchors
# RPN Model, 返回的是keras的Module对象, 注意keras中的Module对象是可call的
rpn = build_rpn_model(config.RPN_ANCHOR_STRIDE, # 1 3 256
len(config.RPN_ANCHOR_RATIOS), config.TOP_DOWN_PYRAMID_SIZE)
# Loop through pyramid layers
layer_outputs = [] # list of lists anchors信息list
for p in rpn_feature_maps:
layer_outputs.append(rpn([p])) # 保存各pyramid特征经过RPN之后的结果
# Concatenate layer outputs
# Convert from list of lists of level outputs to list of lists
# of outputs across levels.
# e.g. [[a1, b1, c1], [a2, b2, c2]] => [[a1, a2], [b1, b2], [c1, c2]]
output_names = ["rpn_class_logits", "rpn_class", "rpn_bbox"]
outputs = list(zip(*layer_outputs)) # [[logits2,……6], [class2,……6], [bbox2,……6]] #P2-P6的信息压缩在一起堆成一个维度
outputs = [KL.Concatenate(axis=1, name=n)(list(o))
for o, n in zip(outputs, output_names)]
#name与对应的信息压缩在一个维度,[batch, num_anchors, 2+2+4]
# 其中num_anchors指的是全部特征层上的anchors总数
rpn_class_logits, rpn_class, rpn_bbox = outputs
#生成anchor的信息(score,与bbox回归矫正信息,logits为class score softmax前的网络输出结果)
#rpn_class_logits, rpn_class shape相同[batch, num_anchors, 2]
#rpn_bbox shape为[batch, num_anchors, 4],(dy,dx,logdh,logdw)
具体的RPN模块调用函数栈如下,
############################################################
# Region Proposal Network (RPN)
############################################################
def rpn_graph(feature_map, anchors_per_location, anchor_stride):
"""Builds the computation graph of Region Proposal Network.
feature_map: backbone features [batch, height, width, depth]
anchors_per_location: number of anchors per pixel in the feature map
anchor_stride: Controls the density of anchors. Typically 1 (anchors for
every pixel in the feature map), or 2 (every other pixel).
Returns:
rpn_class_logits: [batch, H * W * anchors_per_location, 2] Anchor classifier logits (before softmax)
rpn_probs: [batch, H * W * anchors_per_location, 2] Anchor classifier probabilities.
rpn_bbox: [batch, H * W * anchors_per_location, (dy, dx, log(dh), log(dw))] Deltas to be
applied to anchors.
"""
# TODO: check if stride of 2 causes alignment(校准,对齐) issues if the feature map
# is not even.
# Shared convolutional base of the RPN
shared = KL.Conv2D(512, (3, 3), padding='same', activation='relu',
strides=anchor_stride,
name='rpn_conv_shared')(feature_map)
# Anchor Score. [batch, height, width, anchors per location * 2]. 二分类问题,3个开口率,特征channel数量为2*3
x = KL.Conv2D(2 * anchors_per_location, (1, 1), padding='valid',
activation='linear', name='rpn_class_raw')(shared)
# Reshape to [batch, anchors, 2],使用keras的Lambda层实现
rpn_class_logits = KL