code: def update_actor_critic(
      encoder: keras.Model,
      decoder: keras.Model,
      critic: keras.Model,
      actor: keras.Model,
      optimizer_critic: keras.optimizers.Optimizer,
      optimizer_actor: keras.optimizers.Optimizer,
      sparsity_loss: Callable,
      consistency_loss: Callable,
      coeff_sparsity: float,
      coeff_consistency: float,
      X: np.ndarray,
      X_cf: np.ndarray,
      Z: np.ndarray,
      Z_cf_tilde: np.ndarray,
      Y_m: np.ndarray,
      Y_t: np.ndarray,
      C: Optional[np.ndarray],
      R_tilde: np.ndarray,
      **kwargs,
  ) -> Dict[str, Any]:
      """
      Training step. Updates actor and critic networks including additional losses.
  
      Parameters
      ----------
      encoder
          Pretrained encoder network.
      decoder
          Pretrained decoder network.
      critic
          Critic network.
      actor
          Actor network.
      optimizer_critic
          Critic's optimizer.
      optimizer_actor
          Actor's optimizer.
      sparsity_loss
          Sparsity loss function.
      consistency_loss
          Consistency loss function.
      coeff_sparsity
          Sparsity loss coefficient.
      coeff_consistency
          Consistency loss coefficient
      X
          Input array.
      X_cf
          Counterfactual array.
      Z
          Input embedding.
      Z_cf_tilde
          Noised counterfactual embedding.
      Y_m
          Input classification label.
      Y_t
          Target counterfactual classification label.
      C
          Conditional tensor.
      R_tilde
          Noised counterfactual reward.
      **kwargs
          Other arguments. Not used.
  
      Returns
      -------
      Dictionary of losses.
      """
      # Define dictionary of losses.
      losses: Dict[str, float] = dict()
  
      # Transform labels, target and condition to float32
      Y_m = tf.cast(Y_m, dtype=tf.float32)
      Y_t = tf.cast(Y_t, dtype=tf.float32)
      C = tf.cast(C, dtype=tf.float32) if (C is not None) else None
  
      # Define state by concatenating the input embedding, the classification label, the target label, and optionally
      # the conditional vector if exists.
      state = [Z, Y_m, Y_t] + ([C] if C is not None else [])
      state = tf.concat(state, axis=1)
  
      # Define input for critic and compute q-values.
      with tf.GradientTape() as tape_critic:
          input_critic = tf.concat([state, Z_cf_tilde], axis=1)
          output_critic = tf.squeeze(
              critic(input_critic, training=True), axis=1
          )
          loss_critic = tf.reduce_mean(
              tf.square(output_critic - R_tilde)
          )
  
      # Append critic's loss.
      losses.update({"critic_loss": loss_critic})
  
      # Update critic by gradient step.
      grads_critic = tape_critic.gradient(
          loss_critic, critic.trainable_weights
      )
      optimizer_critic.apply_gradients(
          zip(grads_critic, critic.trainable_weights)
      )
  
      with tf.GradientTape() as tape_actor:
          # Compute counterfactual embedding.
          Z_cf = actor(state, training=True)
  
          # Compute critic's output.
          input_critic = tf.concat([state, Z_cf], axis=1)
          output_critic = critic(input_critic, training=False)
  
          # Compute actors' loss.
          loss_actor = -tf.reduce_mean(output_critic)
          losses.update({"actor_loss": loss_actor})
  
          # Decode the counterfactual embedding.
          X_hat_cf = decoder(Z_cf, training=False)
  
          # Compute sparsity losses and append sparsity loss.
          loss_sparsity = sparsity_loss(X_hat_cf, X)
          losses.update(loss_sparsity)
  
          # Add sparsity loss to the overall actor loss.
          for key in loss_sparsity.keys():
              loss_actor += coeff_sparsity * loss_sparsity[key]
  
          # Compute consistency loss and append consistency loss.
          Z_cf_tgt = encoder(X_cf, training=False)
          loss_consistency = consistency_loss(
              Z_cf_pred=Z_cf, Z_cf_tgt=Z_cf_tgt
          )
          losses.update(loss_consistency)
  
          # Add consistency loss to the overall actor loss.
          for key in loss_consistency.keys():
              loss_actor += coeff_consistency * loss_consistency[key]
  
      # Update by gradient descent.
      grads_actor = tape_actor.gradient(
          loss_actor, actor.trainable_weights
      )
      optimizer_actor.apply_gradients(
          zip(grads_actor, actor.trainable_weights)
      )
  
      # Return dictionary of losses for potential logging.
      return losses
  
imports: import os
  import random
  from typing import Any, List, Dict, Callable, Union, Optional, TYPE_CHECKING
  import numpy
  import tensorflow
  import tensorflow.keras
  from alibi.explainers.backends.cfrl_base import CounterfactualRLDataset
  from alibi.models.tensorflow.actor_critic import Actor, Critic
label_desc: Use image node_id 14 for calling a global function with example usage: update_actor_critic(encoder, decoder, critic, actor, optimizer_critic, optimizer_actor, sparsity_loss, consistency_loss, coeff_sparsity, coeff_consistency, X, X_cf, Z, Z_cf_tilde, Y_m, Y_t, C, R_tilde) and returns: losses