class_docstr: Model described in (https://arxiv.org/abs/1811.00945).
  
  A model for producing engaging captions about an image. Given an image and
  this model will attempt to predict an appropriate
  next utterance in the dialog, in the context of a given personality.
  
  See the paper linked above for more information.
class_docstr_tok: ["Model","described","in","(","https",":","\/\/arxiv.org\/abs\/1811.00945",")",".","A","model","for","producing","engaging","captions","about","an","image",".","Given","an","image","and","this","model","will","attempt","to","predict","an","appropriate","next","utterance","in","the","dialog",",","in","the","context","of","a","given","personality",".","See","the","paper","linked","above","for","more","information","."]
docstr: Model eval step.
  
  :param valid_obs:
      list of valid observations
  
  :param image_feats:
      list of image features, one per example
  
  :param personalities:
      list of personalities, one per example
  
  :return:
      the total loss, number of correct examples, the total number of
      examples evaluated, the ranked position of each correct caption,
      and the ranked lists of candidates (one per example)
docstr_tok: ["Model","eval","step",".",":","param","valid_obs",":","list","of","valid","observations",":","param","image_feats",":","list","of","image","features",",","one","per","example",":","param","personalities",":","list","of","personalities",",","one","per","example",":","return",":","the","total","loss",",","number","of","correct","examples",",","the","total","number","of","examples","evaluated",",","the","ranked","position","of","each","correct","caption",",","and","the","ranked","lists","of","candidates","(","one","per","example",")"]
code: def eval_step(self, valid_obs, image_feats, personalities):
      """
      Model eval step.
  
      :param valid_obs:
          list of valid observations
  
      :param image_feats:
          list of image features, one per example
  
      :param personalities:
          list of personalities, one per example
  
      :return:
          the total loss, number of correct examples, the total number of
          examples evaluated, the ranked position of each correct caption,
          and the ranked lists of candidates (one per example)
      """
      med_rank = None
      chosen_captions = None
      if (
          "label_candidates" in valid_obs[0]
          or self.fixed_cands is not None
      ):
          # User provides candidates, used as negatives for evaluation
          candidates_encoded = None
          if self.fixed_cands is not None:
              candidates_encoded = self.fixed_cands_enc
              candidates = self.fixed_cands
          else:
              candidates = [v["label_candidates"] for v in valid_obs]
              if self.one_cand_set:
                  candidates_encoded = self.model(
                      None, None, candidates[0]
                  )[1].detach()
          chosen_captions = self.model.choose_best_caption(
              image_feats,
              personalities,
              candidates,
              candidates_encoded=candidates_encoded,
              k=-1 if self.fixed_cands is None else 100,
          )
          # calculate median ranks
          num_examples = len(chosen_captions)
          loss = -1
          if self.fixed_cands is not None:
              num_correct = 0
          else:
              comments = [v["eval_labels"] for v in valid_obs]
              med_rank = []
              for i, c_list in enumerate(chosen_captions):
                  lowest_rank = len(c_list) + 1
                  for _, c in enumerate(comments[i]):
                      lowest_rank = min(
                          lowest_rank, c_list.index(c) + 1
                      )
                  med_rank.append(lowest_rank)
              num_correct = sum(
                  [
                      1
                      if chosen_captions[i][0] in chosen_captions[i]
                      else 0
                      for i in range(len(chosen_captions))
                  ]
              )
      else:
          comments = [
              random.choice(v["eval_labels"]) for v in valid_obs
          ]
          loss, num_correct, num_examples = self.model.eval_batch(
              image_feats, personalities, comments
          )
  
      return loss, num_correct, num_examples, med_rank, chosen_captions
  
imports: from typing import Optional
  from parlai.core.params import ParlaiParser
  from parlai.core.opt import Opt
  from parlai.core.agents import Agent
  from parlai.core.dict import DictionaryAgent
  from parlai.utils.misc import round_sigfigs
  from .modules import TransresnetModel
  from parlai.tasks.personality_captions.build import build
  from parlai.utils.io import PathManager
  import parlai.utils.torch
  import os
  import random
  import json
  import numpy
  import torch
  import tqdm
label_desc: Use image node_id 11 for calling the TransresnetAgent obj's underlying member method code with example usage: obj.eval_step(valid_obs, image_feats, personalities) and returns: loss,  num_correct,  num_examples,  med_rank,  chosen_captions