Faster RCNN源码解读5-损失函数

Faster RCNN复现

Faster RCNN源码解读1-整体流程和各个子流程梳理

Faster RCNN源码解读2-_anchor_component()为图像建立anchors(核心和关键1)

Faster RCNN源码解读3.1-_region_proposal() 筛选anchors-_proposal_layer()(核心和关键2)

Faster RCNN源码解读3.2-_region_proposal()筛选anchors-_anchor_target_layer()(核心和关键2)

Faster RCNN源码解读3.3-_region_proposal() 筛选anchors-_proposal_target_layer()(核心和关键2)

Faster RCNN源码解读4-其他收尾工作:ROI_pooling、分类、回归等

Faster RCNN源码解读5-损失函数

 

理论介绍:有关Faster RCNN理论介绍的文章,可以自行搜索,这里就不多说理论部分了。

复现过程:代码配置过程没有记录,具体怎么把源码跑起来需要自己搜索一下。

faster rcnn源码确实挺复杂的,虽然一步步解析了,但是觉得还是没有领会其中的精髓,只能算是略知皮毛。在这里将代码解析的过程给大家分享一下,希望对大家有帮助。先是解析了代码的整体结构,然后对各个子结构进行了分析。代码中的注释,有的是原来就有的注释,有的是参考网上别人的,有的是自己理解的,里面或多或少会有些错误,如果发现,欢迎指正!

本文解析的源码地址:https://github.com/lijianaiml/tf-faster-rcnn-windows

知乎:FasterRCNN损失函数理论

CSDN:FasterRCNN损失函数理论 

上面链接里的文章,自己手动抄了一份,加深理解。

rcnn包括两个损失:rpn网络的损失+rcnn网络的损失,其中每个损失又包括分类损失回归损失分类损失使用的是交叉熵回归损失使用的是smooth L1 loss

程序通过**_add_losses**增加对应的损失函数。其中:
rpn_cross_entropyrpn_loss_boxRPN网络的两个损失,这两个损失用于判断archor是否是ground truth(二分类);
cls_scorebbox_predrcnn网络的两个损失。这两个损失的batchsize是256。

  1. 将rpn_label(1,?,?,2)中不是-1的index取出来,之后将rpn_cls_score(1,?,?,2)及rpn_label中对应于index的取出,计算sparse_softmax_cross_entropy_with_logits,得到rpn_cross_entropy。
  2. 计算rpn_bbox_pred(1,?,?,36)和rpn_bbox_targets(1,?,?,36)的_smooth_l1_loss,得到rpn_loss_box。
  3. 计算cls_score(256*21)和label(256)的sparse_softmax_cross_entropy_with_logits:cross_entropy。
  4. 计算bbox_pred(256*84)和bbox_targets(256*84)的_smooth_l1_loss:loss_box。

最终将上面四个loss相加,得到总的loss(还需要加上regularization_loss),至此,损失构造完毕。

