Faster RCNN源码学习一

部分参考链接:https://blog.csdn.net/l297969586/article/details/78019543

https://blog.csdn.net/u012457308/article/details/79566195

https://blog.csdn.net/mao_xiao_feng/article/details/53382790


Loss(在train.py)

Loss主要分为四部分:RPN和RCNN的分类loss,RPN和RCNN的回归loss。分类loss用softmax_cross_entropy计算,回归loss用smooth_l1_loss计算。

softmax_cross_entropy

先对网络最后一层输出做一个softmax,得出属于某一类的概率,公式为:

                                                      

然后计算交叉熵,公式为:

                                                           

是实际标签值。代码中函数为tf.nn.softmax_cross_entropy_with_logits(logits, labels, name=None):logits是网络最后一层输出向量,labels是实际标签向量,函数返回一个向量。要求交叉熵,再做一步tf.reduce_sum操作,对向量里面所有元素求和,如果求loss,再做一步tf.reduce_mean操作,对向量求均值。

Smooth_l1_loss

L1loss,就是误差绝对值,存在零点不平滑问题,smooth_l1_loss修改了这个问题,公式如下:

                               SmoothL1(x)={0.5x2|x|â0.5|x|<1otherwiseSmoothL1(x)={0.5x2|x|<1|x|â0.5otherwise

曲线图如下:

                                     

代码中,smooth_l1_loss是这样计算的:

ResultLoss = outside_weights * SmoothL1(inside_weights * (bbox_pred - bbox_targets))

SmoothL1(x) = 0.5 * (sigma * x)^2, if |x| < 1 / sigma^2

                         |x| - 0.5 / sigma^2, otherwise

L2loss是计算误差的平方,缺点是对离群点、异常值(outlierss)比较敏感,如果feature是unbounded的话,需要好好调整学习率,防止出现梯度爆炸的情况[fast rcnn],但smooth_l1_loss对离群点鲁棒[faster rcnn]。

总损失函数

源代码

# RPN
# 分类层(cls_score)输出在每一个位置上,9个anchor属于前景和背景的概率,窗口回归层(bbox_pred)输出9个anchor对应窗口应该平移的参数dx,dy,dw,dh
# classification loss
rpn_cls_score=tf.reshape(self.net.get_output('rpn_cls_score_reshape'),[-1,2])
rpn_label = tf.reshape(self.net.get_output('rpn-data')[0],[-1])
rpn_cls_score = tf.reshape(tf.gather(rpn_cls_score,tf.where(tf.not_equal(rpn_label,-1))),[-1,2])
rpn_label = tf.reshape(tf.gather(rpn_label,tf.where(tf.not_equal(rpn_label,-1))),[-1])
rpn_cross_entropy=tf.reduce_mean(tf.nn.sparse_softmax_cross_entropy_with_logits(logits=rpn_cls_score, labels=rpn_label))

# boundingbox regression L1 loss
rpn_bbox_pred=self.net.get_output('rpn_bbox_pred')
rpn_bbox_targets=tf.transpose(self.net.get_output('rpn-data')[1],[0,2,3,1])
rpn_bbox_inside_weights=tf.transpose(self.net.get_output('rpn-data')[2],[0,2,3,1])
rpn_bbox_outside_weights=tf.transpose(self.net.get_output('rpn-data')[3],[0,2,3,1])

rpn_smooth_l1=self._modified_smooth_l1(3.0,rpn_bbox_pred,rnp_bbox_targets,rpn_bbox_inside_weights,rpn_bbox_outside_weights)
rpn_loss_box=tf.reduce_mean(tf.reduce_sum(rpn_smooth_l1,reduction_indices=[1,2,3]))

#R-CNN
#cls_score输出(k+1)维数组p,即属于k类和背景的概率;bbox_predict层输出bbox回归位移,用于调整候选区域的位置,输出4*k维数组t,表示分别属于k类时,应该平移缩放的参数
#classificaiton loss
cls_score=self.net.get_output('cls_score')
label=tf.reshape(self.net.get_output('roi-data')[2]
cross_entropy=tf.reduce_mean(tf.nn.sparse_softmax_cross_entropy_with_logits(logits=cls_score,labels=label))

#bounding box regression L1 loss
bbox_pred=self.net.get_output('bbox_pred')
bbox_targets=self.net.get_output('roi-data')[2]
bbox_inside_weights=self.net.get_output('roi-data')[3]
bbox_outside_weights=self.net.get_output('roi-data')[4]

smooth_l1=self._modified_smooth_l1(1.0,bbox_pred,bbox_targets,bbox_inside_weights,bbox_outside_weights)
loss_box=tf.reduce_mean(tf.reduce_sum(smooth_l1,reduction_indices=[1]))

#final loss
loss=cross_entropy+loss_box+rpn_cross_entropy+rpn_loss_box

猜你喜欢

转载自blog.csdn.net/mmff0726/article/details/82773282