Example #1
0
    def GenerateSummaries(self, name):
        """Generate an image summary for max recall by number of points by class."""
        image_summaries = self._GenerateCumulativeSummaries(name)
        p = self.params

        legend_names = []
        for j in p.metadata.EvalClassIndices():
            legend_names.append(p.metadata.ClassNames()[j])

        num_points_bins = self._values.shape[0]
        ys = np.zeros(shape=(num_points_bins,
                             len(p.metadata.EvalClassIndices())),
                      dtype=np.float32)

        for num_points in self._precision_recall:
            ys[num_points, :] = _FindMaximumRecall(
                self._precision_recall[num_points])

        def _Setter(fig, axes):
            """Configure the plot for max recall versus number of points."""
            axes.grid(b=True)
            fontsize = 14
            for i, j in enumerate(p.metadata.EvalClassIndices()):
                for n, x in enumerate(self._values):
                    h = self._histogram[n][j]
                    y = min(ys[n][i] + 0.03, 1.0)
                    if h > 0:
                        text_label = '{} {}s'.format(
                            h, legend_names[i].lower()[:3])
                        axes.text(x,
                                  y,
                                  text_label,
                                  fontdict={'fontsize': fontsize - 2})

            axes.set_xlabel('number of points', fontsize=fontsize)
            axes.set_xticks(self._values)
            axes.set_ylabel('maximum recall', fontsize=fontsize)
            axes.set_ylim([-0.01, 1.05])
            axes.set_xlim([(1.0 / 1.3) * self._values[0],
                           1.3 * self._values[-1]])
            axes.set_yticks(np.arange(0.0, 1.05, 0.1))
            axes.set_xscale('log')
            axes.legend([name.lower() for name in legend_names],
                        numpoints=1,
                        loc='upper left')
            fig.tight_layout()

        tag_str = '{}/recall_by_num_points'.format(name)
        image_summary = plot.Curve(name=tag_str,
                                   figsize=(10, 8),
                                   xs=self._values,
                                   ys=ys,
                                   setter=_Setter,
                                   marker='.',
                                   markersize=14,
                                   linestyle='-',
                                   linewidth=2,
                                   alpha=0.5)
        image_summaries.append(image_summary)
        return image_summaries
Example #2
0
    def GenerateSummaries(self, name):
        """Generate an image summary for AP versus rotation by class."""
        p = self.params
        legend_names = []
        for j in p.metadata.EvalClassIndices():
            legend_names.append(p.metadata.ClassNames()[j])

        num_rotations = self._values.shape[0]
        rotation_in_degrees = self._values * 180.0 / np.pi
        ys = np.zeros(shape=(num_rotations,
                             len(p.metadata.EvalClassIndices())),
                      dtype=np.float32)

        for rotation in self._precision_recall:
            ys[rotation, :] = _FindMaximumRecall(
                self._precision_recall[rotation])

        def _Setter(fig, axes):
            """Configure the plot for max recall versus distance."""
            axes.grid(b=True)
            fontsize = 14
            for i, j in enumerate(p.metadata.EvalClassIndices()):
                for r, x in enumerate(rotation_in_degrees):
                    h = self._histogram[r][j]
                    y = min(ys[r][i] + 0.03, 1.0)
                    text_label = '{} {}s'.format(h,
                                                 legend_names[i].lower()[:3])
                    axes.text(x,
                              y,
                              text_label,
                              fontdict={'fontsize': fontsize - 2})

            axes.set_xlabel('rotation (degrees)', fontsize=fontsize)
            bin_width = (p.metadata.MaximumRotation() /
                         float(self.NumBinsOfHistogram()))
            axes.set_xticks(
                np.arange(0.0,
                          p.metadata.MaximumRotation() + bin_width, bin_width)
                * 180.0 / np.pi)
            axes.set_ylabel('maximum recall', fontsize=fontsize)
            axes.set_ylim([-0.01, 1.05])
            axes.set_yticks(np.arange(0.0, 1.05, 0.1))
            axes.set_xlim([0.0, 180.0])
            axes.legend([name.lower() for name in legend_names],
                        numpoints=1,
                        loc='upper right')
            fig.tight_layout()

        tag_str = '{}/recall_by_rotation'.format(name)
        image_summary = plot.Curve(name=tag_str,
                                   figsize=(10, 8),
                                   xs=rotation_in_degrees,
                                   ys=ys,
                                   setter=_Setter,
                                   marker='.',
                                   markersize=14,
                                   linestyle='-',
                                   linewidth=2,
                                   alpha=0.5)
        return [image_summary]