_add_losses()

  '''
  faster rcnn包括两个损失:rpn网络的损失+rcnn网络的损失。其中每个损失又包括分类损失和回归损失。
  分类损失使用的是交叉熵,回归损失使用的是smooth L1 loss。
  
  程序通过**_add_losses**增加对应的损失函数。其中
  rpn_cross_entropy和rpn_loss_box是RPN网络的两个损失,这两个损失用于判断archor是否是ground truth(二分类);
  cls_score和bbox_pred是rcnn网络的两个损失。这两个损失的batchsize是256。
  
  将rpn_label(1,?,?,2)中不是-1的index取出来,之后将rpn_cls_score(1,?,?,2)及rpn_label中对应于index的取出,
  计算sparse_softmax_cross_entropy_with_logits,得到rpn_cross_entropy。
  计算rpn_bbox_pred(1,?,?,36)和rpn_bbox_targets(1,?,?,36)的_smooth_l1_loss,得到rpn_loss_box。
  计算cls_score(256*21)和label(256)的sparse_softmax_cross_entropy_with_logits:cross_entropy。 
  计算bbox_pred(256*84)和bbox_targets(256*84)的_smooth_l1_loss:loss_box。
  最终将上面四个loss相加,得到总的loss(还需要加上regularization_loss)。
  至此,损失构造完毕。
  '''
  def _add_losses(self, sigma_rpn=3.0):
    with tf.variable_scope('LOSS_' + self._tag) as scope:
      # (1)RPN, class loss 分类损失
      # 每个anchors是正样本还是负样本
      rpn_cls_score = tf.reshape(self._predictions['rpn_cls_score_reshape'], [-1, 2])
      # 特征图中每个位置对应的是正样本、负样本还是不关注(去除了边界框在图像外面的anchors)
      rpn_label = tf.reshape(self._anchor_targets['rpn_labels'], [-1])
      rpn_select = tf.where(tf.not_equal(rpn_label, -1)) #不关注的anchors的索引
      rpn_cls_score = tf.reshape(tf.gather(rpn_cls_score, rpn_select), [-1, 2]) #去除不关注的anchors
      rpn_label = tf.reshape(tf.gather(rpn_label, rpn_select), [-1]) #去除不关注的label
      rpn_cross_entropy = tf.reduce_mean(
        tf.nn.sparse_softmax_cross_entropy_with_logits(logits=rpn_cls_score, labels=rpn_label)) #rpn二分类的损失

      # (2)RPN, bbox loss 回归损失
      rpn_bbox_pred = self._predictions['rpn_bbox_pred'] #每个位置的9个anchors回归位置偏移
      rpn_bbox_targets = self._anchor_targets['rpn_bbox_targets'] #特征图中每个位置和对应的正样本的坐标偏移(很多为0)
      rpn_bbox_inside_weights = self._anchor_targets['rpn_bbox_inside_weights'] #正样本的权重为1(去除负样本和不关注的样本,均为0)
      rpn_bbox_outside_weights = self._anchor_targets['rpn_bbox_outside_weights'] #正样本和负样本(不包括不关注的样本)归一化的权重
      rpn_loss_box = self._smooth_l1_loss(rpn_bbox_pred, rpn_bbox_targets, rpn_bbox_inside_weights,
                                          rpn_bbox_outside_weights, sigma=sigma_rpn, dim=[1, 2, 3])

      # (3)RCNN, class loss 分类损失
      cls_score = self._predictions["cls_score"] #用于rcnn分类的256个anchors的特征
      label = tf.reshape(self._proposal_targets["labels"], [-1]) #正样本和负样本对应的真实的类别
      cross_entropy = tf.reduce_mean(tf.nn.sparse_softmax_cross_entropy_with_logits(logits=cls_score, labels=label))

      # (4)RCNN, bbox loss 回归损失
      bbox_pred = self._predictions['bbox_pred']  #RCNN ,bbox loss
      bbox_targets = self._proposal_targets['bbox_targets'] #256*(4*21)的矩阵,只有为正样本时,对应类别的坐标才不为0,其他类别的坐标全为0
      bbox_inside_weights = self._proposal_targets['bbox_inside_weights']
      bbox_outside_weights = self._proposal_targets['bbox_outside_weights']
      loss_box = self._smooth_l1_loss(bbox_pred, bbox_targets, bbox_inside_weights, bbox_outside_weights)

      self._losses['cross_entropy'] = cross_entropy
      self._losses['loss_box'] = loss_box
      self._losses['rpn_cross_entropy'] = rpn_cross_entropy
      self._losses['rpn_loss_box'] = rpn_loss_box

      loss = cross_entropy + loss_box + rpn_cross_entropy + rpn_loss_box   #总的损失
      regularization_loss = tf.add_n(tf.losses.get_regularization_losses(), 'regu')  #获取总正则化loss.
      self._losses['total_loss'] = loss + regularization_loss

      self._event_summaries.update(self._losses)

    return loss

 _smooth_l1_loss()

  '''
  程序中先计算pred和target的差box_diff,而后得到正样本的差in_box_diff
  (通过乘以权重bbox_inside_weights将负样本设置为0)及绝对值abs_in_box_diff,之后计算上式(3)
  中的符号smoothL1_sign,并得到的smooth L1 loss:in_loss_box,乘以bbox_outside_weights权重,
  并得到最终的loss:loss_box。
  '''
  def _smooth_l1_loss(self, bbox_pred, bbox_targets, bbox_inside_weights, bbox_outside_weights, sigma=1.0, dim=[1]):
    sigma_2 = sigma ** 2
    box_diff = bbox_pred - bbox_targets   # 预测的和真实的相减   x
    in_box_diff = bbox_inside_weights * box_diff  # 乘以正样本的权重1(rpn:去除负样本和不关注的样本,rcnn:去除负样本)
    abs_in_box_diff = tf.abs(in_box_diff)  # 绝对值  |x|
    smoothL1_sign = tf.stop_gradient(tf.to_float(tf.less(abs_in_box_diff, 1. / sigma_2)))   # 小于阈值的截断的标志位
    in_loss_box = tf.pow(in_box_diff, 2) * (sigma_2 / 2.) * smoothL1_sign \
                  + (abs_in_box_diff - (0.5 / sigma_2)) * (1. - smoothL1_sign)  # smooth l1 loss
    out_loss_box = bbox_outside_weights * in_loss_box  # rpn:除以有效样本总数(不考虑不关注的样本),进行归一化;rcnn:正样本四个坐标权重为1,负样本为0
    loss_box = tf.reduce_mean(tf.reduce_sum(
      out_loss_box,
      axis=dim
    ))
    return loss_box

终于更新完了,写完后自己对FasterRCNN也有了更深的理解,送人玫瑰,手有余香。感谢你一直以来的关注!一起努力一起加油!

  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Fast R-CNN(Region-based Convolutional Neural Networks)是一种目标检测算法,而Faster R-CNN是Fast R-CNN的改进版本。Fast R-CNN基于区域建议网络(Region Proposal Network,RPN)生成候选区域,通过提取候选区域特征并送入全连接层进行目标分类和边界框回归。 而Faster R-CNN进一步改进了区域建议网络,将其整合到模型中,从而实现端到端的目标检测。Faster R-CNN的主要创新点是引入了RPN网络,使得检测和提取候选区域的过程能够在训练和测试过程中共享卷积特征,大大提高了检测速度。 Faster R-CNN源码主要包含以下几个部分: 1. 基础模型部分:包括了卷积层、池化层等用于特征提取的网络结构。 2. 区域建议网络(RPN)部分:构建一个小型的神经网络,对于输入图像中的每个位置生成多个候选框,同时输出每个候选框属于目标的概率。 3. 快速区域卷积神经网络(Fast R-CNN)部分:通过共享卷积特征,对RPN输出的候选框进行特征提取,并送入全连接层进行目标分类和边界框回归。 4. 损失函数:用于训练网络的损失函数,主要包括用于划分候选框是否包含目标的分类损失和用于对边界框回归的回归损失。 Faster R-CNN源码实现通常使用深度学习框架,如PyTorch或TensorFlow。在源码中,会包含网络结构的定义、损失函数的定义、数据加载与处理、训练过程以及测试过程等。 总之,Faster R-CNN源码实现了一种端到端的目标检测算法,通过整合区域建议网络和快速区域卷积神经网络,实现了高效准确的目标检测任务。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值