class_docstr: Memory Network agent.
  
  Tips:
  - time features are necessary when memory order matters
  - multiple hops allow multiple steps of reasoning, but also seem to make it
      easier to learn to read the memories if you have at least two hops
  - 'adam' seems to work very poorly compared to 'sgd' for hogwild training
class_docstr_tok: ["Memory","Network","agent",".","Tips",":","-","time","features","are","necessary","when","memory","order","matters","-","multiple","hops","allow","multiple","steps","of","reasoning",",","but","also","seem","to","make","it","easier","to","learn","to","read","the","memories","if","you","have","at","least","two","hops","-","'adam","'","seems","to","work","very","poorly","compared","to","'sgd","'","for","hogwild","training"]
docstr: Override so that we can add memories to the Batch object.
docstr_tok: ["Override","so","that","we","can","add","memories","to","the","Batch","object","."]
code: def batchify(self, obs_batch, sort=False):
      """
      Override so that we can add memories to the Batch object.
      """
      batch = super().batchify(obs_batch, sort)
  
      # get valid observations
      valid_obs = [
          (i, ex) for i, ex in enumerate(obs_batch) if self.is_valid(ex)
      ]
  
      if len(valid_obs) == 0:
          return batch
  
      valid_inds, exs = zip(*valid_obs)
  
      # get memories for the valid observations
      mems = None
      if any("memory_vecs" in ex for ex in exs):
          mems = [ex.get("memory_vecs", None) for ex in exs]
      batch.memory_vecs = mems
      return batch
  
imports: from typing import Optional
  from parlai.core.params import ParlaiParser
  from parlai.core.opt import Opt
  from functools import lru_cache
  import torch
  from parlai.core.torch_ranker_agent import TorchRankerAgent
  from .modules import MemNN, opt_to_kwargs
label_desc: Use image node_id 10 for calling the MemnnAgent obj's underlying member method code with example usage: obj.batchify(obs_batch, sort) and returns: batch, batch