class_docstr: Trainer for the classifier component of a Graph Agreement Model.
  
  Attributes:
    model: A Model object that is used to provide the architecture of the
      classification model.
    is_train: A placeholder for a boolean value specyfing if the model is used
      for train or evaluation.
    data: A CotrainDataset object.
    trainer_agr: A TrainerAgreement or TrainerPerfectAgreement object.
    optimizer: Optimizer used for training the classification model.
    batch_size: Batch size for used when training and evaluating the
      classification model.
    gradient_clip: A float number representing the maximum gradient norm allowed
      if we do gradient clipping. If None, no gradient clipping is performed.
    min_num_iter: An integer representing the minimum number of iterations to
      train the classification model.
    max_num_iter: An integer representing the maximum number of iterations to
      train the classification model.
    num_iter_after_best_val: An integer representing the number of extra
      iterations to perform after improving the validation set accuracy.
    max_num_iter_cotrain: An integer representing the maximum number of cotrain
      iterations to train for.
    reg_weight_ll: A float representing the weight of the agreement loss term
      component of the classification model loss function, between
      labeled-labeled pairs of samples.
    reg_weight_lu: A float representing the weight of the agreement loss term
      component of the classification model loss function, between
      labeled-unlabeled pairs of samples.
    reg_weight_uu: A float representing the weight of the agreement loss term
      component of the classification model loss function, between
      unlabeled-unlabeled pairs of samples.
    num_pairs_reg: An integer representing the number of sample pairs of each
      type (LL, LU, UU) to include in each computation of the classification
      model loss.
    iter_cotrain: A Tensorflow variable containing the current cotrain
      iteration.
    reg_weight_vat: A float representing the weight of the virtual adversarial
      training (VAT) regularization loss in the classification model loss
      function.
    use_ent_min: A boolean specifying whether to use entropy regularization with
      VAT.
    enable_summaries: Boolean specifying whether to enable variable summaries.
    summary_step: Integer representing the summary step size.
    summary_dir: String representing the path to a directory where to save the
      variable summaries.
    logging_step: Integer representing the number of iterations after which we
      log the loss of the model.
    eval_step: Integer representing the number of iterations after which we
      evaluate the model.
    warm_start: Whether the model parameters are initialized at their best value
      in the previous cotrain iteration. If False, they are reinitialized.
      gradient_clip=None,
    abs_loss_chg_tol: A float representing the absolute tolerance for checking
      if the training loss has converged. If the difference between the current
      loss and previous loss is less than `abs_loss_chg_tol`, we count this
      iteration towards convergence (see `loss_chg_iter_below_tol`).
    rel_loss_chg_tol: A float representing the relative tolerance for checking
      if the training loss has converged. If the ratio between the current loss
      and previous loss is less than `rel_loss_chg_tol`, we count this iteration
      towards convergence (see `loss_chg_iter_below_tol`).
    loss_chg_iter_below_tol: An integer representing the number of consecutive
      iterations that pass the convergence criteria before stopping training.
    checkpoints_dir: Path to the folder where to store TensorFlow model
      checkpoints.
    weight_decay: Weight for the weight decay term in the classification model
      loss.
    weight_decay_schedule: Schedule how to adjust the classification weight
      decay weight after every cotrain iteration.
    penalize_neg_agr: Whether to not only encourage agreement between samples
      that the agreement model believes should have the same label, but also
      penalize agreement when two samples agree when the agreement model
      predicts they should disagree.
    first_iter_original:  A boolean specifying whether the first cotrain
      iteration trains the original classification model (with no agreement
      term).
    use_l2_classif: Whether to use L2 loss for classification, as opposed to the
      whichever loss is specified in the provided model_cls.
    seed: Seed used by all the random number generators in this class.
    use_graph: Boolean specifying whether the agreement loss is applied to graph
      edges, as opposed to random pairs of samples.
docstr: Computes the regularization loss coming from the agreement term.
  
  This is calculated using the following idea: we incur a loss for pairs of
  samples that should have the same label, but for which the predictions of
  the classification model are not equal. The loss incured by each pair is
  proportionate to the distance between the two predictions, as well as the
  confidence we have that they should agree.
  
  In the case of pairs where both samples are labeled (LL), the agreement
  confidence is 1.0. When at least one sample is unlabeled (LU, UU), then we
  use the agreement model to estimate this confidence.
  
  Note that for the pairs where a label is available, we can compute this loss
  wrt. the actual label, instead of the classifier predictions. However, when
  both samples are labeled (LL), for one of them we use the prediction and for
  the other the true label -- otherwise there are no gradients to proagate.
  
  Args:
    data: A CotrainDataset object.
    is_train: A placeholder for a boolean that specifies if this is function
      is called as part of model training or inference.
    features_shape: A tuple of integers containing the number of features in
      each dimension of the inputs, not including batch size.
  
  Returns:
    The computed agreement loss op.
