code: def cluster_activations(
      separated_activations: List[np.ndarray],
      nb_clusters: int = 2,
      nb_dims: int = 10,
      reduce: str = "FastICA",
      clustering_method: str = "KMeans",
      generator: Optional[DataGenerator] = None,
      clusterer_new: Optional[MiniBatchKMeans] = None,
  ) -> Tuple[List[np.ndarray], List[np.ndarray]]:
      """
      Clusters activations and returns two arrays.
      1) separated_clusters: where separated_clusters[i] is a 1D array indicating which cluster each data point
      in the class has been assigned.
      2) separated_reduced_activations: activations with dimensionality reduced using the specified reduce method.
  
      :param separated_activations: List where separated_activations[i] is a np matrix for the ith class where
             each row corresponds to activations for a given data point.
      :param nb_clusters: number of clusters (defaults to 2 for poison/clean).
      :param nb_dims: number of dimensions to reduce activation to via PCA.
      :param reduce: Method to perform dimensionality reduction, default is FastICA.
      :param clustering_method: Clustering method to use, default is KMeans.
      :param generator: whether or not a the activations are a batch or full activations
      :return: (separated_clusters, separated_reduced_activations).
      :param clusterer_new: whether or not a the activations are a batch or full activations
      :return: (separated_clusters, separated_reduced_activations)
      """
      separated_clusters = []
      separated_reduced_activations = []
  
      if clustering_method == "KMeans":
          clusterer = KMeans(n_clusters=nb_clusters)
      else:
          raise ValueError(
              f"{clustering_method} clustering method not supported."
          )
  
      for activation in separated_activations:
          # Apply dimensionality reduction
          nb_activations = np.shape(activation)[1]
          if nb_activations > nb_dims:
              # TODO: address issue where if fewer samples than nb_dims this fails
              reduced_activations = reduce_dimensionality(
                  activation, nb_dims=nb_dims, reduce=reduce
              )
          else:
              logger.info(
                  "Dimensionality of activations = %i less than nb_dims = %i. Not applying dimensionality "
                  "reduction.",
                  nb_activations,
                  nb_dims,
              )
              reduced_activations = activation
          separated_reduced_activations.append(reduced_activations)
  
          # Get cluster assignments
          if generator is not None and clusterer_new is not None:
              clusterer_new = clusterer_new.partial_fit(
                  reduced_activations
              )
              # NOTE: this may cause earlier predictions to be less accurate
              clusters = clusterer_new.predict(reduced_activations)
          else:
              clusters = clusterer.fit_predict(reduced_activations)
          separated_clusters.append(clusters)
  
      return separated_clusters, separated_reduced_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 3 for calling a global function with example usage: cluster_activations(separated_activations, nb_clusters, nb_dims, reduce, clustering_method, generator, clusterer_new) and returns: separated_clusters,  separated_reduced_activations