def _build(self, logits, targets, target_lens, normalize_by_length=False):  # pylint: disable=arguments-differ
    """Builds the cross entropy loss.

    Args:
      logits: <float32> [batch_size, seq_len, vocab_size] for predicted logits.
      targets: <int32> [batch_size, seq_len] if `sparse=True` or
        <float32> [batch_size, seq_len, vocab_size] otherwise.
      target_lens: <int32> [batch_size] for the target sequence lengths.
      normalize_by_length: Boolean indicating whether to normalize the loss by
        the sequence length (i.e., shorter sequences are penalized more).

    Returns:
      loss: <float32> [batch_size] for the loss.
    """
    # Build weights.
    weights = tf.sequence_mask(target_lens, dtype=logits.dtype)

    # Build loss.
    if self._sparse:
      loss = self._build_sparse(logits, targets, weights, normalize_by_length)
    else:
      loss = self._build_dense(logits, targets, weights, normalize_by_length)

    return loss
Builds the cross entropy loss.

    Args:
      logits: <float32> [batch_size, seq_len, vocab_size] for predicted logits.
      targets: <int32> [batch_size, seq_len] if `sparse=True` or
        <float32> [batch_size, seq_len, vocab_size] otherwise.
      target_lens: <int32> [batch_size] for the target sequence lengths.
      normalize_by_length: Boolean indicating whether to normalize the loss by
        the sequence length (i.e., shorter sequences are penalized more).

    Returns:
      loss: <float32> [batch_size] for the loss.
    
language/labs/consistent_zero_shot_nmt/models/losses.py