def testPerfectBox(self):
        metadata = waymo_metadata.WaymoMetadata()
        params = waymo_ap_metric.WaymoAPMetrics.Params(metadata)
        m = params.Instantiate()
        # Make one update with a perfect box.
        update_dict = py_utils.NestedMap(
            groundtruth_labels=np.array([1]),
            groundtruth_bboxes=np.ones(shape=(1, 7)),
            groundtruth_difficulties=np.zeros(shape=(1)),
            groundtruth_num_points=None,
            detection_scores=np.ones(shape=(5, 1)),
            detection_boxes=np.ones(shape=(5, 1, 7)),
            detection_heights_in_pixels=np.ones(shape=(5, 1)))

        m.Update('1234', update_dict)

        waymo_ap = m.value
        self.assertAllClose(waymo_ap, 1. / 3.)

        # Write a summary.
        summary = m.Summary('foo')
        # Check that both AP and APH are in the tags.
        tags = [v.tag for v in summary.value]
        self.assertIn('foo/Pedestrian/AP_default', tags)
        self.assertIn('foo/Pedestrian/APH_default', tags)
Beispiel #2
0
def _FilterKeepLabels(params, label_names):
    """Keep only label names in 'label_names' from input."""
    metadata = waymo_metadata.WaymoMetadata()
    filtered_labels = [
        metadata.ClassNames().index(label_name) for label_name in label_names
    ]
    params.extractors.labels.filter_labels = filtered_labels
Beispiel #3
0
 def Params(cls):
     p = super(WaymoOpenDatasetDecoder, cls).Params()
     p.Define(
         'draw_visualizations', True, 'Boolean for whether to draw '
         'visualizations. This is independent of laser_sampling_rate.')
     p.ap_metric = waymo_ap_metric.WaymoAPMetrics.Params(
         waymo_metadata.WaymoMetadata())
     return p
Beispiel #4
0
    def testWaymoBreakdowns(self):
        metadata = waymo_metadata.WaymoMetadata()
        params = waymo_ap_metric.WaymoAPMetrics.Params(metadata)
        params.waymo_breakdown_metrics = ['RANGE', 'VELOCITY']

        m = params.Instantiate()
        # Make one update with a perfect box.
        update_dict = py_utils.NestedMap(
            groundtruth_labels=np.array([1]),
            groundtruth_bboxes=np.ones(shape=(1, 7)),
            groundtruth_difficulties=np.zeros(shape=(1)),
            groundtruth_num_points=None,
            groundtruth_speed=np.zeros(shape=(1, 2)),
            detection_scores=np.ones(shape=(5, 1)),
            detection_boxes=np.ones(shape=(5, 1, 7)),
            detection_heights_in_pixels=np.ones(shape=(5, 1)))

        m.Update('1234', update_dict)

        # Write a summary.
        summary = m.Summary('foo')
        # Check that the summary value for default ap and
        # a waymo breakdown version by range is the same.
        for v in summary.value:
            if v.tag == 'foo/Vehicle/AP_LEVEL_1':
                default_val = v.simple_value
            elif v.tag == 'foo/Vehicle/APH_LEVEL_1':
                aph_default_val = v.simple_value
            elif v.tag == 'foo_extra/AP_RANGE_TYPE_VEHICLE_[0, 30)_LEVEL_1':
                ap_bd_val_l1 = v.simple_value
            elif v.tag == 'foo_extra/AP_RANGE_TYPE_VEHICLE_[0, 30)_LEVEL_2':
                ap_bd_val_l2 = v.simple_value
            elif v.tag == 'foo_extra/APH_RANGE_TYPE_VEHICLE_[0, 30)_LEVEL_1':
                aph_bd_val_l1 = v.simple_value
            elif v.tag == 'foo_extra/APH_RANGE_TYPE_VEHICLE_[0, 30)_LEVEL_2':
                aph_bd_val_l2 = v.simple_value
            elif v.tag == 'foo_extra/AP_VELOCITY_TYPE_VEHICLE_STATIONARY_LEVEL_1':
                vbd_val_l1 = v.simple_value
            elif v.tag == 'foo_extra/AP_VELOCITY_TYPE_VEHICLE_STATIONARY_LEVEL_2':
                vbd_val_l2 = v.simple_value

        self.assertEqual(ap_bd_val_l1, default_val)
        self.assertEqual(ap_bd_val_l2, default_val)
        self.assertEqual(aph_bd_val_l1, aph_default_val)
        self.assertEqual(aph_bd_val_l2, aph_default_val)
        self.assertEqual(vbd_val_l1, default_val)
        self.assertEqual(vbd_val_l2, default_val)

        # Check that eval classes not evaluated are not present.
        tags = [v.tag for v in summary.value]
        self.assertNotIn('foo_extra/APH_RANGE_TYPE_SIGN_[0, 30)_LEVEL_1', tags)
        self.assertNotIn('foo_extra/APH_RANGE_TYPE_SIGN_[0, 30)_LEVEL_2', tags)
