class_docstr: Implementation of the Knockoff Nets attack from Orekondy et al. (2018).
  
  | Paper link: https://arxiv.org/abs/1812.02766
docstr: Extract a thieved classifier.
  
  :param x: An array with the source input to the victim classifier.
  :param y: Target values (class labels) one-hot-encoded of shape (nb_samples, nb_classes) or indices of shape
            `(nb_samples,)`.
  :param thieved_classifier: A thieved classifier to be stolen.
  :return: The stolen classifier.
docstr_tok: ["Extract","a","thieved","classifier",".",":","param","x",":","An","array","with","the","source","input","to","the","victim","classifier",".",":","param","y",":","Target","values","(","class","labels",")","one-hot-encoded","of","shape","(","nb_samples",",","nb_classes",")","or","indices","of","shape","`","(","nb_samples",",",")","`",".",":","param","thieved_classifier",":","A","thieved","classifier","to","be","stolen",".",":","return",":","The","stolen","classifier","."]
code: def extract(
      self, x: np.ndarray, y: Optional[np.ndarray] = None, **kwargs
  ) -> "CLASSIFIER_TYPE":
      """
      Extract a thieved classifier.
  
      :param x: An array with the source input to the victim classifier.
      :param y: Target values (class labels) one-hot-encoded of shape (nb_samples, nb_classes) or indices of shape
                `(nb_samples,)`.
      :param thieved_classifier: A thieved classifier to be stolen.
      :return: The stolen classifier.
      """
      # Check prerequisite for random strategy
      if (
          self.sampling_strategy == "random" and y is not None
      ):  # pragma: no cover
          logger.warning(
              "This attack with random sampling strategy does not use the provided label y."
          )
  
      # Check prerequisite for adaptive strategy
      if (
          self.sampling_strategy == "adaptive" and y is None
      ):  # pragma: no cover
          raise ValueError(
              "This attack with adaptive sampling strategy needs label y."
          )
  
      # Check the size of the source input vs nb_stolen
      if x.shape[0] < self.nb_stolen:  # pragma: no cover
          logger.warning(
              "The size of the source input is smaller than the expected number of queries submitted "
              "to the victim classifier."
          )
  
      # Check if there is a thieved classifier provided for training
      thieved_classifier = kwargs.get("thieved_classifier")
      if thieved_classifier is None or not isinstance(
          thieved_classifier, ClassifierMixin
      ):  # pragma: no cover
          raise ValueError("A thieved classifier is needed.")
  
      # Implement model extractions
      if self.sampling_strategy == "random":
          thieved_classifier = self._random_extraction(x, thieved_classifier)  # type: ignore
      else:
          thieved_classifier = self._adaptive_extraction(x, y, thieved_classifier)  # type: ignore
  
      return thieved_classifier
  
imports: from __future__ import absolute_import, division, print_function, unicode_literals
  import logging
  from typing import Optional, TYPE_CHECKING, Union
  import numpy
  from tqdm.auto import trange
  from art.config import ART_NUMPY_DTYPE
  from art.attacks.attack import ExtractionAttack
  from art.estimators.estimator import BaseEstimator
  from art.estimators.classification.classifier import ClassifierMixin
  from art.utils import to_categorical
label_desc: Use image node_id 2 for calling the KnockoffNets obj's underlying member method code with example usage: obj.extract(x, y) and returns: thieved_classifier