code: def add_noise(
      Z_cf: Union[tf.Tensor, np.ndarray],
      noise: "NormalActionNoise",
      act_low: float,
      act_high: float,
      step: int,
      exploration_steps: int,
      **kwargs,
  ) -> tf.Tensor:
      """
      Add noise to the counterfactual embedding.
  
      Parameters
      ----------
      Z_cf
          Counterfactual embedding.
      noise
          Noise generator object.
      act_low
          Noise lower bound.
      act_high
          Noise upper bound.
      step
          Training step.
      exploration_steps
          Number of exploration steps. For the first `exploration_steps`, the noised counterfactual embedding
          is sampled uniformly at random.
      **kwargs
          Other arguments. Not used.
  
      Returns
      -------
      Z_cf_tilde
          Noised counterfactual embedding.
      """
      # Generate noise.
      eps = noise(Z_cf.shape)
  
      if step > exploration_steps:
          Z_cf_tilde = Z_cf + eps
          Z_cf_tilde = tf.clip_by_value(
              Z_cf_tilde,
              clip_value_min=act_low,
              clip_value_max=act_high,
          )
      else:
          # for the first exploration_steps, the action is sampled from a uniform distribution between
          # [act_low, act_high] to encourage exploration. After that, the algorithm returns to the normal exploration.
          Z_cf_tilde = tf.random.uniform(
              Z_cf.shape, minval=act_low, maxval=act_high
          )
  
      return Z_cf_tilde
  
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 10 for calling a global function with example usage: add_noise(Z_cf, noise, act_low, act_high, step, exploration_steps) and returns: Z_cf_tilde