def _build_decoder_agreement_loss(self, central_lang_tag="<en>"):
    """Builds an agreement loss that enforces consistency of the decodings.

    Args:
      central_lang_tag: A string with the tag of the central language.
        A ``central'' language (usually English) is the one that has parallel
        data with all other languages. It is used to protect supervised
        directions from gradients coming from auxiliary losses.

    Returns:
      loss: <float32> [] for the agreement losses.
    """
    # Get target embeddigns and vocab size.
    target_modality = self._problem_hparams.modality["targets"]
    target_modality_scope = self._variable_scopes[target_modality.name]
    target_embeddings = model_utils.get_embeddings(
        modality=target_modality,
        outer_scope=target_modality_scope,
        inner_scope="shared")
    target_vocab_size = target_modality._vocab_size  # pylint: disable=protected-access

    # Build auxiliary sequences (if necessary).
    aux_keys = self._build_aux_sequences(
        target_embeddings, target_vocab_size,
        central_lang_tag=central_lang_tag)

    # Build loss.
    aux_loss = 0.
    with tf.name_scope("dec_agreement_loss"):
      for key1, key2 in zip(aux_keys, aux_keys[::-1]):
        # Prepare for decoding.
        targets = self.dec_outputs[key2]["rnn_output"]
        targets_length = self.dec_outputs[key2]["length"]
        shifted_targets = common_layers.shift_right_3d(targets)
        hiddens = self.enc_outputs[key1].outputs
        hiddens_length = self.inputs[key1][1]
        enc_state = self.enc_outputs[key1].final_state
        # Decode.
        decode_func = self.get_decode_func(
            target_embeddings,
            shifted_targets, targets_length,
            hiddens, hiddens_length,
            enc_state,
            mode=tf_estimator.ModeKeys.PREDICT,
            decoder_iterations=self._hparams.aux_decode_length)
        aux_dec_outputs = decode_func()
        # Compute logits (protect central directions from the gradients).
        aux_logits_1 = model_utils.build_logits(
            sequences=tf.expand_dims(
                aux_dec_outputs["rnn_output"], axis=2),
            embeddings=target_embeddings,
            vocab_size=target_vocab_size)
        aux_logits_1 = tf.where(
            self._is_central[key1],
            tf.stop_gradient(aux_logits_1),
            aux_logits_1)
        # Compute KL loss.
        logits = tf.squeeze(aux_logits_1, axis=2)
        if self._hparams.dec_agreement_loss_sparse:
          target_ids = self.dec_outputs[key2]["sample_id"]
          aux_loss = aux_loss + losses.CrossEntropyLoss(sparse=True)(
              logits, target_ids, targets_length)
        else:
          aux_logits_2 = tf.squeeze(self.dec_outputs[key2]["logits"], axis=2)
          target_probs = tf.nn.softmax(aux_logits_2, axis=-1)
          aux_loss = aux_loss + losses.CrossEntropyLoss(sparse=False)(
              logits, target_probs, targets_length)

    aux_loss = self._hparams.dec_agreement_coeff * aux_loss

    return aux_loss
Builds an agreement loss that enforces consistency of the decodings.

    Args:
      central_lang_tag: A string with the tag of the central language.
        A ``central'' language (usually English) is the one that has parallel
        data with all other languages. It is used to protect supervised
        directions from gradients coming from auxiliary losses.

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