Beispiel #1
0
def inference(model_config, eval_config, dataset_config, data_split,
              ckpt_indices):

    # Overwrite the defaults
    dataset_config = config_builder.proto_to_obj(dataset_config)

    dataset_config.data_split = data_split
    dataset_config.data_split_dir = 'training'
    if data_split == 'test':
        dataset_config.data_split_dir = 'testing'

    eval_config.eval_mode = 'test'
    eval_config.evaluate_repeatedly = False

    dataset_config.has_labels = False
    # Enable this to see the actually memory being used
    eval_config.allow_gpu_mem_growth = True

    eval_config = config_builder.proto_to_obj(eval_config)
    # Grab the checkpoint indices to evaluate
    eval_config.ckpt_indices = ckpt_indices

    # Remove augmentation during evaluation in test mode
    dataset_config.aug_list = []

    # Build the dataset object
    dataset = DatasetBuilder.build_kitti_dataset(dataset_config,
                                                 use_defaults=False)

    # Setup the model
    model_name = model_config.model_name
    # Overwrite repeated field
    model_config = config_builder.proto_to_obj(model_config)
    # Switch path drop off during evaluation
    model_config.path_drop_probabilities = [1.0, 1.0]

    with tf.Graph().as_default():
        if model_name == 'mlod_model':
            model = MlodModel(model_config,
                              train_val_test=eval_config.eval_mode,
                              dataset=dataset)
        elif model_name == 'rpn_model':
            model = RpnModel(model_config,
                             train_val_test=eval_config.eval_mode,
                             dataset=dataset)
        else:
            raise ValueError('Invalid model name {}'.format(model_name))

        model_evaluator = Evaluator(model, dataset_config, eval_config)
        model_evaluator.run_latest_checkpoints()
Beispiel #2
0
def set_up_model():

    test_pipeline_config_path = mlod.root_dir() + \
        '/configs/mlod_exp_example.config'
    model_config, train_config, _, dataset_config = \
        config_builder.get_configs_from_pipeline_file(
            test_pipeline_config_path, is_training=True)

    dataset_config = config_builder.proto_to_obj(dataset_config)

    train_val_test = 'test'
    dataset_config.data_split = 'test'
    dataset_config.data_split_dir = 'testing'
    dataset_config.has_labels = False
    dataset_config.aug_list = []

    dataset = DatasetBuilder.build_kitti_dataset(dataset_config,
                                                 use_defaults=False)

    model_name = model_config.model_name
    if model_name == 'rpn_model':
        model = RpnModel(model_config,
                         train_val_test=train_val_test,
                         dataset=dataset)
    elif model_name == 'mlod_model':
        model = MlodModel(model_config,
                          train_val_test=train_val_test,
                          dataset=dataset)
    else:
        raise ValueError('Invalid model_name')

    return model
Beispiel #3
0
def set_up_model_test_mode(pipeline_config_path, data_split):
    """Returns the model and its config in test mode."""

    model_config, _, _,  dataset_config = \
        config_builder.get_configs_from_pipeline_file(
            pipeline_config_path, is_training=False)

    dataset = DatasetBuilder.build_kitti_dataset(dataset_config,
                                                 use_defaults=False)

    # Overwrite the defaults
    dataset_config = config_builder.proto_to_obj(dataset_config)

    # Use the validation set
    dataset_config.data_split = data_split
    dataset_config.data_split_dir = 'training'
    if data_split == 'test':
        dataset_config.data_split_dir = 'testing'

    # Remove augmentation when in test mode
    dataset_config.aug_list = []

    # Build the dataset object
    dataset = DatasetBuilder.build_kitti_dataset(dataset_config,
                                                 use_defaults=False)

    model_name = model_config.model_name
    if model_name == 'rpn_model':
        model = RpnModel(model_config, train_val_test='test', dataset=dataset)
    elif model_name == 'mlod_model':
        model = MlodModel(model_config, train_val_test='test', dataset=dataset)
    else:
        raise ValueError('Invalid model_name')

    return model, model_config
