class_docstr: Dual encoder model for text and video.
  
  Attributes:
    clip_vision_config: The config to create the video tower from.
    clip_text_config: The config to create the text tower from.
    temporal_agg: How to agregate embeddings of the different frames.
class_docstr_tok: ["Dual","encoder","model","for","text","and","video",".","Attributes",":","clip_vision_config",":","The","config","to","create","the","video","tower","from",".","clip_text_config",":","The","config","to","create","the","text","tower","from",".","temporal_agg",":","How","to","agregate","embeddings","of","the","different","frames","."]
docstr: Returns the loss for VFC training.
docstr_tok: ["Returns","the","loss","for","VFC","training","."]
code: def loss_function(
      self,
      encoded_video: jnp.ndarray,
      encoded_text: jnp.ndarray,
      batch: Any,
      config: ml_collections.ConfigDict,
      encoded_verbs: Optional[jnp.ndarray] = None,
  ) -> float:
      """Returns the loss for VFC training."""
  
      verb_hard_negatives = config.get("verb_hard_negatives", False)
      # Training with hard negatives ...
      if verb_hard_negatives:
          batch_mask_text = jax.lax.all_gather(
              batch["text_mask"], "batch"
          )
          batch_mask_text = batch_mask_text.reshape(
              (-1,) + batch_mask_text.shape[2:]
          )
          loss = losses.verb_hard_neg_nce(
              encoded_video,
              encoded_text,
              batch_mask_text,
              config.temperature,
              config.get("v2t_weight", 1.0),
              config.get("t2v_weight", 1.0),
              config.get("beta_hnnce", 0.0),
          )
      # ... or not. In this case, this is the baseline.
      else:
          loss = losses.baseline_nce(
              encoded_video,
              encoded_text,
              config.temperature,
              config.get("v2t_weight", 1.0),
              config.get("t2v_weight", 1.0),
              config.get("beta_hnnce", 0.0),
          )
  
      # Second, we (optionally) compute the verb-phrase loss.
      if encoded_verbs is not None:
          batch_mask_verb = jax.lax.all_gather(
              batch["verb_mask"], "batch"
          )
          batch_mask_verb = batch_mask_verb.reshape(
              (-1,) + batch_mask_verb.shape[2:]
          )
          verb_phrase_loss = losses.verb_phrase_nce(
              encoded_video,
              encoded_verbs,
              batch_mask_verb,
              config.temperature,
          )
          loss += (
              config.get("verb_phrase_loss_weight") * verb_phrase_loss
          )
      return jnp.mean(loss)
  
imports: from typing import Any, Optional
  import flax.linen
  import jax
  import jax.numpy
  import ml_collections
  from scenic.model_lib.base_models import base_model
  from scenic.projects.baselines.clip import layers
  from scenic.projects.baselines.clip import model
  from scenic.projects.verbs_in_action import losses
  from scenic.projects.verbs_in_action import utils
label_desc: Use image node_id 2 for calling the VideoAndTextModule obj's underlying member method code with example usage: obj.loss_function(encoded_video, encoded_text, batch, config, encoded_verbs) and returns: jnp