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: Find activations from :class:`.Classifier`.
docstr_tok: ["Find","activations","from",":","class",":","`",".Classifier","`","."]
code: def _get_activations(
      self, x_train: Optional[np.ndarray] = None
  ) -> np.ndarray:
      """
      Find activations from :class:`.Classifier`.
      """
      logger.info("Getting activations")
  
      if self.classifier.layer_names is not None:
          nb_layers = len(self.classifier.layer_names)
      else:
          raise ValueError("No layer names identified.")
      protected_layer = nb_layers - 1
  
      if self.generator is not None and x_train is not None:
          activations = self.classifier.get_activations(
              x_train,
              layer=protected_layer,
              batch_size=self.generator.batch_size,
          )
      else:
          activations = self.classifier.get_activations(
              self.x_train, layer=protected_layer, batch_size=128
          )
  
      # wrong way to get activations activations = self.classifier.predict(self.x_train)
      if isinstance(activations, np.ndarray):
          # flatten activations across batch
          activations = np.reshape(
              activations, (activations.shape[0], -1)
          )
          nodes_last_layer = activations.shape[1]
      else:
          raise ValueError("activations is None or tensor.")
  
      if nodes_last_layer <= self.TOO_SMALL_ACTIVATIONS:
          logger.warning(
              "Number of activations in last hidden layer is too small. Method may not work properly. "
              "Size: %s",
              str(nodes_last_layer),
          )
      return activations
  
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 15 for calling the ActivationDefence obj's underlying member method code with example usage: obj._get_activations(x_train) and returns: activations