docstr_tok: ["Computes","the","regularization","loss","coming","from","the","agreement","term",".","This","is","calculated","using","the","following","idea",":","we","incur","a","loss","for","pairs","of","samples","that","should","have","the","same","label",",","but","for","which","the","predictions","of","the","classification","model","are","not","equal",".","The","loss","incured","by","each","pair","is","proportionate","to","the","distance","between","the","two","predictions",",","as","well","as","the","confidence","we","have","that","they","should","agree",".","In","the","case","of","pairs","where","both","samples","are","labeled","(","LL",")",",","the","agreement","confidence","is","1.0",".","When","at","least","one","sample","is","unlabeled","(","LU",",","UU",")",",","then","we","use","the","agreement","model","to","estimate","this","confidence",".","Note","that","for","the","pairs","where","a","label","is","available",",","we","can","compute","this","loss","wrt",".","the","actual","label",",","instead","of","the","classifier","predictions",".","However",",","when","both","samples","are","labeled","(","LL",")",",","for","one","of","them","we","use","the","prediction","and","for","the","other","the","true","label","--","otherwise","there","are","no","gradients","to","proagate",".","Args",":","data",":","A","CotrainDataset","object",".","is_train",":","A","placeholder","for","a","boolean","that","specifies","if","this","is","function","is","called","as","part","of","model","training","or","inference",".","features_shape",":","A","tuple","of","integers","containing","the","number","of","features","in","each","dimension","of","the","inputs",",","not","including","batch","size",".","Returns",":","The","computed","agreement","loss","op","."]
code: def _get_agreement_reg_loss(self, data, is_train, features_shape):
      """Computes the regularization loss coming from the agreement term.
  
      This is calculated using the following idea: we incur a loss for pairs of
      samples that should have the same label, but for which the predictions of
      the classification model are not equal. The loss incured by each pair is
      proportionate to the distance between the two predictions, as well as the
      confidence we have that they should agree.
  
      In the case of pairs where both samples are labeled (LL), the agreement
      confidence is 1.0. When at least one sample is unlabeled (LU, UU), then we
      use the agreement model to estimate this confidence.
  
      Note that for the pairs where a label is available, we can compute this loss
      wrt. the actual label, instead of the classifier predictions. However, when
      both samples are labeled (LL), for one of them we use the prediction and for
      the other the true label -- otherwise there are no gradients to proagate.
  
      Args:
        data: A CotrainDataset object.
        is_train: A placeholder for a boolean that specifies if this is function
          is called as part of model training or inference.
        features_shape: A tuple of integers containing the number of features in
          each dimension of the inputs, not including batch size.
  
      Returns:
        The computed agreement loss op.
      """
      # Select num_pairs_reg pairs of samples from each category LL, LU, UU.
      # for which to do the regularization.
      indices_lu_left = tf.placeholder(dtype=tf.int64, shape=(None,))
      indices_lu_right = tf.placeholder(dtype=tf.int64, shape=(None,))
      indices_uu_left = tf.placeholder(dtype=tf.int64, shape=(None,))
      indices_uu_right = tf.placeholder(dtype=tf.int64, shape=(None,))
  
      features_ll_right = tf.placeholder(
          dtype=tf.float32, shape=features_shape
      )
      features_lu_left = tf.placeholder(
          dtype=tf.float32, shape=features_shape
      )
      features_lu_right = tf.placeholder(
          dtype=tf.float32, shape=features_shape
      )
      features_uu_left = tf.placeholder(
          dtype=tf.float32, shape=features_shape
      )
      features_uu_right = tf.placeholder(
          dtype=tf.float32, shape=features_shape
      )
  
      labels_ll_left_idx = tf.placeholder(dtype=tf.int64, shape=(None,))
      labels_ll_right_idx = tf.placeholder(
          dtype=tf.int64, shape=(None,)
      )
      labels_lu_left_idx = tf.placeholder(dtype=tf.int64, shape=(None,))
  
      labels_ll_left = tf.one_hot(labels_ll_left_idx, data.num_classes)
      labels_lu_left = tf.one_hot(labels_lu_left_idx, data.num_classes)
  
      with tf.variable_scope("predictions", reuse=True):
          encoding, _, _ = self.model.get_encoding_and_params(
              inputs=features_ll_right,
              is_train=is_train,
              update_batch_stats=False,
          )
          (
              predictions_ll_right,
              _,
              _,
          ) = self.model.get_predictions_and_params(
              encoding=encoding, is_train=is_train
          )
          predictions_ll_right = self.model.normalize_predictions(
              predictions_ll_right
          )
  
          encoding, _, _ = self.model.get_encoding_and_params(
              inputs=features_lu_right,
              is_train=is_train,
              update_batch_stats=False,
          )
          (
              predictions_lu_right,
              _,
              _,
          ) = self.model.get_predictions_and_params(
              encoding=encoding, is_train=is_train
          )
          predictions_lu_right = self.model.normalize_predictions(
              predictions_lu_right
          )
  
          encoding, _, _ = self.model.get_encoding_and_params(
              inputs=features_uu_left,
              is_train=is_train,
              update_batch_stats=False,
          )
          (
              predictions_uu_left,
              _,
              _,
          ) = self.model.get_predictions_and_params(
              encoding=encoding, is_train=is_train
          )
          predictions_uu_left = self.model.normalize_predictions(
              predictions_uu_left
          )
  
          encoding, _, _ = self.model.get_encoding_and_params(
              inputs=features_uu_right,
              is_train=is_train,
              update_batch_stats=False,
          )
          (
              predictions_uu_right,
              _,
              _,
          ) = self.model.get_predictions_and_params(
              encoding=encoding, is_train=is_train
          )
          predictions_uu_right = self.model.normalize_predictions(
              predictions_uu_right
          )
  
      # Compute Euclidean distance between the label distributions that the
      # classification model predicts for the src and tgt of each pair.
      # Stop gradients need to be added
      # The case where there are no more uu or lu
      # edges at the end of training, so the shapes don't match needs fixing.
      left = tf.concat(
          (labels_ll_left, labels_lu_left, predictions_uu_left), axis=0
      )
      right = tf.concat(
          (
              predictions_ll_right,
              predictions_lu_right,
              predictions_uu_right,
          ),
          axis=0,
      )
      dists = tf.reduce_sum(tf.square(left - right), axis=-1)
  
      # Estimate a weight for each distance, depending on the predictions
      # of the agreement model. For the labeled samples, we can use the actual
      # agreement between the labels, no need to estimate.
      agreement_ll = tf.cast(
          tf.equal(labels_ll_left_idx, labels_ll_right_idx),
          dtype=tf.float32,
      )
      (
          _,
          agreement_lu,
          _,
          _,
      ) = self.trainer_agr.create_agreement_prediction(
          src_features=features_lu_left,
          tgt_features=features_lu_right,
          is_train=is_train,
          src_indices=indices_lu_left,
          tgt_indices=indices_lu_right,
      )
      (
          _,
          agreement_uu,
          _,
          _,
      ) = self.trainer_agr.create_agreement_prediction(
          src_features=features_uu_left,
          tgt_features=features_uu_right,
          is_train=is_train,
          src_indices=indices_uu_left,
          tgt_indices=indices_uu_right,
      )
      agreement = tf.concat(
          (agreement_ll, agreement_lu, agreement_uu), axis=0
      )
      if self.penalize_neg_agr:
          # Since the agreement is predicting scores between [0, 1], anything
          # under 0.5 should represent disagreement. Therefore, we want to encourage
          # agreement whenever the score is > 0.5, otherwise don't incur any loss.
          agreement = tf.nn.relu(agreement - 0.5)
  
      # Create a Tensor containing the weights assigned to each pair in the
      # agreement regularization loss, depending on how many samples in the pair
      # were labeled. This weight can be either reg_weight_ll, reg_weight_lu,
      # or reg_weight_uu.
      num_ll = tf.shape(predictions_ll_right)[0]
      num_lu = tf.shape(predictions_lu_right)[0]
      num_uu = tf.shape(predictions_uu_left)[0]
      weights = tf.concat(
          (
              self.reg_weight_ll
              * tf.ones(
                  num_ll,
              ),
              self.reg_weight_lu
              * tf.ones(
                  num_lu,
              ),
              self.reg_weight_uu
              * tf.ones(
                  num_uu,
              ),
          ),
          axis=0,
      )
  
      # Scale each distance by its agreement weight and regularzation weight.
      loss = tf.reduce_mean(dists * weights * agreement)
  
      self.indices_lu_left = indices_lu_left
      self.indices_lu_right = indices_lu_right
      self.indices_uu_left = indices_uu_left
      self.indices_uu_right = indices_uu_right
      self.features_ll_right = features_ll_right
      self.features_lu_left = features_lu_left
      self.features_lu_right = features_lu_right
      self.features_uu_left = features_uu_left
      self.features_uu_right = features_uu_right
      self.labels_ll_left = labels_ll_left_idx
      self.labels_ll_right = labels_ll_right_idx
      self.labels_lu_left = labels_lu_left_idx
      self.agreement_lu = agreement_lu
  
      return loss
  
imports: import logging
  import os
  from .adversarial_dense import entropy_y_x
  from .adversarial_dense import get_loss_vat
  import numpy
  import tensorflow
  from .trainer_base import batch_iterator
  from .trainer_base import Trainer
label_desc: Use image node_id 4 for calling the TrainerClassification obj's underlying member method code with example usage: obj._get_agreement_reg_loss(data, is_train, features_shape) and returns: loss