code: def virtual_adv_regularizer(
      input_layer, embedding_fn, virtual_adv_config, embedding=None
  ):
      """Calculates virtual adversarial loss for the given input.
  
      Virtual adversarial loss is defined as the distance between the embedding of
      the input and that of a slightly perturbed input. Optimizing this loss helps
      smooth models locally.
  
      Reference paper: https://arxiv.org/pdf/1704.03976.pdf
  
      Args:
        input_layer: a dense tensor for input features whose first dimension is the
          training batch size.
        embedding_fn: a unary function that computes the embedding for the given
          `input_layer` input.
        virtual_adv_config: an `nsl.configs.VirtualAdvConfig` object that specifies
          parameters for generating adversarial examples and computing the
          adversarial loss.
        embedding: (optional) a dense tensor representing the embedding of
          `input_layer`. If not provided, it will be calculated as
          `embedding_fn(input_layer)`.
  
      Returns:
        virtual_adv_loss: a `float32` denoting the virtural adversarial loss.
      """
  
      if embedding is None:
          embedding = embedding_fn(input_layer)
  
      seed_perturbation = tf.random.normal(tf.shape(input=input_layer))
      return _virtual_adv_regularizer(
          input_layer,
          embedding_fn,
          virtual_adv_config,
          embedding,
          seed_perturbation,
      )
  
imports: from neural_structured_learning.lib import distances
  from neural_structured_learning.lib import utils
  import tensorflow
label_desc: Use image node_id 3 for calling a global function with example usage: virtual_adv_regularizer(input_layer, embedding_fn, virtual_adv_config, embedding) and returns: _virtual_adv_regularizer