美文网首页
yolo_v3改focal loss

yolo_v3改focal loss

作者: 求索_700e | 来源:发表于2019-02-15 12:24 被阅读0次

    retinanet中的损失函数定义如下:

    def _focal(y_true, y_pred):

            """ Compute the focal loss given the target tensor and the predicted tensor.

            As defined in https://arxiv.org/abs/1708.02002

            Args

                y_true: Tensor of target data from the generator with shape (B, N, num_classes).

                y_pred: Tensor of predicted data from the network with shape (B, N, num_classes).

            Returns

                The focal loss of y_pred w.r.t. y_true.

            """

            labels        = y_true[:, :, :-1]##这行的意思是:The slices [1:] and [:-1] mean all but the first and

    ### all but the last elements of the array。更多,请看下面第三行的解释.

            anchor_state  = y_true[:, :, -1]  # -1 for ignore, 0 for background, 1 for object

            classification = y_pred

    #### 解释:

            ####请看anchors.py中的函数anchor_targets_bbox,就知道

    #### Returns

            #### labels_batch: batch that contains labels & anchor states (np.array of shape (batch_size, N, num_classes + 1),

            ####      where N is the number of anchors for an image and the last column defines the anchor state (-1 for ignore, 0 for bg, 1 for fg).

            #### regression_batch: batch that contains bounding-box regression targets for an image & anchor states (np.array of shape (batch_size, N, 4 + 1),

            ####      where N is the number of anchors for an image, the first 4 columns define regression targets for (x1, y1, x2, y2) and the

            ####      last column defines anchor states (-1 for ignore, 0 for bg, 1 for fg).

            #### annotations_batch: annotations per anchor (np.array of shape (batch_size, N, annotations.shape[1]), where N is the number of anchors for an image)

    ## y_true就是labels_batch

            # filter out "ignore" anchors

            indices        = backend.where(keras.backend.not_equal(anchor_state, -1))

            labels        = backend.gather_nd(labels, indices)

            classification = backend.gather_nd(classification, indices)

            # compute the focal loss

            alpha_factor = keras.backend.ones_like(labels) * alpha

            alpha_factor = backend.where(keras.backend.equal(labels, 1), alpha_factor, 1 - alpha_factor)

            focal_weight = backend.where(keras.backend.equal(labels, 1), 1 - classification, classification)

            focal_weight = alpha_factor * focal_weight ** gamma

            cls_loss = focal_weight * keras.backend.binary_crossentropy(labels, classification)

            # compute the normalizer: the number of positive anchors

            normalizer = backend.where(keras.backend.equal(anchor_state, 1))

            normalizer = keras.backend.cast(keras.backend.shape(normalizer)[0], keras.backend.floatx())

            normalizer = keras.backend.maximum(1.0, normalizer)

            return keras.backend.sum(cls_loss) / normalizer

        return _focal

    --------------------------------------------------------

    def smooth_l1(sigma=3.0):

        """ Create a smooth L1 loss functor.

        Args

            sigma: This argument defines the point where the loss changes from L2 to L1.

        Returns

            A functor for computing the smooth L1 loss given target data and predicted data.

        """

        sigma_squared = sigma ** 2

        def _smooth_l1(y_true, y_pred):

            """ Compute the smooth L1 loss of y_pred w.r.t. y_true.

            Args

                y_true: Tensor from the generator of shape (B, N, 5). The last value for each box is the state of the anchor (ignore, negative, positive).

                y_pred: Tensor from the network of shape (B, N, 4).

            Returns

                The smooth L1 loss of y_pred w.r.t. y_true.

            """

            # separate target and state

            regression        = y_pred

            regression_target = y_true[:, :, :4]

            anchor_state      = y_true[:, :, 4]

            # filter out "ignore" anchors

            indices          = backend.where(keras.backend.equal(anchor_state, 1))

            regression        = backend.gather_nd(regression, indices)

            regression_target = backend.gather_nd(regression_target, indices)

            # compute smooth L1 loss

            # f(x) = 0.5 * (sigma * x)^2          if |x| < 1 / sigma / sigma

            #        |x| - 0.5 / sigma / sigma    otherwise

            regression_diff = regression - regression_target

            regression_diff = keras.backend.abs(regression_diff)

            regression_loss = backend.where(

                keras.backend.less(regression_diff, 1.0 / sigma_squared),

                0.5 * sigma_squared * keras.backend.pow(regression_diff, 2),

                regression_diff - 0.5 / sigma_squared

            )

            # compute the normalizer: the number of positive anchors

            normalizer = keras.backend.maximum(1, keras.backend.shape(indices)[0])

            normalizer = keras.backend.cast(normalizer, dtype=keras.backend.floatx())

            return keras.backend.sum(regression_loss) / normalizer

        return _smooth_l1

    在yolo_v3中,修改这句:

    confidence_loss = object_mask * K.binary_crossentropy(object_mask, raw_pred[...,4:5], from_logits=True)+ \

                (1-object_mask) * K.binary_crossentropy(object_mask, raw_pred[...,4:5], from_logits=True) * ignore_mask

    改为:

    alpha=0.25

    gamma=2

    alpha_factor = keras.backend.ones_like(object_mask) * alpha

    alpha_factor =tf.where(keras.backend.equal(object_mask, 1), alpha_factor, 1 - alpha_factor)

    focal_weight = tf.where(keras.backend.equal(object_mask, 1), 1 - raw_pred[...,4:5], raw_pred[...,4:5])

    focal_weight = alpha_factor * focal_weight ** gamma

    confidence_loss = focal_weight * keras.backend.binary_crossentropy(object_mask, raw_pred[...,4:5],from_logits=True)

    ignore_mask呢??????

    相关文章

      网友评论

          本文标题:yolo_v3改focal loss

          本文链接:https://www.haomeiwen.com/subject/bhtbjqtx.html