code: def sparsity_loss(
      X_hat_split: List[torch.Tensor],
      X_ohe: torch.Tensor,
      category_map: Dict[int, List[str]],
      weight_num: float = 1.0,
      weight_cat: float = 1.0,
  ):
      """
      Computes heterogeneous sparsity loss.
  
      Parameters
      ----------
      X_hat_split
          List of one-hot encoded reconstructed columns form the auto-encoder.
      X_ohe
          One-hot encoded representation of the input.
      category_map
          Dictionary of category mapping. The keys are column indexes and the values are lists containing the possible
          values for an attribute.
      weight_num
          Numerical loss weight.
      weight_cat
          Categorical loss weight.
  
      Returns
      -------
      Heterogeneous sparsity loss.
      """
      # Split the input into a list of tensor, where each element corresponds to a network head
      X_ohe_num_split, X_ohe_cat_split = split_ohe(
          X_ohe=X_ohe, category_map=category_map
      )
  
      # Sample differentiable output
      X_ohe_hat_split = sample_differentiable(
          X_hat_split=X_hat_split, category_map=category_map
      )
  
      # Define numerical and categorical loss
      num_loss, cat_loss = 0.0, 0.0
      offset = 0
  
      # Compute numerical loss
      if len(X_ohe_num_split) > 0:
          offset = 1
          num_loss = torch.mean(
              l1_loss(
                  input=X_ohe_hat_split[0],  # type: ignore
                  target=X_ohe_num_split[0],
                  reduction="none",
              )
          )
  
      # Compute categorical loss
      if len(X_ohe_cat_split) > 0:
          for i in range(len(X_ohe_cat_split)):
              cat_loss += torch.mean(
                  l0_ohe(
                      input=X_ohe_hat_split[i + offset],  # type: ignore
                      target=X_ohe_cat_split[i],
                      reduction="none",
                  )
              )
          cat_loss /= len(X_ohe_cat_split)
  
      return {
          "sparsity_num_loss": weight_num * num_loss,
          "sparsity_cat_loss": weight_cat * cat_loss,
      }
  
file_path: alibi/alibi/explainers/backends/pytorch/cfrl_tabular.py
imports: from typing import List, Dict
  import torch
  import torch.nn.functional
  from alibi.explainers.backends.cfrl_tabular import split_ohe, generate_condition
  from alibi.explainers.backends.pytorch.cfrl_base import get_actor, get_critic, get_optimizer, data_generator, encode, decode, generate_cf, update_actor_critic, add_noise, to_numpy, to_tensor, set_seed, save_model, load_model
label_desc: Use image node_id 4 for calling a global function with example usage: sparsity_loss(X_hat_split, X_ohe, category_map, weight_num, weight_cat) and returns: dict