class_docstr: Method from Chen et al., 2018 performing poisoning detection based on activations clustering.
  
  | Paper link: https://arxiv.org/abs/1811.03728
  
  | Please keep in mind the limitations of defences. For more information on the limitations of this
      defence, see https://arxiv.org/abs/1905.13409 . For details on how to evaluate classifier security
      in general, see https://arxiv.org/abs/1902.06705
docstr: If ground truth is known, this function returns a confusion matrix in the form of a JSON object.
  
  :param is_clean: Ground truth, where is_clean[i]=1 means that x_train[i] is clean and is_clean[i]=0 means
                   x_train[i] is poisonous.
  :param kwargs: A dictionary of defence-specific parameters.
  :return: JSON object with confusion matrix.
docstr_tok: ["If","ground","truth","is","known",",","this","function","returns","a","confusion","matrix","in","the","form","of","a","JSON","object",".",":","param","is_clean",":","Ground","truth",",","where","is_clean","[","i","]","=1","means","that","x_train","[","i","]","is","clean","and","is_clean","[","i","]","=0","means","x_train","[","i","]","is","poisonous",".",":","param","kwargs",":","A","dictionary","of","defence-specific","parameters",".",":","return",":","JSON","object","with","confusion","matrix","."]
code: def evaluate_defence(self, is_clean: np.ndarray, **kwargs) -> str:
      """
      If ground truth is known, this function returns a confusion matrix in the form of a JSON object.
  
      :param is_clean: Ground truth, where is_clean[i]=1 means that x_train[i] is clean and is_clean[i]=0 means
                       x_train[i] is poisonous.
      :param kwargs: A dictionary of defence-specific parameters.
      :return: JSON object with confusion matrix.
      """
      if is_clean is None or is_clean.size == 0:
          raise ValueError(
              "is_clean was not provided while invoking evaluate_defence."
          )
  
      self.set_params(**kwargs)
  
      if not self.activations_by_class and self.generator is None:
          activations = self._get_activations()
          self.activations_by_class = self._segment_by_class(
              activations, self.y_train
          )
  
      (
          self.clusters_by_class,
          self.red_activations_by_class,
      ) = self.cluster_activations()
      _, self.assigned_clean_by_class = self.analyze_clusters()
  
      # Now check ground truth:
      if self.generator is not None:
          batch_size = self.generator.batch_size
          num_samples = self.generator.size
          num_classes = self.classifier.nb_classes
          self.is_clean_by_class = [
              np.empty(0, dtype=int) for _ in range(num_classes)
          ]
  
          # calculate is_clean_by_class for each batch
          for batch_idx in range(num_samples // batch_size):  # type: ignore
              _, y_batch = self.generator.get_batch()
              is_clean_batch = is_clean[
                  batch_idx * batch_size : batch_idx * batch_size
                  + batch_size
              ]
              clean_by_class_batch = self._segment_by_class(
                  is_clean_batch, y_batch
              )
              self.is_clean_by_class = [
                  np.append(
                      self.is_clean_by_class[class_idx],
                      clean_by_class_batch[class_idx],
                  )
                  for class_idx in range(num_classes)
              ]
  
      else:
          self.is_clean_by_class = self._segment_by_class(
              is_clean, self.y_train
          )
      (
          self.errors_by_class,
          conf_matrix_json,
      ) = self.evaluator.analyze_correctness(
          self.assigned_clean_by_class, self.is_clean_by_class
      )
      return conf_matrix_json
  
imports: from __future__ import absolute_import, division, print_function, unicode_literals
  import logging
  import os
  import pickle
  import time
  from typing import Any, Dict, List, Optional, Tuple, TYPE_CHECKING
  import numpy
  from sklearn.cluster import KMeans, MiniBatchKMeans
  from art import config
  from art.data_generators import DataGenerator
  from art.defences.detector.poison.clustering_analyzer import ClusteringAnalyzer
  from art.defences.detector.poison.ground_truth_evaluator import GroundTruthEvaluator
  from art.defences.detector.poison.poison_filtering_defence import PoisonFilteringDefence
  from art.utils import segment_by_class
  from art.visualization import create_sprite, save_image, plot_3d
label_desc: Use image node_id 2 for calling the ActivationDefence obj's underlying member method code with example usage: obj.evaluate_defence(is_clean) and returns: conf_matrix_json