Esempio n. 1
0
def _build_cls_off_ang_loss(model, prediction_dict):
    """Builds classification, offset, and angle vector losses.

    Args:
        model: network model
        prediction_dict: prediction dictionary

    Returns:
        losses_output: losses dictionary
    """

    # Minibatch Predictions
    mb_cls_logits = prediction_dict[model.PRED_MB_CLASSIFICATION_LOGITS]
    mb_cls_softmax = prediction_dict[model.PRED_MB_CLASSIFICATION_SOFTMAX]
    mb_offsets = prediction_dict[model.PRED_MB_OFFSETS]
    mb_angle_vectors = prediction_dict[model.PRED_MB_ANGLE_VECTORS]

    # Ground Truth
    mb_cls_gt = prediction_dict[model.PRED_MB_CLASSIFICATIONS_GT]
    mb_offsets_gt = prediction_dict[model.PRED_MB_OFFSETS_GT]
    mb_orientations_gt = prediction_dict[model.PRED_MB_ORIENTATIONS_GT]

    mb_pos_gt = tf.cast(tf.greater(tf.argmax(mb_cls_gt, axis=1), 0), tf.float32)
    mb_neg_gt = tf.cast(tf.equal(tf.argmax(mb_cls_gt, axis=1), 0), tf.float32)

    # Decode ground truth orientations
    with tf.variable_scope('avod_gt_angle_vectors'):
        mb_angle_vectors_gt = \
            orientation_encoder.tf_orientation_to_angle_vector(
                mb_orientations_gt)

    # Losses
    with tf.variable_scope('avod_losses'):
        with tf.variable_scope('classification'):
            cls_loss, acc_all, acc_pos = _get_cls_loss(model, mb_cls_logits, mb_cls_gt, mb_pos_gt, mb_neg_gt)

        with tf.variable_scope('regression'):
            final_reg_loss, offset_loss_norm, ang_loss_norm = _get_off_ang_loss(
                model, mb_offsets, mb_offsets_gt,
                mb_angle_vectors, mb_angle_vectors_gt,
                mb_cls_softmax, mb_cls_gt)

        with tf.variable_scope('avod_loss'):
            avod_loss = cls_loss + final_reg_loss
            tf.summary.scalar('avod_loss', avod_loss)

    # Loss dictionary
    losses_output = dict()

    losses_output[KEY_CLASSIFICATION_LOSS] = cls_loss
    losses_output[KEY_REGRESSION_LOSS] = final_reg_loss
    losses_output[KEY_AVOD_LOSS] = avod_loss

    # Separate losses for plotting
    losses_output[KEY_OFFSET_LOSS_NORM] = offset_loss_norm
    losses_output[KEY_ANG_LOSS_NORM] = ang_loss_norm

    return losses_output, acc_all, acc_pos
    def test_two_way_conversion(self):
        # Test conversion for angles between [-pi, pi] with 0.5 degree steps
        np_orientations = np.arange(np.pi, np.pi, np.pi / 360.0)

        tf_angle_vectors = orientation_encoder.tf_orientation_to_angle_vector(
            np_orientations)
        tf_orientations = orientation_encoder.tf_angle_vector_to_orientation(
            tf_angle_vectors)

        # Check that conversion from orientation -> angle vector ->
        # orientation results in the same values
        with self.test_session() as sess:
            orientations_out = sess.run(tf_orientations)
            np.testing.assert_allclose(orientations_out, np_orientations)
    def test_tf_orientation_to_angle_vector(self):
        # Test conversion for angles between [-pi, pi] with 0.5 degree steps
        np_orientations = np.arange(-np.pi, np.pi, np.pi / 360.0)

        expected_angle_vectors = np.stack(
            [np.cos(np_orientations),
             np.sin(np_orientations)], axis=1)

        # Convert to tensors and convert to angle unit vectors
        tf_orientations = tf.convert_to_tensor(np_orientations)
        tf_angle_vectors = orientation_encoder.tf_orientation_to_angle_vector(
            tf_orientations)

        with self.test_session() as sess:
            angle_vectors_out = sess.run(tf_angle_vectors)

            np.testing.assert_allclose(angle_vectors_out,
                                       expected_angle_vectors)
    def loss(self, prediction_dict):
        # Fetch the ground truth values
        location_gt = prediction_dict[self.PRED_LOCATION_GT]
        orientation_gt = prediction_dict[self.PRED_ORIENT_GT]
        orientation_vec_gt = orientation_encoder.tf_orientation_to_angle_vector(
            orientation_gt)
        size_gt = prediction_dict[self.PRED_SIZE_GT]

        # Fetch the prediction values
        with tf.variable_scope('epbrm_prediction_batch'):
            location_pred = prediction_dict[self.PRED_LOCATION]
            orientation_vec_pred = prediction_dict[self.PRED_ORIENT]
            size_pred = prediction_dict[self.PRED_SIZE]
        # Calculate the losses
        with tf.variable_scope('epbrm_losses'):
            # Location loss
            with tf.variable_scope('location'):
                # Fetch the loss function
                reg_loss = losses.WeightedSmoothL1Loss()

                location_loss = reg_loss(location_pred,
                                         location_gt,
                                         weight=5.0)
            # Size loss
            with tf.variable_scope('size'):
                # Fetch the loss function
                reg_loss = losses.WeightedSmoothL1Loss()

                size_loss = reg_loss(size_pred, size_gt, weight=5.0)

            # Orientation loss
            with tf.variable_scope('orientation'):
                # Fetch the loss function
                reg_loss = losses.WeightedSmoothL1Loss()

                orientation_loss = reg_loss(orientation_vec_pred,
                                            orientation_vec_gt,
                                            weight=1.0)
        with tf.variable_scope('epBRM_loss'):
            total_loss = tf.reduce_sum(location_loss) + tf.reduce_sum(
                size_loss) + tf.reduce_sum(orientation_loss)
        return total_loss