目标检测——SSD损失值计算

SSD损失分为两部分,类别损失和回归框位置损失

其中,类别损失采用softmax损失,回顾框损失采用l1——smooth损失。

1. softmax损失:

    def _softmax_loss(self, y_true, y_pred):
        y_pred = tf.maximum(y_pred, 1e-7)
        softmax_loss = -tf.reduce_sum(y_true * tf.math.log(y_pred),
                                      axis=-1)
        return softmax_loss

SSD类别部分的网络输出维度为(batch_size, 8732, num_classes),并经过softmax激活函数,转化为概率。

softmax_loss = -tf.reduce_sum(y_true * tf.math.log(y_pred),  axis=-1)

概率取-log,与对应真实值位置乘积求和, 维度为(batch_size, 8732)

2. l1_soomth 损失 

    def _l1_smooth_loss(self, y_true, y_pred):
        abs_loss = tf.abs(y_true - y_pred)
        sq_loss = 0.5 * (y_true - y_pred)**2
        l1_loss = tf.where(tf.less(abs_loss, 1.0), sq_loss, abs_loss - 0.5)
        return tf.reduce_sum(l1_loss, -1)

SSD回归框偏差部份输出维度为(batch_size, 8732, 4),分别求l1_loss 和 l2_loss,将二者结合,

l1_loss = tf.where(tf.less(abs_loss, 1.0), sq_loss, abs_loss - 0.5)

return tf.reduce_sum(l1_loss, -1)

 维度为(batch_size, 8732)。

3. 计算类别和回归框总损失

3.1 正样本:

正样本的损失分为类别损失和回归损失两种:

类别损失:(batch_size, )

pos_conf_loss = tf.reduce_sum(conf_loss * y_true[:, :, -8], axis=1)

回归损失:(batch_size, )

pos_loc_loss = tf.reduce_sum(loc_loss * y_true[:, :, -8],axis=1)

3.2 负样本

负样本的损失只有类别损失:

首先如何确定负样本,如果选取所有的负样本,则会引起类别不平衡的问题,所以选取部分负样本(正样本数量的3倍)

num_neg = tf.minimum(3 * num_pos, 8732 - num_pos)

# 求平均每个图片要取多少个负样本
num_neg_batch = tf.reduce_mean(tf.boolean_mask(num_neg,
tf.greater(num_neg, 0)))
num_neg_batch = tf.cast(num_neg_batch,tf.int32)

如果是选取部分负样本,选取哪些呢?选取不该有预测结果的框,求他们的最大置信度

max_confs = tf.reduce_max(y_pred[:, :, confs_start:confs_end], axis=2)  # 5:25 (不包括背景的20个类别)

# 取top_k个置信度,作为负样本
_, indices = tf.nn.top_k(max_confs * (1 - y_true[:, :, -8]),
k=num_neg_batch)

抽取相应位置的conf_loss

neg_conf_loss = tf.gather(tf.reshape(conf_loss, [-1]),
full_indices)
neg_conf_loss = tf.reshape(neg_conf_loss,
[batch_size, num_neg_batch])
neg_conf_loss = tf.reduce_sum(neg_conf_loss, axis=1)

3.3 总损失

total_loss = tf.reduce_sum(pos_conf_loss) + tf.reduce_sum(neg_conf_loss)
total_loss /= tf.reduce_sum(num_pos)
total_loss += tf.reduce_sum(self.alpha * pos_loc_loss) / tf.reduce_sum(num_pos)


 

 

posted @ 2020-12-15 22:55  learningcaiji  阅读(720)  评论(0编辑  收藏  举报