class_docstr: Counterfactual Reinforcement Learning. 
class_docstr_tok: ["Counterfactual","Reinforcement","Learning","."]
docstr: Validates arguments.
  
  Parameters
  ----------
  predictor.
      A callable that takes a `numpy` array of `N` data points as inputs and returns `N` outputs.
  encoder
      Pretrained encoder network.
  decoder
      Pretrained decoder network.
  latent_dim
      Auto-encoder latent dimension.
  coeff_sparsity
      Sparsity loss coefficient.
  coeff_consistency
      Consistency loss coefficient.
  backend
      Deep learning backend: ``'tensorflow'`` | ``'pytorch'``.
  **kwargs
      Other arguments.
code: def _validate_kwargs(
      self,
      predictor: Callable,
      encoder: "Union[tensorflow.keras.Model, torch.nn.Module]",
      decoder: "Union[tensorflow.keras.Model, torch.nn.Module]",
      latent_dim: Optional[int],
      coeff_sparsity: float,
      coeff_consistency: float,
      backend: str,
      seed: int,
      **kwargs,
  ):
      """
      Validates arguments.
  
      Parameters
      ----------
      predictor.
          A callable that takes a `numpy` array of `N` data points as inputs and returns `N` outputs.
      encoder
          Pretrained encoder network.
      decoder
          Pretrained decoder network.
      latent_dim
          Auto-encoder latent dimension.
      coeff_sparsity
          Sparsity loss coefficient.
      coeff_consistency
          Consistency loss coefficient.
      backend
          Deep learning backend: ``'tensorflow'`` | ``'pytorch'``.
      **kwargs
          Other arguments.
      """
      # Copy default parameters.
      params = deepcopy(DEFAULT_BASE_PARAMS)
  
      # Update parameters with mandatory arguments
      params.update(
          {
              "encoder": encoder,
              "decoder": decoder,
              "latent_dim": latent_dim,
              "predictor": predictor,
              "coeff_sparsity": coeff_sparsity,
              "coeff_consistency": coeff_consistency,
              "backend": backend,
              "seed": seed,
          }
      )
  
      # Add actor if not user-specified.
      not_specified = {"actor": False, "critic": False}
      if "actor" not in kwargs:
          not_specified["actor"] = True
          params["actor"] = self.backend.get_actor(
              hidden_dim=params["actor_hidden_dim"],
              output_dim=params["latent_dim"],
          )
  
      if "critic" not in kwargs:
          not_specified["critic"] = True
          params["critic"] = self.backend.get_critic(
              hidden_dim=params["critic_hidden_dim"]
          )
  
      # Add optimizers if not user-specified.
      optimizers = ["optimizer_actor", "optimizer_critic"]
  
      for optim in optimizers:
          # extract model in question
          model_name = optim.split("_")[1]
          model = params[model_name]
          lr = params["lr_" + model_name]
  
          # If the optimizer is user-specified, just update the params
          if optim in kwargs:
              params.update({optim: kwargs[optim]})
              if (
                  self.params["backend"] == Framework.PYTORCH
                  and not_specified[model_name]
              ):
                  raise ValueError(
                      f"Can not specify {optim} when {model_name} not specified for pytorch backend."
                  )
  
          # If the optimizer is not user-specified, it need to be initialized. The initialization is backend specific.
          elif params["backend"] == Framework.TENSORFLOW:
              params.update({optim: self.backend.get_optimizer(lr=lr)})
          else:
              params.update(
                  {
                      optim: self.backend.get_optimizer(
                          model=model, lr=lr
                      )
                  }
              )
  
      # Add sparsity loss if not user-specified.
      params["sparsity_loss"] = (
          self.backend.sparsity_loss
          if "sparsity_loss" not in kwargs
          else kwargs["sparsity_loss"]
      )
  
      # Add consistency loss if not user-specified.
      params["consistency_loss"] = (
          self.backend.consistency_loss
          if "consistency_loss" not in kwargs
          else kwargs["consistency_loss"]
      )
  
      # Validate arguments.
      allowed_keys = set(params.keys())
      provided_keys = set(kwargs.keys())
      common_keys = allowed_keys & provided_keys
  
      # Check if some provided keys are incorrect
      if len(common_keys) < len(provided_keys):
          incorrect_keys = ", ".join(provided_keys - common_keys)
          logger.warning(
              "The following keys are incorrect: " + incorrect_keys
          )
  
      # Update default parameters and all parameters
      params.update({key: kwargs[key] for key in common_keys})
      return 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 6 for calling the CounterfactualRL obj's underlying member method code with example usage: obj._validate_kwargs(predictor, encoder, decoder, latent_dim, coeff_sparsity, coeff_consistency, backend, seed) and returns: params