docstr: Compute the loss for the given sample.
  
  Returns a tuple with three elements:
  1) the loss, as a Variable
  2) the sample size, which is used as the denominator for the gradient
  3) logging outputs to display while training
docstr_tok: ["Compute","the","loss","for","the","given","sample",".","Returns","a","tuple","with","three","elements",":","1",")","the","loss",",","as","a","Variable","2",")","the","sample","size",",","which","is","used","as","the","denominator","for","the","gradient","3",")","logging","outputs","to","display","while","training"]
code: def forward(self, model, sample, reduce=True):
      """Compute the loss for the given sample.
  
      Returns a tuple with three elements:
      1) the loss, as a Variable
      2) the sample size, which is used as the denominator for the gradient
      3) logging outputs to display while training
      """
  
      # 1. Generate translation using student model
      net_output = model(**sample["net_input"])
      student_lprobs = model.get_normalized_probs(
          net_output, log_probs=True
      )
      # [bsz, seqlen, vocab] -> [bsz*seqlen, vocab]
      lprobs = student_lprobs.view(-1, student_lprobs.size(-1))
  
      # 2. Get translation from teacher models and calulate KD loss.
      kd_loss = None
      if "top_k_scores" in sample:
          # top_k_scores is not present in the validation data.
          kd_loss = self.get_kd_loss(sample, student_lprobs, lprobs)
  
      # 3. Compute NLL loss with respect to the ground truth
      target = model.get_targets(sample, net_output).view(-1)
      nll_loss = F.nll_loss(
          lprobs,
          target,
          size_average=False,
          ignore_index=self.padding_idx,
          reduce=reduce,
      )
  
      # 4. Linearly interpolate between NLL and KD loss
      if kd_loss is not None:
          loss = kd_loss * self.kd_weight + nll_loss * (
              1 - self.kd_weight
          )
      else:
          loss = nll_loss
  
      if self.args.sentence_avg:
          sample_size = sample["target"].size(0)
      else:
          sample_size = sample["ntokens"]
      if self.args.sentence_avg:
          sample_size = sample["target"].size(0)
      else:
          sample_size = sample["ntokens"]
      logging_output = {
          "loss": utils.item(loss.data) if reduce else loss.data,
          "ntokens": sample["ntokens"],
          "nsamples": sample["target"].size(0),
          "sample_size": sample_size,
      }
      return loss, sample_size, logging_output
  
file_path: translate/pytorch_translate/research/knowledge_distillation/knowledge_distillation_loss.py
imports: import math
  import torch
  import torch.nn.functional
  from fairseq import utils
  from fairseq.criterions import LegacyFairseqCriterion, register_criterion
  from pytorch_translate import utils
label_desc: Use image node_id 4 for calling the KnowledgeDistillationCriterion obj's underlying member method code with example usage: obj.forward(model, sample, reduce) and returns: loss,  sample_size,  logging_output