Example #3
0
    def GenerateSummaries(self, name):
        """Generate an image summary for AP versus distance by class."""
        num_distances = self._values.shape[0]
        p = self.params
        ys = np.zeros(shape=(num_distances,
                             len(p.metadata.EvalClassIndices())),
                      dtype=np.float32)

        legend_names = []
        for i, j in enumerate(p.metadata.EvalClassIndices()):
            legend_names.append(p.metadata.ClassNames()[j])
            for distance in self._average_precisions:
                v = self._average_precisions[distance][i]
                if np.isnan(v):
                    v = 0.0
                ys[distance, i] = v

        def _Setter(fig, axes):
            """Configure the plot for mAP versus distance."""
            axes.grid(b=False)
            fontsize = 14
            for i, j in enumerate(p.metadata.EvalClassIndices()):
                for d, x in enumerate(self._values):
                    h = self._histogram[d][j]
                    y = min(ys[d][i] + 0.03, 1.0)
                    if h > 0:
                        text_label = '{} {}s'.format(
                            h, legend_names[i].lower()[:3])
                        axes.text(x,
                                  y,
                                  text_label,
                                  fontdict={'fontsize': fontsize - 2})

            axes.set_xlabel('distance (world coordinates)', fontsize=fontsize)
            axes.set_xticks(
                np.arange(
                    0.0,
                    p.metadata.MaximumDistance() +
                    p.metadata.DistanceBinWidth(),
                    p.metadata.DistanceBinWidth()))
            axes.set_ylabel('average precision (AP)', fontsize=fontsize)
            axes.set_ylim([-0.02, 1.05])
            axes.set_yticks(np.arange(0.0, 1.05, 0.1))
            axes.legend([name.lower() for name in legend_names],
                        numpoints=1,
                        loc=3)
            fig.tight_layout()

        tag_str = '{}/AP_by_distance'.format(name)
        image_summary = plot.Curve(name=tag_str,
                                   figsize=(10, 8),
                                   xs=self._values,
                                   ys=ys,
                                   setter=_Setter,
                                   marker='.',
                                   markersize=14,
                                   linestyle='-',
                                   linewidth=2,
                                   alpha=0.5)
        return [image_summary]
Example #4
0
    def Summary(self, name):
        """Generate tf summaries for calibration.

    Args:
      name: str, name of summary.

    Returns:
      list of tf.Summary
    """
        summaries = []
        for class_id in self._metadata.EvalClassIndices():
            classname = self._metadata.ClassNames()[class_id]
            tag_str = '{}/{}/calibration'.format(name, classname)

            if classname not in self._calibration_by_class:
                continue

            # Extract the data.
            mean_predicted_accuracy = self._calibration_by_class[classname][
                0, :]
            mean_empirical_accuracy = self._calibration_by_class[classname][
                1, :]
            num_examples_per_bin = self._calibration_by_class[classname][-1, :]
            total_examples = np.sum(num_examples_per_bin)
            legend = ['%s (%d)' % (classname, total_examples)]

            def _CalibrationSetter(fig, axes):
                """Configure the plot for calibration."""
                ticks = np.arange(0, 1.05, 0.1)
                axes.grid(b=False)
                axes.set_xlabel('Predicted accuracy')
                axes.set_xticks(ticks)
                axes.set_ylabel('Empirical accuracy')
                axes.set_yticks(ticks)
                axes.legend(legend, numpoints=1)  # pylint: disable=cell-var-from-loop
                fig.tight_layout()

            calibration_curve_summary = plot.Curve(name=tag_str,
                                                   figsize=(10, 8),
                                                   xs=mean_predicted_accuracy,
                                                   ys=mean_empirical_accuracy,
                                                   setter=_CalibrationSetter,
                                                   marker='.',
                                                   markersize=14,
                                                   linestyle='-',
                                                   linewidth=2,
                                                   alpha=0.5)

            ece = ExpectedCalibrationError(mean_predicted_accuracy,
                                           mean_empirical_accuracy,
                                           num_examples_per_bin)

            ece_summary = tf.Summary(value=[
                tf.Summary.Value(tag='{}/{}/calibration_ece'.format(
                    name, classname),
                                 simple_value=ece)
            ])
            summaries.extend([calibration_curve_summary, ece_summary])
        return summaries
