class_docstr: Utility for training shadow models and generating shadow-datasets for membership inference attacks in scikit-learn,
  PyTorch and TensorFlow v2.
docstr: Generates a shadow dataset (member and nonmember samples and their corresponding model predictions) by splitting
  the dataset into training and testing samples, and then training the shadow models on the result.
  
  :param x: The samples used to train the shadow models.
  :param y: True labels for the dataset samples (as expected by the estimator's fit method).
  :param member_ratio: Percentage of the data that should be used to train the shadow models. Must be between 0
                       and 1.
  :return: The shadow dataset generated. The shape is `((member_samples, true_label, model_prediction),
           (nonmember_samples, true_label, model_prediction))`.
docstr_tok: ["Generates","a","shadow","dataset","(","member","and","nonmember","samples","and","their","corresponding","model","predictions",")","by","splitting","the","dataset","into","training","and","testing","samples",",","and","then","training","the","shadow","models","on","the","result",".",":","param","x",":","The","samples","used","to","train","the","shadow","models",".",":","param","y",":","True","labels","for","the","dataset","samples","(","as","expected","by","the","estimator","'s","fit","method",")",".",":","param","member_ratio",":","Percentage","of","the","data","that","should","be","used","to","train","the","shadow","models",".","Must","be","between","0","and","1.",":","return",":","The","shadow","dataset","generated",".","The","shape","is","`","(","(","member_samples",",","true_label",",","model_prediction",")",",","(","nonmember_samples",",","true_label",",","model_prediction",")",")","`","."]
code: def generate_shadow_dataset(
      self,
      x: np.ndarray,
      y: np.ndarray,
      member_ratio: float = 0.5,
  ) -> Tuple[
      Tuple[np.ndarray, np.ndarray, np.ndarray],
      Tuple[np.ndarray, np.ndarray, np.ndarray],
  ]:
      """
      Generates a shadow dataset (member and nonmember samples and their corresponding model predictions) by splitting
      the dataset into training and testing samples, and then training the shadow models on the result.
  
      :param x: The samples used to train the shadow models.
      :param y: True labels for the dataset samples (as expected by the estimator's fit method).
      :param member_ratio: Percentage of the data that should be used to train the shadow models. Must be between 0
                           and 1.
      :return: The shadow dataset generated. The shape is `((member_samples, true_label, model_prediction),
               (nonmember_samples, true_label, model_prediction))`.
      """
  
      if len(x) != len(y):
          raise ValueError(
              "Number of samples in dataset does not match number of labels"
          )
  
      # Shuffle data set
      random_indices = self._rng.permutation(len(x))
      x, y = x[random_indices], y[random_indices]
  
      if self._disjoint_datasets:
          shadow_dataset_size = len(x) // len(self._shadow_models)
      else:
          shadow_dataset_size = len(x)
  
      member_samples = []
      member_true_label = []
      member_prediction = []
      nonmember_samples = []
      nonmember_true_label = []
      nonmember_prediction = []
  
      # Train and create predictions for every model
      for i, shadow_model in enumerate(self._shadow_models):
          if self._disjoint_datasets:
              shadow_x = x[
                  shadow_dataset_size
                  * i : shadow_dataset_size
                  * (i + 1)
              ]
              shadow_y = y[
                  shadow_dataset_size
                  * i : shadow_dataset_size
                  * (i + 1)
              ]
  
              shadow_x_train = shadow_x[
                  : int(member_ratio * shadow_dataset_size)
              ]
              shadow_y_train = shadow_y[
                  : int(member_ratio * shadow_dataset_size)
              ]
              shadow_x_test = shadow_x[
                  int(member_ratio * shadow_dataset_size) :
              ]
              shadow_y_test = shadow_y[
                  int(member_ratio * shadow_dataset_size) :
              ]
          else:
              member_indexes = self._rng.choice(
                  len(x) - 1, int(len(x) * member_ratio), replace=False
              )
              non_member_indexes = np.setdiff1d(
                  range(len(x) - 1), member_indexes, assume_unique=True
              )
              shadow_x_train = x[member_indexes]
              shadow_y_train = y[member_indexes]
              shadow_x_test = x[non_member_indexes]
              shadow_y_test = y[non_member_indexes]
  
          self._shadow_models_train_sets[i] = (
              shadow_x_train,
              shadow_y_train,
          )
  
          shadow_model.fit(shadow_x_train, shadow_y_train)
  
          member_samples.append(shadow_x_train)
          member_true_label.append(shadow_y_train)
          member_prediction.append(shadow_model.predict(shadow_x_train))
  
          nonmember_samples.append(shadow_x_test)
          nonmember_true_label.append(shadow_y_test)
          nonmember_prediction.append(
              shadow_model.predict(shadow_x_test)
          )
  
      def concat(first: np.ndarray, second: np.ndarray) -> np.ndarray:
          return np.concatenate((first, second))
  
      # Concatenate the results of all the shadow models
      all_member_samples = reduce(concat, member_samples)
      all_member_true_label = reduce(concat, member_true_label)
      all_member_prediction = reduce(concat, member_prediction)
      all_nonmember_samples = reduce(concat, nonmember_samples)
      all_nonmember_true_label = reduce(concat, nonmember_true_label)
      all_nonmember_prediction = reduce(concat, nonmember_prediction)
  
      return (
          (
              all_member_samples,
              all_member_true_label,
              all_member_prediction,
          ),
          (
              all_nonmember_samples,
              all_nonmember_true_label,
              all_nonmember_prediction,
          ),
      )
  
file_path: adversarial-robustness-toolbox/art/attacks/inference/membership_inference/shadow_models.py
imports: from __future__ import absolute_import, division, print_function, unicode_literals
  import math
  from functools import reduce
  from typing import Callable, Tuple, TYPE_CHECKING, List, Optional, Sequence
  import numpy
label_desc: Use image node_id 2 for calling the ShadowModels obj's underlying member method code with example usage: obj.generate_shadow_dataset(x, y, member_ratio) and returns: all_member_samples,  all_member_true_label,  all_member_prediction,  all_nonmember_samples,  all_nonmember_true_label,  all_nonmember_prediction, np