class_docstr: Class which generates and stores classification batches.
  
  Each classification batch contains result of the classification of one
  batch of adversarial images.
class_docstr_tok: ["Class","which","generates","and","stores","classification","batches",".","Each","classification","batch","contains","result","of","the","classification","of","one","batch","of","adversarial","images","."]
docstr: Computes classification results.
  
  Args:
    adv_batches: instance of AversarialBatches
    dataset_batches: instance of DatasetBatches
    dataset_meta: instance of DatasetMetadata
    defense_work: instance of DefenseWorkPieces
  
  Returns:
    accuracy_matrix, error_matrix, hit_target_class_matrix,
    processed_images_count
docstr_tok: ["Computes","classification","results",".","Args",":","adv_batches",":","instance","of","AversarialBatches","dataset_batches",":","instance","of","DatasetBatches","dataset_meta",":","instance","of","DatasetMetadata","defense_work",":","instance","of","DefenseWorkPieces","Returns",":","accuracy_matrix",",","error_matrix",",","hit_target_class_matrix",",","processed_images_count"]
code: def compute_classification_results(
      self,
      adv_batches,
      dataset_batches,
      dataset_meta,
      defense_work=None,
  ):
      """Computes classification results.
  
      Args:
        adv_batches: instance of AversarialBatches
        dataset_batches: instance of DatasetBatches
        dataset_meta: instance of DatasetMetadata
        defense_work: instance of DefenseWorkPieces
  
      Returns:
        accuracy_matrix, error_matrix, hit_target_class_matrix,
        processed_images_count
      """
      class_batch_to_work = {}
      if defense_work:
          for v in itervalues(defense_work.work):
              class_batch_to_work[
                  v["output_classification_batch_id"]
              ] = v
  
      # accuracy_matrix[defense_id, attack_id] = num correctly classified
      accuracy_matrix = ResultMatrix()
      # error_matrix[defense_id, attack_id] = num misclassfied
      error_matrix = ResultMatrix()
      # hit_target_class_matrix[defense_id, attack_id] = num hit target class
      hit_target_class_matrix = ResultMatrix()
      # processed_images_count[defense_id] = num processed images by defense
      processed_images_count = {}
  
      total_count = len(self.data)
      processed_count = 0
      logging.info(
          "Processing %d files with classification results",
          len(self.data),
      )
      for k, v in iteritems(self.data):
          if processed_count % 100 == 0:
              logging.info(
                  "Processed %d out of %d classification results",
                  processed_count,
                  total_count,
              )
          processed_count += 1
          defense_id = v["submission_id"]
          adv_batch = adv_batches.data[v["adversarial_batch_id"]]
          attack_id = adv_batch["submission_id"]
  
          work_item = class_batch_to_work.get(k)
          required_work_stats = [
              "stat_correct",
              "stat_error",
              "stat_target_class",
              "stat_num_images",
          ]
          if work_item and work_item["error"]:
              # ignore batches with error
              continue
          if work_item and all(
              work_item.get(i) is not None for i in required_work_stats
          ):
              count_correctly_classified = work_item["stat_correct"]
              count_errors = work_item["stat_error"]
              count_hit_target_class = work_item["stat_target_class"]
              num_images = work_item["stat_num_images"]
          else:
              logging.warning(
                  "Recomputing accuracy for classification batch %s", k
              )
              (
                  count_correctly_classified,
                  count_errors,
                  count_hit_target_class,
                  num_images,
              ) = analyze_one_classification_result(
                  self._storage_client,
                  v["result_path"],
                  adv_batch,
                  dataset_batches,
                  dataset_meta,
              )
  
          # update accuracy and hit target class
          accuracy_matrix[
              defense_id, attack_id
          ] += count_correctly_classified
          error_matrix[defense_id, attack_id] += count_errors
          hit_target_class_matrix[
              defense_id, attack_id
          ] += count_hit_target_class
          # update number of processed images
          processed_images_count[defense_id] = (
              processed_images_count.get(defense_id, 0) + num_images
          )
      return (
          accuracy_matrix,
          error_matrix,
          hit_target_class_matrix,
          processed_images_count,
      )
  
imports: from __future__ import absolute_import
  from __future__ import division
  from __future__ import print_function
  import csv
  from io import BytesIO
  from io import StringIO
  import logging
  import os
  import pickle
  import time
  from six import iteritems
  from six import iterkeys
  from six import itervalues
  from six import PY3
label_desc: Use image node_id 9 for calling the ClassificationBatches obj's underlying member method code with example usage: obj.compute_classification_results(adv_batches, dataset_batches, dataset_meta, defense_work) and returns: accuracy_matrix,  error_matrix,  hit_target_class_matrix,  processed_images_count