Example #5
0
  def GenerateSummaries(self, name):
    """Generate an image summary for PR by difficulty and for calibration.

    Args:
      name: str, name of summary.

    Returns:
      list of summaries
    """

    legend = {}
    p = self.params
    for class_id in p.metadata.EvalClassIndices():
      legend[class_id] = []
      for difficulty, i in p.metadata.DifficultyLevels().items():
        num_objects = self._histogram[i][class_id]
        legend[class_id].append('%s (%d)' % (difficulty, num_objects))

    image_summaries = []
    for i, j in enumerate(p.metadata.EvalClassIndices()):

      def _PRSetter(fig, axes):
        """Configure the plot for precision recall."""
        ticks = np.arange(0, 1.05, 0.1)
        axes.grid(b=False)
        axes.set_xlabel('Recall')
        axes.set_xticks(ticks)
        axes.set_ylabel('Precision')
        axes.set_yticks(ticks)
        axes.legend(legend[j], numpoints=1)  # pylint: disable=cell-var-from-loop
        fig.tight_layout()

      classname = p.metadata.ClassNames()[j]
      # Generate Precision-Recall curves.
      rs = []
      ps = []
      for difficulty in p.metadata.DifficultyLevels():
        ps += [self._precision_recall[difficulty][i][:, 0]]
        rs += [self._precision_recall[difficulty][i][:, 1]]
      tag_str = '{}/{}/PR'.format(name, classname)
      image_summary = plot.Curve(
          name=tag_str,
          figsize=(10, 8),
          xs=rs[0],
          ys=np.array(ps).T,
          setter=_PRSetter,
          marker='.',
          markersize=14,
          linestyle='-',
          linewidth=2,
          alpha=0.5)
      image_summaries.append(image_summary)

    for difficulty, c in self._calibration.items():
      calibration_summaries = c.Summary(difficulty)
      for calibration_summary in calibration_summaries:
        image_summaries.append(calibration_summary)

    return image_summaries
Example #6
0
  def _GenerateCumulativeSummaries(self, name):
    """Generate an image summary for CDF of a variate."""
    xs = []
    ys = []
    num_zeros = []
    legend_names = []
    min_value = 5.0
    p = self.params

    for i, j in enumerate(p.metadata.EvalClassIndices()):
      legend_names.append(p.metadata.ClassNames()[j])
      if len(self._cumulative_distribution[j]) > min_value:
        self._cumulative_distribution[j].sort()
        x = np.array(self._cumulative_distribution[j])
        nonzeros = np.flatnonzero(x)
        cdf = np.arange(x.size).astype(np.float) / x.size
        xs.append(x)
        ys.append(cdf)
        num_zeros.append(x.size - nonzeros.size)
      else:
        xs.append(None)
        ys.append(None)
        num_zeros.append(None)

    image_summaries = []
    for i, j in enumerate(p.metadata.EvalClassIndices()):
      classname = p.metadata.ClassNames()[j]

      def _Setter(fig, axes):
        """Configure the plot for CDF of the variate."""
        axes.grid(b=False)
        fontsize = 14

        axes.set_ylim([0, 1.05])
        axes.set_xlim([1.0, 11500])
        axes.set_ylabel('cumulative distribution', fontsize=fontsize)
        axes.set_xlabel('number of points', fontsize=fontsize)
        axes.set_xscale('log')
        legend_text = '{} {}s ({} contain zero points)'.format(
            xs[i].size,
            p.metadata.ClassNames()[j].lower(), num_zeros[i])
        axes.legend({legend_text}, loc='upper left')
        fig.tight_layout()

      if xs[i] is not None:
        tag_str = '{}/{}/cdf_of_num_points'.format(name, classname)
        image_summary = plot.Curve(
            name=tag_str,
            figsize=(10, 8),
            xs=xs[i],
            ys=ys[i],
            setter=_Setter,
            marker='',
            linestyle='-',
            linewidth=2,
            alpha=0.5)
        image_summaries.append(image_summary)
    return image_summaries
