class_docstr: Counterfactual Reinforcement Learning. 
class_docstr_tok: ["Counterfactual","Reinforcement","Learning","."]
docstr: Constructor.
  
  Parameters
  ----------
  predictor
      A callable that takes a `numpy` array of `N` data points as inputs and returns `N` outputs. For
      classification task, the second dimension of the output should match the number of classes. Thus, the
      output can be either a soft label distribution or a hard label distribution (i.e. one-hot encoding)
      without affecting the performance since `argmax` is applied to the predictor's output.
  encoder
      Pretrained encoder network.
  decoder
      Pretrained decoder network.
  coeff_sparsity
      Sparsity loss coefficient.
  coeff_consistency
      Consistency loss coefficient.
  latent_dim
      Auto-encoder latent dimension. Can be omitted if the actor network is user specified.
  backend
      Deep learning backend: ``'tensorflow'`` | ``'pytorch'``. Default ``'tensorflow'``.
  seed
      Seed for reproducibility. The results are not reproducible for ``'tensorflow'`` backend.
  **kwargs
      Used to replace any default parameter from :py:data:`alibi.explainers.cfrl_base.DEFAULT_BASE_PARAMS`.
code: def __init__(
      self,
      predictor: Callable[[np.ndarray], np.ndarray],
      encoder: "Union[tensorflow.keras.Model, torch.nn.Module]",
      decoder: "Union[tensorflow.keras.Model, torch.nn.Module]",
      coeff_sparsity: float,
      coeff_consistency: float,
      latent_dim: Optional[int] = None,
      backend: str = "tensorflow",
      seed: int = 0,
      **kwargs,
  ):
      """
      Constructor.
  
      Parameters
      ----------
      predictor
          A callable that takes a `numpy` array of `N` data points as inputs and returns `N` outputs. For
          classification task, the second dimension of the output should match the number of classes. Thus, the
          output can be either a soft label distribution or a hard label distribution (i.e. one-hot encoding)
          without affecting the performance since `argmax` is applied to the predictor's output.
      encoder
          Pretrained encoder network.
      decoder
          Pretrained decoder network.
      coeff_sparsity
          Sparsity loss coefficient.
      coeff_consistency
          Consistency loss coefficient.
      latent_dim
          Auto-encoder latent dimension. Can be omitted if the actor network is user specified.
      backend
          Deep learning backend: ``'tensorflow'`` | ``'pytorch'``. Default ``'tensorflow'``.
      seed
          Seed for reproducibility. The results are not reproducible for ``'tensorflow'`` backend.
      **kwargs
          Used to replace any default parameter from :py:data:`alibi.explainers.cfrl_base.DEFAULT_BASE_PARAMS`.
      """
      super().__init__(meta=deepcopy(DEFAULT_META_CFRL))
  
      # Clean backend flag.
      backend = backend.strip().lower()
  
      # Verify backend installed
      CounterfactualRL._verify_backend(backend)
  
      # Select backend.
      self.backend = self._select_backend(backend, **kwargs)
  
      # Set seed for reproducibility.
      self.backend.set_seed(seed)
  
      # Validate arguments.
      self.params = self._validate_kwargs(
          predictor=predictor,
          encoder=encoder,
          decoder=decoder,
          latent_dim=latent_dim,
          coeff_sparsity=coeff_sparsity,
          coeff_consistency=coeff_consistency,
          backend=backend,
          seed=seed,
          **kwargs,
      )
  
      # If pytorch backend, the if GPU available, send everything to GPU
      if self.params["backend"] == Framework.PYTORCH:
          from alibi.explainers.backends.pytorch.cfrl_base import (
              get_device,
          )
  
          self.params.update({"device": get_device()})
  
          # Send encoder and decoder to device.
          self.params["encoder"].to(self.params["device"])
          self.params["decoder"].to(self.params["device"])
  
          # Sent actor and critic to device.
          self.params["actor"].to(self.params["device"])
          self.params["critic"].to(self.params["device"])
  
      # Update meta-data with all parameters passed (correct and incorrect).
      self.meta["params"].update(
          CounterfactualRL._serialize_params(self.params)
      )
  
imports: import logging
  import os
  from abc import ABC, abstractmethod
  from copy import deepcopy
  from typing import TYPE_CHECKING, Any, Callable, Dict, Optional, Tuple, Union, cast
  import numpy
  from tqdm import tqdm
  from alibi.api.defaults import DEFAULT_DATA_CFRL, DEFAULT_META_CFRL
  from alibi.api.interfaces import Explainer, Explanation, FitMixin
  from alibi.explainers.backends.cfrl_base import generate_empty_condition, get_classification_reward, get_hard_distribution, identity_function
  from alibi.utils.frameworks import Framework, has_pytorch, has_tensorflow
label_desc: Use image node_id 1 to create a new CounterfactualRL object from inherited base classes: Explainer, FitMixin with example: obj = CounterfactualRL(predictor, encoder, decoder, coeff_sparsity, coeff_consistency, latent_dim, backend, seed)