Beispiel #4
0
    def test_path_drop_weights(self):
        # Tests the effect of path-drop on network's feature maps.
        # It sets up a minimal-training process to check the
        # feature before and after running the 'train_op' while
        # path-drop is in effect.

        train_val_test = 'train'
        # overwrite the training iterations
        self.train_config.max_iterations = 2
        self.train_config.overwrite_checkpoints = True

        # Overwrite path drop probabilities
        model_config = config_builder.proto_to_obj(self.model_config)
        model_config.path_drop_probabilities = [0.0, 0.8]

        with tf.Graph().as_default():
            # Set a graph-level seed
            tf.set_random_seed(1245)
            model = RpnModel(model_config,
                             train_val_test=train_val_test,
                             dataset=self.dataset)
            prediction_dict = model.build()
            losses_dict, total_loss = model.loss(prediction_dict)

            global_summaries = set([])
            # Optimizer
            training_optimizer = optimizer_builder.build(
                self.train_config.optimizer, global_summaries)
            train_op = slim.learning.create_train_op(total_loss,
                                                     training_optimizer)

            init_op = tf.global_variables_initializer()

            with tf.Session() as sess:
                sess.run(init_op)
                for step in range(1, self.train_config.max_iterations):
                    feed_dict = model.create_feed_dict()
                    if step == 1:
                        current_feature_maps = sess.run(model.img_feature_maps,
                                                        feed_dict=feed_dict)
                        exp_feature_maps = current_feature_maps
                    train_op_loss = sess.run(train_op, feed_dict=feed_dict)
                    print('Step {}, Total Loss {:0.3f} '.format(
                        step, train_op_loss))

                    updated_feature_maps = sess.run(model.img_feature_maps,
                                                    feed_dict=feed_dict)
            # The feature maps should have remained the same since
            # the image path was dropped
            np.testing.assert_array_almost_equal(updated_feature_maps,
                                                 exp_feature_maps,
                                                 decimal=4)
Beispiel #5
0
def set_up_video_dataset(dataset_config, dataset_dir, data_split,
                         data_split_dir):

    # Overwrite fields
    dataset_config.name = 'kitti_video'
    dataset_config.dataset_dir = dataset_dir
    dataset_config.data_split = data_split
    dataset_config.data_split_dir = data_split_dir
    dataset_config.has_labels = False

    # Overwrite repeated fields
    dataset_config = config_builder_util.proto_to_obj(dataset_config)
    dataset_config.aug_list = []

    dataset = DatasetBuilder.build_kitti_dataset(dataset_config,
                                                 use_defaults=False)

    return dataset
Beispiel #6
0
    def test_disable_path_drop(self):
        # Test path drop is disabled when the probabilities
        # are set to 1.0.

        train_val_test = 'train'
        # Overwrite path drop probabilities
        model_config = config_builder.proto_to_obj(self.model_config)
        model_config.path_drop_probabilities = [1.0, 1.0]

        with tf.Graph().as_default():
            model = RpnModel(model_config,
                             train_val_test=train_val_test,
                             dataset=self.dataset)
            model.build()
            # These variables are set during path drop only
            # in the case of no path-drop, they should be non-existence
            self.assertFalse(hasattr(model, 'img_path_drop_mask'))
            self.assertFalse(hasattr(model, 'bev_path_drop_mask'))