Example #7
0
    def GenerateSummaries(self, name):
        """Generate an image summary for precision recall by difficulty."""
        p = self.params

        image_summaries = []
        for i, class_index in enumerate(p.metadata.EvalClassIndices()):

            def _Setter(fig, axes):
                """Configure the plot for precision recall."""
                ticks = np.arange(0, 1.05, 0.1)
                axes.grid(b=False)
                axes.set_xlabel('Recall')
                axes.set_xticks(ticks)
                axes.set_ylabel('Precision')
                axes.set_yticks(ticks)
                # TODO(vrv): Add legend indicating number of objects in breakdown.
                fig.tight_layout()

            classname = p.metadata.ClassNames()[class_index]
            for breakdown_name in p.breakdown_list:
                # 'ONE_SHARD' breakdowns are the overall metrics (not sliced up)
                # So we should never skip this.
                if 'ONE_SHARD' in breakdown_name:
                    breakdown_str = breakdown_name.replace('ONE_SHARD_', '')
                    tag_str = '{}/{}/{}/PR'.format(name, classname,
                                                   breakdown_str)
                # Otherwise check that the class we are looking at is in the breakdown.
                elif classname.lower() in breakdown_name.lower():
                    tag_str = '{}/{}/{}/PR'.format(name, classname,
                                                   breakdown_name)
                else:
                    continue

                ps = [self._precision_recall[breakdown_name][i][:, 0]]
                rs = [self._precision_recall[breakdown_name][i][:, 1]]
                image_summary = plot.Curve(name=tag_str,
                                           figsize=(10, 8),
                                           xs=rs[0],
                                           ys=np.array(ps).T,
                                           setter=_Setter,
                                           marker='.',
                                           markersize=14,
                                           linestyle='-',
                                           linewidth=2,
                                           alpha=0.5)
                image_summaries.append(image_summary)
        return image_summaries
Example #8
0
    def GenerateSummaries(self, name):
        """Generate an image summary for precision recall by difficulty."""
        p = self.params

        image_summaries = []
        for i, j in enumerate(p.metadata.EvalClassIndices()):

            def _Setter(fig, axes):
                """Configure the plot for precision recall."""
                ticks = np.arange(0, 1.05, 0.1)
                axes.grid(b=False)
                axes.set_xlabel('Recall')
                axes.set_xticks(ticks)
                axes.set_ylabel('Precision')
                axes.set_yticks(ticks)
                # TODO(vrv): Add legend indicating number of objects in breakdown.
                fig.tight_layout()

            classname = p.metadata.ClassNames()[j]
            for k, breakdown_str in enumerate(p.breakdown_list):
                # Skip adding entries for breakdowns that are in a different class.
                #
                # The first breakdown is the overall one, so never skip it.
                if k > 0 and classname.lower() not in breakdown_str.lower():
                    continue
                ps = [self._precision_recall[breakdown_str][i][:, 0]]
                rs = [self._precision_recall[breakdown_str][i][:, 1]]
                if k == 0:
                    # Overall class PR.
                    tag_str = '{}/{}/PR'.format(name, classname)
                else:
                    tag_str = '{}/{}/{}/PR'.format(name, classname,
                                                   breakdown_str)
                image_summary = plot.Curve(name=tag_str,
                                           figsize=(10, 8),
                                           xs=rs[0],
                                           ys=np.array(ps).T,
                                           setter=_Setter,
                                           marker='.',
                                           markersize=14,
                                           linestyle='-',
                                           linewidth=2,
                                           alpha=0.5)
                image_summaries.append(image_summary)

        return image_summaries
Example #9
0
  def Summary(self, name):

    def _Setter(fig, axes):
      # 20 ticks betweein 0 and 1.
      ticks = np.arange(0, 1.05, 0.05)
      axes.grid(b=True)
      axes.set_xlabel(self._plot_labels[0])
      axes.set_xticks(ticks)
      axes.set_ylabel(self._plot_labels[1])
      axes.set_yticks(ticks)
      fig.tight_layout()

    xs, ys, _ = self._curve_fn(
        self._label, self._prob, sample_weight=self._weight)
    if self._mode == 'pr':
      # Swap because sklearn returns <'precision', 'recall'>.
      xs, ys = ys, xs
    ret = plot.Curve(name=name, figsize=(12, 12), xs=xs, ys=ys, setter=_Setter)
    ret.value.add(tag=name, simple_value=self.value)
    return ret
