class_docstr: Implementation of methods in Neural Cleanse: Identifying and Mitigating Backdoor Attacks in Neural Networks.
  Wang et al. (2019).
  
  | Paper link: https://people.cs.uchicago.edu/~ravenben/publications/pdf/backdoor-sp19.pdf
docstr: Generates a possible backdoor for the model. Returns the pattern and the mask
  :return: A tuple of the pattern and mask for the model.
docstr_tok: ["Generates","a","possible","backdoor","for","the","model",".","Returns","the","pattern","and","the","mask",":","return",":","A","tuple","of","the","pattern","and","mask","for","the","model","."]
code: def generate_backdoor(
      self, x_val: np.ndarray, y_val: np.ndarray, y_target: np.ndarray
  ) -> Tuple[np.ndarray, np.ndarray]:
      """
      Generates a possible backdoor for the model. Returns the pattern and the mask
      :return: A tuple of the pattern and mask for the model.
      """
      import keras.backend as K
      from keras.preprocessing.image import ImageDataGenerator
  
      self.reset()
      datagen = ImageDataGenerator()
      gen = datagen.flow(x_val, y_val, batch_size=self.batch_size)
      mask_best: Optional[np.ndarray] = None
      pattern_best: Optional[np.ndarray] = None
      reg_best = float("inf")
      cost_set_counter = 0
      cost_up_counter = 0
      cost_down_counter = 0
      cost_up_flag = False
      cost_down_flag = False
      early_stop_counter = 0
      early_stop_reg_best = reg_best
      mini_batch_size = len(x_val) // self.batch_size
      for _ in tqdm(
          range(self.steps),
          desc=f"Generating backdoor for class {np.argmax(y_target)}",
      ):
          loss_reg_list = []
          loss_acc_list = []
  
          for _ in range(mini_batch_size):
              x_batch, _ = gen.next()
              y_batch = [y_target] * x_batch.shape[0]
              _, batch_loss_reg, _, batch_loss_acc = self.train(
                  [x_batch, y_batch]
              )
  
              loss_reg_list.extend(list(batch_loss_reg.flatten()))
              loss_acc_list.extend(list(batch_loss_acc.flatten()))
  
          avg_loss_reg = np.mean(loss_reg_list)
          avg_loss_acc = np.mean(loss_acc_list)
  
          # save best mask/pattern so far
          if (
              avg_loss_acc >= self.attack_success_threshold
              and avg_loss_reg < reg_best
          ):
              mask_best = K.eval(self.mask_tensor)
              pattern_best = K.eval(self.pattern_tensor)
              reg_best = avg_loss_reg
  
          # check early stop
          if self.early_stop:  # pragma: no cover
              if reg_best < float("inf"):
                  if (
                      reg_best
                      >= self.early_stop_threshold * early_stop_reg_best
                  ):
                      early_stop_counter += 1
                  else:
                      early_stop_counter = 0
              early_stop_reg_best = min(reg_best, early_stop_reg_best)
  
              if (
                  cost_down_flag
                  and cost_up_flag
                  and early_stop_counter >= self.early_stop_patience
              ):
                  logger.info("Early stop")
                  break
  
          # cost modification
          if avg_loss_acc >= self.attack_success_threshold:
              cost_set_counter += 1
              if cost_set_counter >= self.patience:
                  self.cost = self.init_cost
                  K.set_value(self.cost_tensor, self.cost)
                  cost_up_counter = 0
                  cost_down_counter = 0
                  cost_up_flag = False
                  cost_down_flag = False
          else:
              cost_set_counter = 0
  
          if avg_loss_acc >= self.attack_success_threshold:
              cost_up_counter += 1
              cost_down_counter = 0
          else:
              cost_up_counter = 0
              cost_down_counter += 1
  
          if cost_up_counter >= self.patience:
              cost_up_counter = 0
              self.cost *= self.cost_multiplier_up
              K.set_value(self.cost_tensor, self.cost)
              cost_up_flag = True
          elif cost_down_counter >= self.patience:
              cost_down_counter = 0
              self.cost /= self.cost_multiplier_down
              K.set_value(self.cost_tensor, self.cost)
              cost_down_flag = True
  
      if mask_best is None:
          mask_best = K.eval(self.mask_tensor)
          pattern_best = K.eval(self.pattern_tensor)
  
      if pattern_best is None:
          raise ValueError("Unexpected `None` detected.")
  
      return mask_best, pattern_best
  
imports: from __future__ import absolute_import, division, print_function, unicode_literals
  import logging
  from typing import List, Optional, Tuple, Union, TYPE_CHECKING
  import numpy
  from tqdm.auto import tqdm
  from art.config import ART_NUMPY_DTYPE
  from art.estimators.poison_mitigation.neural_cleanse.neural_cleanse import NeuralCleanseMixin
  from art.estimators.classification.keras import KerasClassifier, KERAS_MODEL_TYPE
label_desc: Use image node_id 4 for calling the KerasNeuralCleanse obj's underlying member method code with example usage: obj.generate_backdoor(x_val, y_val, y_target) and returns: mask_best,  pattern_best