Beispiel #5
0
 def Params(cls):
     p = super(WaymoOpenDatasetDecoder, cls).Params()
     p.Define(
         'draw_visualizations', False, 'Boolean for whether to draw '
         'visualizations. This is independent of laser_sampling_rate.')
     p.ap_metric = waymo_ap_metric.WaymoAPMetrics.Params(
         waymo_metadata.WaymoMetadata())
     p.Define(
         'extra_ap_metrics', {},
         'Dictionary of extra AP metrics to run in the decoder. The key'
         'is the name of the metric and the value is a sub-class of '
         'APMetric')
     return p
Beispiel #6
0
def build_waymo_metric(pred_bbox,
                       pred_class_id,
                       pred_class_score,
                       pred_frame_id,
                       gt_bbox,
                       gt_class_id,
                       gt_frame_id,
                       gt_speed,
                       box_type='3d',
                       breakdowns=None):
    """Build waymo evaluation metric."""
    metadata = waymo_metadata.WaymoMetadata()
    if breakdowns is None:
        breakdowns = ['RANGE']
    waymo_metric_config = _build_waymo_metric_config(metadata, box_type,
                                                     breakdowns)

    ap, ap_ha, pr, pr_ha, _ = py_metrics_ops.detection_metrics(
        prediction_bbox=pred_bbox,
        prediction_type=pred_class_id,
        prediction_score=pred_class_score,
        prediction_frame_id=tf.cast(pred_frame_id, tf.int64),
        prediction_overlap_nlz=tf.zeros_like(pred_frame_id, dtype=tf.bool),
        ground_truth_bbox=gt_bbox,
        ground_truth_type=gt_class_id,
        ground_truth_frame_id=tf.cast(gt_frame_id, tf.int64),
        ground_truth_difficulty=tf.zeros_like(gt_frame_id, dtype=tf.uint8),
        ground_truth_speed=gt_speed,
        config=waymo_metric_config.SerializeToString())

    # All tensors returned by Waymo's metric op have a leading dimension
    # B=number of breakdowns. At this moment we always use B=1 to make
    # it compatible to the python code.
    scalar_metrics = {
        '%s_ap' % box_type: ap[0],
        '%s_ap_ha_weighted' % box_type: ap_ha[0]
    }
    curve_metrics = {
        '%s_pr' % box_type: pr[0],
        '%s_pr_ha_weighted' % box_type: pr_ha[0]
    }

    breakdown_names = config_util.get_breakdown_names_from_config(
        waymo_metric_config)
    for i, metric in enumerate(breakdown_names):
        # There is a scalar / curve for every breakdown.
        scalar_metrics['%s_ap_%s' % (box_type, metric)] = ap[i]
        scalar_metrics['%s_ap_ha_weighted_%s' % (box_type, metric)] = ap_ha[i]
        curve_metrics['%s_pr_%s' % (box_type, metric)] = pr[i]
        curve_metrics['%s_pr_ha_weighted_%s' % (box_type, metric)] = pr_ha[i]
    return scalar_metrics, curve_metrics
    def testWaymoAPConfig(self):
        metadata = waymo_metadata.WaymoMetadata()
        # Use 2D metric.
        config = waymo_ap_metric._BuildWaymoMetricConfig(metadata, '2d', [])
        vehicle_idx = label_pb2.Label.Type.Value('TYPE_VEHICLE')
        ped_idx = label_pb2.Label.Type.Value('TYPE_PEDESTRIAN')
        cyc_idx = label_pb2.Label.Type.Value('TYPE_CYCLIST')

        thresholds_meta = metadata.IoUThresholds()
        self.assertNear(config.iou_thresholds[vehicle_idx],
                        thresholds_meta['Vehicle'], 1e-6)
        self.assertNear(config.iou_thresholds[ped_idx],
                        thresholds_meta['Pedestrian'], 1e-6)
        self.assertNear(config.iou_thresholds[cyc_idx],
                        thresholds_meta['Cyclist'], 1e-6)
Beispiel #8
0
    def Task(self):
        p = super(StarNetVehicle, self).Task()
        p.train.l2_regularizer_weight = 3e-5

        class_names = waymo_metadata.WaymoMetadata().ClassNames()
        num_classes = len(class_names)

        p.per_class_loss_weight = [0.] * num_classes
        p.per_class_loss_weight[class_names.index('Vehicle')] = 1.0

        # See WaymoMetadata.EvalClassIndices for correspondences for metric_weights.
        p.output_decoder.ap_metric.metric_weights = {
            'default': np.array([1.0, 0.0, 0.0]),
        }
        p.nms_iou_threshold[class_names.index('Vehicle')] = 0.03
        p.nms_score_threshold[class_names.index('Vehicle')] = 0.31
        return p