Example #10
0
    def GenerateSummaries(self, name):
        """Generate an image summary for PR by difficulty and for calibration.

    Args:
      name: str, name of summary.

    Returns:
      list of summaries
    """

        legend = {}
        p = self.params
        for class_id in p.metadata.EvalClassIndices():
            legend[class_id] = []
            for difficulty, i in p.metadata.DifficultyLevels().items():
                num_objects = self._histogram[i][class_id]
                legend[class_id].append('%s (%d)' % (difficulty, num_objects))

        summaries = []
        for i, j in enumerate(p.metadata.EvalClassIndices()):

            def _PRSetter(fig, axes):
                """Configure the plot for precision recall."""
                ticks = np.arange(0, 1.05, 0.1)
                axes.grid(b=False)
                axes.set_xlabel('Recall')
                axes.set_xticks(ticks)
                axes.set_ylabel('Precision')
                axes.set_yticks(ticks)
                # pylint: disable=undefined-loop-variable
                axes.legend(legend[j], numpoints=1)  # pylint: disable=cell-var-from-loop
                # pylint: enable=undefined-loop-variable
                fig.tight_layout()

            classname = p.metadata.ClassNames()[j]
            # Generate Precision-Recall curves.
            rs = []
            ps = []
            for difficulty in p.metadata.DifficultyLevels():
                ps += [self._precision_recall[difficulty][i][:, 0]]
                rs += [self._precision_recall[difficulty][i][:, 1]]
            tag_str = '{}/{}/PR'.format(name, classname)
            image_summary = plot.Curve(name=tag_str,
                                       figsize=(10, 8),
                                       xs=rs[0],
                                       ys=np.array(ps).T,
                                       setter=_PRSetter,
                                       marker='.',
                                       markersize=14,
                                       linestyle='-',
                                       linewidth=2,
                                       alpha=0.5)
            summaries.append(image_summary)

        for difficulty, c in self._calibration.items():
            # Note that we only generate a calibration for a single difficulty level.
            calibration_summaries = c.Summary(name)
            for calibration_summary in calibration_summaries:
                summaries.append(calibration_summary)

        # Generate scalar summaries for the various recalls for each difficulty.
        for difficulty in p.metadata.DifficultyLevels():
            max_recall = _FindMaximumRecall(self._precision_recall[difficulty])
            for i, j in enumerate(p.metadata.EvalClassIndices()):
                classname = p.metadata.ClassNames()[j]
                summary = tf.Summary(value=[
                    tf.Summary.Value(tag='{}/{}/max_recall_{}'.format(
                        name, classname, difficulty),
                                     simple_value=max_recall[i])
                ])
                summaries.append(summary)

            for precision_level in p.metadata.RecallAtPrecision():
                recall_at_precision = _FindRecallAtGivenPrecision(
                    self._precision_recall[difficulty], precision_level)
                for i, j in enumerate(p.metadata.EvalClassIndices()):
                    classname = p.metadata.ClassNames()[j]
                    summary = tf.Summary(value=[
                        tf.Summary.Value(tag='{}/{}/recall_{}_{}'.format(
                            name, classname, int(precision_level *
                                                 100), difficulty),
                                         simple_value=recall_at_precision[i])
                    ])
                    summaries.append(summary)
        return summaries
