docstr: Explain instance and return PP or PN with metadata.
  
  Parameters
  ----------
  X
      Instances to attack.
  Y
      Labels for `X`.
  verbose
      Print intermediate results of optimization if ``True``.
  
  Returns
  -------
  explanation
      `Explanation` object containing the PP or PN with additional metadata as attributes.
      See usage at `CEM examples`_ for details.
  
      .. _CEM examples:
          https://docs.seldon.io/projects/alibi/en/stable/methods/CEM.html
docstr_tok: ["Explain","instance","and","return","PP","or","PN","with","metadata",".","Parameters","--","--","--","--","--","X","Instances","to","attack",".","Y","Labels","for","`","X","`",".","verbose","Print","intermediate","results","of","optimization","if","``","True","``",".","Returns","--","--","--","-","explanation","`","Explanation","`","object","containing","the","PP","or","PN","with","additional","metadata","as","attributes",".","See","usage","at","`","CEM","examples","`","_","for","details",".","..","_CEM","examples",":","https",":","\/\/docs.seldon.io\/projects\/alibi\/en\/stable\/methods\/CEM.html"]
code: def explain(
      self,
      X: np.ndarray,
      Y: Optional[np.ndarray] = None,
      verbose: bool = False,
  ) -> Explanation:
      """
      Explain instance and return PP or PN with metadata.
  
      Parameters
      ----------
      X
          Instances to attack.
      Y
          Labels for `X`.
      verbose
          Print intermediate results of optimization if ``True``.
  
      Returns
      -------
      explanation
          `Explanation` object containing the PP or PN with additional metadata as attributes.
          See usage at `CEM examples`_ for details.
  
          .. _CEM examples:
              https://docs.seldon.io/projects/alibi/en/stable/methods/CEM.html
      """
      if X.shape[0] != 1:
          logger.warning(
              "Currently only single instance explanations supported (first dim = 1), "
              "but first dim = %s",
              X.shape[0],
          )
  
      if Y is None:
          if self.model:
              Y = self.sess.run(
                  self.predict(
                      tf.convert_to_tensor(X, dtype=tf.float32)
                  )
              )
          else:
              Y = self.predict(X)
          Y_ohe = np.zeros(Y.shape)
          Y_ohe[np.arange(Y.shape[0]), np.argmax(Y, axis=1)] = 1
          Y = Y_ohe.copy()
  
      # find best PP or PN
      self.best_attack = False
      best_attack, grads = self.attack(X, Y=Y, verbose=verbose)
  
      # output explanation dictionary
      data = copy.deepcopy(DEFAULT_DATA_CEM)
      data["X"] = X
      data["X_pred"] = np.argmax(Y, axis=1)[0]
  
      if not self.best_attack:
          logger.warning("No {} found!".format(self.mode))
  
          # create explanation object
          explanation = Explanation(
              meta=copy.deepcopy(self.meta), data=data
          )
          return explanation
  
      data[self.mode] = best_attack
      if self.model:
          Y_pert = self.sess.run(
              self.predict(
                  tf.convert_to_tensor(best_attack, dtype=tf.float32)
              )
          )
      else:
          Y_pert = self.predict(best_attack)
      data[self.mode + "_pred"] = np.argmax(Y_pert, axis=1)[0]
      data["grads_graph"], data["grads_num"] = grads[0], grads[1]
  
      # create explanation object
      explanation = Explanation(
          meta=copy.deepcopy(self.meta), data=data
      )
  
      return explanation
  
file_path: alibi/alibi/explainers/cem.py
imports: import copy
  import logging
  import sys
  from typing import Any, Callable, Optional, Tuple, Union
  import numpy
  import tensorflow.compat.v1
  from alibi.api.defaults import DEFAULT_DATA_CEM, DEFAULT_META_CEM
  from alibi.api.interfaces import Explainer, Explanation, FitMixin
label_desc: Use image node_id 7 for calling the CEM obj's underlying member method code with example usage: obj.explain(X, Y, verbose) and returns: explanation, explanation