Beispiel #7
0
def main():
    """ Converts a set of network predictions into text files required for
    KITTI evaluation.
    """

    ##############################
    # Options
    ##############################
    checkpoint_name = 'mlod_exp_example'

    # data_split = 'val'
    data_split = 'val_half'

    global_steps = None
    # global_steps = [28000, 19000, 33000, 34000]

    score_threshold = 0.1

    save_2d = False  # Save 2D predictions
    save_3d = True  # Save 2D and 3D predictions together

    # Checkpoints below this are skipped
    min_step = 20000
    # Object Type
    obj_type = 'obj'
    ##############################
    # End of Options
    ##############################

    # Parse experiment config
    pipeline_config_file = \
        mlod.root_dir() + '/data/outputs/' + checkpoint_name + \
        '/' + checkpoint_name + '.config'
    _, _, _, dataset_config = \
        config_builder_util.get_configs_from_pipeline_file(
            pipeline_config_file, is_training=False)

    # Overwrite defaults
    dataset_config = config_builder_util.proto_to_obj(dataset_config)
    dataset_config.data_split = data_split
    dataset_config.aug_list = []

    if data_split == 'test':
        dataset_config.data_split_dir = 'testing'

    dataset = DatasetBuilder.build_kitti_dataset(dataset_config,
                                                 use_defaults=False)

    # Get available prediction folders
    predictions_root_dir = mlod.root_dir() + '/data/outputs/' + \
        checkpoint_name + '/predictions'

    proposals_root_dir = predictions_root_dir + \
        '/proposals_and_scores/' + dataset.data_split

    print('Converting proposals from', proposals_root_dir)

    if not global_steps:
        global_steps = os.listdir(proposals_root_dir)
        global_steps.sort(key=int)
        print('Checkpoints found ', global_steps)

    for step_idx in range(len(global_steps)):

        global_step = global_steps[step_idx]

        # Skip first checkpoint
        if int(global_step) < min_step:
            continue

        final_predictions_dir = proposals_root_dir + \
            '/' + str(global_step)

        # 2D and 3D prediction directories
        kitti_predictions_2d_dir = predictions_root_dir + \
            '/kitti_proposals_2d/' + \
            dataset.data_split + '/' + \
            str(score_threshold) + '/' + \
            str(global_step) + '/data'
        kitti_proposals_3d_dir = predictions_root_dir + \
            '/kitti_proposals_3d/' + \
            dataset.data_split + '/' + \
            str(score_threshold) + '/' + \
            str(global_step) + '/data'

        if save_2d and not os.path.exists(kitti_predictions_2d_dir):
            os.makedirs(kitti_predictions_2d_dir)
        if save_3d and not os.path.exists(kitti_proposals_3d_dir):
            os.makedirs(kitti_proposals_3d_dir)

        # Do conversion
        num_samples = dataset.num_samples
        num_valid_samples = 0

        print('\nGlobal step:', global_step)
        print('Converting proposals from:', final_predictions_dir)

        if save_2d:
            print('2D Detections saved to:', kitti_predictions_2d_dir)
        if save_3d:
            print('Proposals saved to:', kitti_proposals_3d_dir)

        for sample_idx in range(num_samples):

            # Print progress
            sys.stdout.write('\rConverting {} / {}'.format(
                sample_idx + 1, num_samples))
            sys.stdout.flush()

            sample_name = dataset.sample_names[sample_idx]

            prediction_file = sample_name + '.txt'

            kitti_predictions_2d_file_path = kitti_predictions_2d_dir + \
                '/' + prediction_file
            kitti_predictions_3d_file_path = kitti_proposals_3d_dir + \
                '/' + prediction_file

            predictions_file_path = final_predictions_dir + \
                '/' + prediction_file

            # If no predictions, skip to next file
            if not os.path.exists(predictions_file_path):
                if save_2d:
                    np.savetxt(kitti_predictions_2d_file_path, [])
                if save_3d:
                    np.savetxt(kitti_predictions_3d_file_path, [])
                continue

            all_predictions = np.loadtxt(predictions_file_path)

            # Swap l, w for predictions where w > l
            swapped_indices = all_predictions[:, 4] > all_predictions[:, 3]
            fixed_predictions = np.copy(all_predictions)
            fixed_predictions[swapped_indices,
                              3] = all_predictions[swapped_indices, 4]
            fixed_predictions[swapped_indices,
                              4] = all_predictions[swapped_indices, 3]
            fixed_predictions[swapped_indices, 6] = np.pi / 2

            score_filter = all_predictions[:, 7] >= score_threshold
            all_predictions = fixed_predictions[score_filter]

            # If no predictions, skip to next file
            if len(all_predictions) == 0:
                if save_2d:
                    np.savetxt(kitti_predictions_2d_file_path, [])
                if save_3d:
                    np.savetxt(kitti_predictions_3d_file_path, [])
                continue

            # Project to image space
            sample_name = prediction_file.split('.')[0]
            img_idx = int(sample_name)

            # Load image for truncation
            image = Image.open(dataset.get_rgb_image_path(sample_name))
            stereo_calib_p2 = calib_utils.read_calibration(
                dataset.calib_dir, img_idx).p2

            boxes = []
            image_filter = []
            for i in range(len(all_predictions)):
                box_3d = all_predictions[i, 0:7]
                img_box = box_3d_projector.project_to_image_space(
                    box_3d,
                    stereo_calib_p2,
                    truncate=True,
                    image_size=image.size,
                    discard_before_truncation=False)

                # Skip invalid boxes (outside image space)
                if img_box is None:
                    image_filter.append(False)
                else:
                    image_filter.append(True)
                    boxes.append(img_box)

            boxes = np.asarray(boxes)
            all_predictions = all_predictions[image_filter]

            # If no predictions, skip to next file
            if len(boxes) == 0:
                if save_2d:
                    np.savetxt(kitti_predictions_2d_file_path, [])
                if save_3d:
                    np.savetxt(kitti_predictions_3d_file_path, [])
                continue

            num_valid_samples += 1

            # To keep each value in its appropriate position, an array of zeros
            # (N, 16) is allocated but only values [4:16] are used
            kitti_predictions = np.zeros([len(boxes), 16])

            # Truncation and Occlusion are always empty (see below)

            # Alpha (Not computed)
            kitti_predictions[:, 3] = -10 * np.ones(
                (len(kitti_predictions)), dtype=np.int32)

            # 2D predictions
            kitti_predictions[:, 4:8] = boxes[:, 0:4]

            # 3D predictions
            # (l, w, h)
            kitti_predictions[:, 8] = all_predictions[:, 5]
            kitti_predictions[:, 9] = all_predictions[:, 4]
            kitti_predictions[:, 10] = all_predictions[:, 3]
            # (x, y, z)
            kitti_predictions[:, 11:14] = all_predictions[:, 0:3]
            # (ry, score)
            kitti_predictions[:, 14:16] = all_predictions[:, 6:8]

            # Round detections to 3 decimal places
            kitti_predictions = np.round(kitti_predictions, 3)

            # Empty Truncation, Occlusion
            kitti_empty_1 = -1 * np.ones(
                (len(kitti_predictions), 2), dtype=np.int32)
            # Empty 3D (x, y, z)
            kitti_empty_2 = -1 * np.ones(
                (len(kitti_predictions), 3), dtype=np.int32)
            # Empty 3D (h, w, l)
            kitti_empty_3 = -1000 * np.ones(
                (len(kitti_predictions), 3), dtype=np.int32)
            # Empty 3D (ry)
            kitti_empty_4 = -10 * np.ones(
                (len(kitti_predictions), 1), dtype=np.int32)

            # Create Type Array
            obj_types = [obj_type for i in range(len(kitti_predictions))]

            # Stack 2D predictions text
            kitti_text_2d = np.column_stack([
                obj_types, kitti_empty_1, kitti_predictions[:, 3:8],
                kitti_empty_2, kitti_empty_3, kitti_empty_4,
                kitti_predictions[:, 15]
            ])

            # Stack 3D predictions text
            kitti_text_3d = np.column_stack(
                [obj_types, kitti_empty_1, kitti_predictions[:, 3:16]])

            # Save to text files
            if save_2d:
                np.savetxt(kitti_predictions_2d_file_path,
                           kitti_text_2d,
                           newline='\r\n',
                           fmt='%s')
            if save_3d:
                np.savetxt(kitti_predictions_3d_file_path,
                           kitti_text_3d,
                           newline='\r\n',
                           fmt='%s')

        print('\nNum valid:', num_valid_samples)
        print('Num samples:', num_samples)
model_config, _, eval_config, dataset_config = \
    config_builder.get_configs_from_pipeline_file(
        args.pipeline_config_path,
        is_training=False)

# Overwrite data split
dataset_config.data_split = 'trainval'

dataset_config.data_split_dir = 'training'
dataset_config.has_labels = True

# Set CUDA device id
os.environ['CUDA_VISIBLE_DEVICES'] = args.device

# Convert to object to overwrite repeated fields
dataset_config = config_builder.proto_to_obj(dataset_config)

# Remove augmentation during evaluation
dataset_config.aug_list = ['flipping']

# Build the dataset object
dataset = DatasetBuilder.build_kitti_dataset(dataset_config,
                                             use_defaults=False)

# Setup the model
model_name = model_config.model_name

# Convert to object to overwrite repeated fields
model_config = config_builder.proto_to_obj(model_config)

# Switch path drop off during evaluation