Beispiel #9
0
 def Params(cls):
   p = super().Params()
   p.Define(
       'draw_visualizations', False, 'Boolean for whether to draw '
       'visualizations. This is independent of laser_sampling_rate.')
   p.ap_metric = waymo_ap_metric.WaymoAPMetrics.Params(
       waymo_metadata.WaymoMetadata())
   p.Define(
       'extra_ap_metrics', {},
       'Dictionary of extra AP metrics to run in the decoder. The key'
       'is the name of the metric and the value is a sub-class of '
       'APMetric')
   p.Define(
       'save_residuals', False,
       'If True, this expects the residuals and ground-truth to be available '
       'in the decoder output dictionary, and it will save it to the decoder '
       'output file. See decode_include_residuals in PointDetectorBase '
       'for details.')
   return p
  def testPerfectBox(self):
    metadata = waymo_metadata.WaymoMetadata()
    params = waymo_ap_metric.WaymoAPMetrics.Params(metadata)
    m = params.Instantiate()
    # Make one update with a perfect box.
    update_dict = py_utils.NestedMap(
        groundtruth_labels=np.array([1]),
        groundtruth_bboxes=np.ones(shape=(1, 7)),
        groundtruth_difficulties=np.zeros(shape=(1)),
        groundtruth_num_points=None,
        detection_scores=np.ones(shape=(5, 1)),
        detection_boxes=np.ones(shape=(5, 1, 7)),
        detection_heights_in_pixels=np.ones(shape=(5, 1)))

    m.Update('1234', update_dict)

    waymo_ap = m._AveragePrecisionByDifficulty()
    self.assertAllClose(waymo_ap['default'][0], 1.)
    self.assertTrue(np.isnan(waymo_ap['default'][1]))
Beispiel #11
0
    def Task(self):
        metadata = waymo_metadata.WaymoMetadata()
        num_classes = len(metadata.ClassNames())
        p = starnet.ModelV2.Params(
            num_classes,
            num_anchor_bboxes_offsets=self.NUM_ANCHOR_BBOX_OFFSETS,
            num_anchor_bboxes_rotations=self.NUM_ANCHOR_BBOX_ROTATIONS,
            num_anchor_bboxes_dimensions=self.NUM_ANCHOR_BBOX_DIMENSIONS,
            num_laser_features=3)

        # Update the Point Cloud Featurizer architecture
        starnet_builder = starnet.Builder()
        starnet_builder.linear_params_init = (
            py_utils.WeightInit.KaimingUniformFanInRelu())

        gin_layers = [[
            self.GIN_HIDDEN_DIMS * 2, self.GIN_HIDDEN_DIMS * 4,
            self.GIN_HIDDEN_DIMS
        ]] * self.NUM_GIN_LAYERS  # pyformat: disable

        p.cell_featurizer = starnet_builder.GINFeaturizerV2(
            'feat',
            num_laser_features=3,
            fc_dims=self.GIN_HIDDEN_DIMS,
            mlp_dims=gin_layers,
            fc_use_bn=False)
        p.cell_feature_dims = self.GIN_HIDDEN_DIMS * (self.NUM_GIN_LAYERS + 1)

        p.output_decoder = waymo_decoder.WaymoOpenDatasetDecoder.Params()
        p.max_nms_boxes = 512
        p.use_oriented_per_class_nms = True

        # Note: Sub-classes need to set nms_iou_threshold and nms_score_threshold
        # appropriately.
        p.nms_iou_threshold = [0.0] * num_classes

        # TODO(jngiam): 1.1 for untrained classes is needed to avoid an issue
        # with boxutils error.
        p.nms_score_threshold = [1.1] * num_classes

        p.name = 'starnet'
        tp = p.train
        tp.optimizer = optimizer.Adam.Params()
        tp.clip_gradient_norm_to_value = 5

        ep = p.eval

        # Train set uses a smaller decoding set, so we can
        # safely eval over the entire input.
        ep.samples_per_summary = 0

        # To be tuned.
        p.train.l2_regularizer_weight = 1e-8

        cluster = cluster_factory.Current()
        train_cluster_p = cluster.params.Copy()
        train_cluster_p.job = 'trainer_client'
        train_cluster_p.mode = 'sync'

        # When running a decoding only job, there are no trainer workers, so we set
        # worker replicas to 1 as a dummy value.
        if train_cluster_p.worker.replicas <= 0:
            train_cluster_p.worker.replicas = 1

        # Set learning rate and schedule.
        with cluster_factory.Cluster(train_cluster_p):
            train_input_p = self.Train()

        # Adapted from V1 tuning.
        tp.ema_decay = 0.99
        # TODO(b/148537111): consider setting this to True.
        tp.ema_decay_moving_vars = False
        tp.learning_rate = 0.001
        lr_util.SetExponentialLR(train_p=tp,
                                 train_input_p=train_input_p,
                                 exp_start_epoch=5,
                                 total_epoch=75)

        p.dimension_loss_weight = .3
        p.location_loss_weight = 3.
        p.loss_weight_classification = 1.
        p.loss_weight_localization = 3.
        p.rotation_loss_weight = 0.3

        return p