模型评估中目标检测模型的目标框亮度敏感度分析以及相关的解决方法

举报
talking_cv 发表于 2020/08/13 15:45:29 2020/08/13
【摘要】 在目标检测任务中,不同数据集的目标框的亮度可能会有差异,目标框亮度敏感度就是衡量这个差异的变量,而不同的目标框亮度的数值对模型训练以及推理都会有影响。本博客将对该敏感度进行分析并对相关的解决方法进行介绍

一、 问题描述

   在目标检测任务中,不同数据集的目标框的亮度可能会有差异,目标框亮度敏感度就是衡量这个差异的变量,而不同的目标框亮度的数值对模型训练以及推理都会有影响。下图表示的就是同一个图片中,目标框内部标签的亮度值不一样。

图1 目标框亮度不均匀场景

二、解决方法

  在深度学习任务中,dropout是一种被广泛使用的正则化技术,这种技术存在的缺点就是随机的丢弃掉特征层的某一个单元,使得相邻特征单元共享的语义信息也会一起丢弃掉,DropBlock改进了上述问题,即可以按照特征块来进行丢弃,对深度学习网络进行正则化处理。DropBlock 是类似dropout 的简单方法。二者的主要区别在于DropBlock丢弃层特征图的相邻区域,而不是丢弃单独的随机单元。具体详细介绍参见DropBlock论文

DropBlock模块主要有2个参数,block_size,γ。

  •  block_size:表示dropout的方块的大小(长,宽),当block_size=1,DropBlock 退化为传统的dropout,正常可以取3,5,7

  •  γ:表示drop过程中的概率,也就是伯努利函数的概率

dropout(对应b图)和dropblock(对应c图)的对比

图2 Dropout和Dropblock原理对比图,其中,b图表示Dropout,c图表示DropBlock

  tf版的官方实现方式如下:

class Dropblock(object):
  """DropBlock: a regularization method for convolutional neural networks.
    DropBlock is a form of structured dropout, where units in a contiguous
    region of a feature map are dropped together. DropBlock works better than
    dropout on convolutional layers due to the fact that activation units in
    convolutional layers are spatially correlated.
    See https://arxiv.org/pdf/1810.12890.pdf for details.
  """

  def __init__(self,
               dropblock_keep_prob=None,
               dropblock_size=None,
               data_format='channels_last'):
    self._dropblock_keep_prob = dropblock_keep_prob
    self._dropblock_size = dropblock_size
    self._data_format = data_format

  def __call__(self, net, is_training=False):
    """Builds Dropblock layer.
    Args:
      net: `Tensor` input tensor.
      is_training: `bool` if True, the model is in training mode.
    Returns:
      A version of input tensor with DropBlock applied.
    """
    if (not is_training or self._dropblock_keep_prob is None or
        self._dropblock_keep_prob == 1.0):
      return net

    logging.info('Applying DropBlock: dropblock_size %d,'
                 'net.shape %s', self._dropblock_size, net.shape)

    if self._data_format == 'channels_last':
      _, height, width, _ = net.get_shape().as_list()
    else:
      _, _, height, width = net.get_shape().as_list()

    total_size = width * height
    dropblock_size = min(self._dropblock_size, min(width, height))
    # Seed_drop_rate is the gamma parameter of DropBlcok.
    seed_drop_rate = (
        1.0 - self._dropblock_keep_prob) * total_size / dropblock_size**2 / (
            (width - self._dropblock_size + 1) *
            (height - self._dropblock_size + 1))

    # Forces the block to be inside the feature map.
    w_i, h_i = tf.meshgrid(tf.range(width), tf.range(height))
    valid_block = tf.logical_and(
        tf.logical_and(w_i >= int(dropblock_size // 2),
                       w_i < width - (dropblock_size - 1) // 2),
        tf.logical_and(h_i >= int(dropblock_size // 2),
                       h_i < width - (dropblock_size - 1) // 2))

    if self._data_format == 'channels_last':
      valid_block = tf.reshape(valid_block, [1, height, width, 1])
    else:
      valid_block = tf.reshape(valid_block, [1, 1, height, width])

    randnoise = tf.random_uniform(net.shape, dtype=tf.float32)
    valid_block = tf.cast(valid_block, dtype=tf.float32)
    seed_keep_rate = tf.cast(1 - seed_drop_rate, dtype=tf.float32)
    block_pattern = (1 - valid_block + seed_keep_rate + randnoise) >= 1
    block_pattern = tf.cast(block_pattern, dtype=tf.float32)

    if self._data_format == 'channels_last':
      ksize = [1, self._dropblock_size, self._dropblock_size, 1]
    else:
      ksize = [1, 1, self._dropblock_size, self._dropblock_size]
    block_pattern = -tf.nn.max_pool(
        -block_pattern,
        ksize=ksize,
        strides=[1, 1, 1, 1],
        padding='SAME',
        data_format='NHWC' if self._data_format == 'channels_last' else 'NCHW')

    percent_ones = tf.cast(tf.reduce_sum(block_pattern), tf.float32) / tf.cast(
        tf.size(block_pattern), tf.float32)

    net = net / tf.cast(percent_ones, net.dtype) * tf.cast(
        block_pattern, net.dtype)
    return net


三、实验验证

  在开源数据集Canine Coccidiosis Parasite上面进行实验,该数据集只有一个类别,使用DropBlock之前,模型对目标框亮度敏感度如下所示:

图3 使用DropBlock之前,检测模型对目标框亮度敏感度分析

  使用DropBlock之后,模型对目标框亮度敏感度的结果如下所示,可以看到,使用DropBlock之后,类别的目标框亮度敏感度从原来的0.0658降低到0.0204,在模型评估阶段可以有效降低检测模型对目标框的亮度敏感度。


图4 使用DropBlock之后,检测模型对目标框亮度敏感度分析

四、用户建议

在模型推理结果中,如果检测出来的类别对于目标框亮度的敏感程度比较大,推荐在训练的时候,使用DropBlock进行模型优化和加强。


【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。