我正在使用自定义损失函数(yolo v2损失函数),但是我以南

时间:2019-11-12 12:25:22

标签: keras nan yolo loss

以下代码是从回购协议Keras-Yolo-v2启发而来的,我正遇到代码问题,我试图了解Nan造成损失的可能原因。 我已经使用过诸如clipnorm之类的技术,但这没有帮助。 这是yolo v2的自定义丢失,我正在尝试在Tensorflow 2.0上实现它。 我对此有一些想法,在某个地方值变成0并导致Nan的损失,但是我可以确切地知道可能在哪里发生。任何帮助将不胜感激。

预先感谢

class YoloLossKeras:

    def __init__(self, priors):
        self.priors = priors

    def loss(self, y_true, y_pred):

        n_cells = y_pred.get_shape().as_list()[1]
        y_true = tf.reshape(y_true, tf.shape(y_pred), name='y_true')
        y_pred = tf.identity(y_pred, name='y_pred')

        #### PROCESS PREDICTIONS ####
        # get x-y coords (for now they are with respect to cell)
        predicted_xy = tf.nn.sigmoid(y_pred[..., :2])

        # convert xy coords to be with respect to image
        cell_inds = tf.range(n_cells, dtype=tf.float32)
        predicted_xy = tf.stack((
            predicted_xy[..., 0] + tf.reshape(cell_inds, [1, -1, 1]), 
            predicted_xy[..., 1] + tf.reshape(cell_inds, [-1, 1, 1])
        ), axis=-1)

        # compute bb width and height
        predicted_wh = self.priors * tf.exp(y_pred[..., 2:4])

        # compute predicted bb center and width
        predicted_min = predicted_xy - predicted_wh / 2
        predicted_max = predicted_xy + predicted_wh / 2

        predicted_objectedness = tf.nn.sigmoid(y_pred[..., 4])
        predicted_logits = tf.nn.softmax(y_pred[..., 5:])


        #### PROCESS TRUE ####
        true_xy = y_true[..., :2]
        true_wh = y_true[..., 2:4]
        true_logits = y_true[..., 5:]

        true_min = true_xy - true_wh / 2
        true_max = true_xy + true_wh / 2

        #### compute iou between ground truth and predicted (used for objectedness) ####
        intersect_mins  = tf.maximum(predicted_min, true_min)
        intersect_maxes = tf.minimum(predicted_max, true_max)
        intersect_wh    = tf.maximum(intersect_maxes - intersect_mins, 0.)
        intersect_areas = intersect_wh[..., 0] * intersect_wh[..., 1]

        true_areas = true_wh[..., 0] * true_wh[..., 1]
        pred_areas = predicted_wh[..., 0] * predicted_wh[..., 1]

        union_areas = pred_areas + true_areas - intersect_areas
        iou_scores  = intersect_areas / union_areas

        #### Compute loss terms ####
        responsibility_selector = y_true[..., 4]

        xy_diff = tf.square(true_xy - predicted_xy) * responsibility_selector[..., None]
        xy_loss = tf.reduce_sum(xy_diff, axis=[1, 2, 3, 4])

        wh_diff = tf.square(tf.sqrt(true_wh) - tf.sqrt(predicted_wh)) * responsibility_selector[..., None]
        wh_loss = tf.reduce_sum(wh_diff, axis=[1, 2, 3, 4])

        obj_diff = tf.square(iou_scores - predicted_objectedness) * responsibility_selector
        obj_loss = tf.reduce_sum(obj_diff, axis=[1, 2, 3])

        best_iou = tf.reduce_max(iou_scores, axis=-1)
        no_obj_diff = tf.square(0 - predicted_objectedness) * tf.cast(best_iou < 0.6,tf.float32)[..., None] * (1 - responsibility_selector)
        no_obj_loss = tf.reduce_sum(no_obj_diff, axis=[1, 2, 3])

        clf_diff = tf.square(true_logits - predicted_logits) * responsibility_selector[..., None]
        clf_loss = tf.reduce_sum(clf_diff, axis=[1, 2, 3, 4])

        object_coord_scale = 5
        object_conf_scale = 1
        noobject_conf_scale = 1
        object_class_scale = 1

        loss = object_coord_scale * (xy_loss + wh_loss) + \
                object_conf_scale * obj_loss + noobject_conf_scale * no_obj_loss + \
                object_class_scale * clf_loss
        return loss 

0 个答案:

没有答案