Example #11
0
  def GenerateSummaries(self, name):
    """Generate an image summary for AP versus rotation by class."""
    num_rotations = self._values.shape[0]
    p = self.params
    rotation_in_degrees = self._values * 180.0 / np.pi
    ys = np.zeros(
        shape=(num_rotations, len(p.metadata.EvalClassIndices())),
        dtype=np.float32)

    legend_names = []
    for i, j in enumerate(p.metadata.EvalClassIndices()):
      legend_names.append(p.metadata.ClassNames()[j])
      for rotation in self._average_precisions:
        v = self._average_precisions[rotation][i]
        if np.isnan(v):
          v = 0.0
        ys[rotation, i] = v

    def _Setter(fig, axes):
      """Configure the plot for mAP versus distance."""
      axes.grid(b=False)
      fontsize = 14
      for i, j in enumerate(p.metadata.EvalClassIndices()):
        for r, x in enumerate(rotation_in_degrees):
          h = self._histogram[r][j]
          y = min(ys[r][i] + 0.03, 1.0)
          # TODO(shlens): Only display car currently for visual clarity
          # but relax this soon.
          if h > 0 and p.metadata.ClassNames()[j] in ['Car', 'Vehicle']:
            text_label = '{} {}s'.format(h, legend_names[i].lower()[:3])
            axes.text(x, y, text_label, fontdict={'fontsize': fontsize - 2})

      axes.set_xlabel('rotation (degrees)', fontsize=fontsize)
      bin_width = (
          p.metadata.MaximumRotation() / float(self.NumBinsOfHistogram()))
      axes.set_xticks(
          np.arange(0.0,
                    p.metadata.MaximumRotation() + bin_width, bin_width) *
          180.0 / np.pi)
      axes.set_ylabel('average precision (AP)', fontsize=fontsize)
      axes.set_ylim([-0.02, 1.05])
      axes.set_yticks(np.arange(0.0, 1.05, 0.1))
      axes.set_xlim([0.0, 180.0])
      axes.legend([name.lower() for name in legend_names],
                  numpoints=1,
                  loc='upper right')
      fig.tight_layout()

    tag_str = '{}/AP_by_rotation'.format(name)
    image_summary = plot.Curve(
        name=tag_str,
        figsize=(10, 8),
        xs=rotation_in_degrees,
        ys=ys,
        setter=_Setter,
        marker='.',
        markersize=14,
        linestyle='-',
        linewidth=2,
        alpha=0.5)
    return [image_summary]
Example #12
0
  def GenerateSummaries(self, name):
    """Generate an image summary for max recall by number of points by class."""
    image_summaries = self._GenerateCumulativeSummaries(name)
    p = self.params

    num_points_bins = self._values.shape[0]
    ys = np.zeros(
        shape=(num_points_bins, len(p.metadata.EvalClassIndices())),
        dtype=np.float32)

    # The method for computing precision-recall inserts precision = 0.0
    # when a particular recall value has not been achieved. The maximum
    # recall value is therefore the highest recall value when the associated
    # precision > 0.
    valid_precisions = {}
    for num_points in self._precision_recall:
      valid_precisions[num_points] = (
          self._precision_recall[num_points][:, :, 0] > 0.0)

    legend_names = []
    for i, j in enumerate(p.metadata.EvalClassIndices()):
      legend_names.append(p.metadata.ClassNames()[j])
      for num_points in self._precision_recall:
        valid_precisions_indices = valid_precisions[num_points][i]
        if not np.any(valid_precisions_indices):
          v = 0.0
        else:
          v = np.max(self._precision_recall[num_points]
                     [i, valid_precisions_indices, 1])
        ys[num_points, i] = v

    def _Setter(fig, axes):
      """Configure the plot for max recall versus number of points."""
      axes.grid(b=True)
      fontsize = 14
      for i, j in enumerate(p.metadata.EvalClassIndices()):
        for n, x in enumerate(self._values):
          h = self._histogram[n][j]
          y = min(ys[n][i] + 0.03, 1.0)
          if h > 0:
            text_label = '{} {}s'.format(h, legend_names[i].lower()[:3])
            axes.text(x, y, text_label, fontdict={'fontsize': fontsize - 2})

      axes.set_xlabel('number of points', fontsize=fontsize)
      axes.set_xticks(self._values)
      axes.set_ylabel('maximum recall', fontsize=fontsize)
      axes.set_ylim([-0.01, 1.05])
      axes.set_xlim([(1.0 / 1.3) * self._values[0], 1.3 * self._values[-1]])
      axes.set_yticks(np.arange(0.0, 1.05, 0.1))
      axes.set_xscale('log')
      axes.legend([name.lower() for name in legend_names],
                  numpoints=1,
                  loc='upper left')
      fig.tight_layout()

    tag_str = '{}/recall_by_num_points'.format(name)
    image_summary = plot.Curve(
        name=tag_str,
        figsize=(10, 8),
        xs=self._values,
        ys=ys,
        setter=_Setter,
        marker='.',
        markersize=14,
        linestyle='-',
        linewidth=2,
        alpha=0.5)
    image_summaries.append(image_summary)
    return image_summaries