class_docstr: Runs the HotFlip style attack at the word-level https://arxiv.org/abs/1712.06751.  We use the
  first-order taylor approximation described in https://arxiv.org/abs/1903.06620, in the function
  `_first_order_taylor()`.
  
  We try to re-use the embedding matrix from the model when deciding what other words to flip a
  token to.  For a large class of models, this is straightforward.  When there is a
  character-level encoder, however (e.g., with ELMo, any char-CNN, etc.), or a combination of
  encoders (e.g., ELMo + glove), we need to construct a fake embedding matrix that we can use in
  `_first_order_taylor()`.  We do this by getting a list of words from the model's vocabulary
  and embedding them using the encoder.  This can be expensive, both in terms of time and memory
  usage, so we take a `max_tokens` parameter to limit the size of this fake embedding matrix.
  This also requires a model to `have` a token vocabulary in the first place, which can be
  problematic for models that only have character vocabularies.
  
  Registered as an `Attacker` with name "hotflip".
  
  # Parameters
  
  predictor : `Predictor`
      The model (inside a Predictor) that we're attacking.  We use this to get gradients and
      predictions.
  vocab_namespace : `str`, optional (default=`'tokens'`)
      We use this to know three things: (1) which tokens we should ignore when producing flips
      (we don't consider non-alphanumeric tokens); (2) what the string value is of the token that
      we produced, so we can show something human-readable to the user; and (3) if we need to
      construct a fake embedding matrix, we use the tokens in the vocabulary as flip candidates.
  max_tokens : `int`, optional (default=`5000`)
      This is only used when we need to construct a fake embedding matrix.  That matrix can take
      a lot of memory when the vocab size is large.  This parameter puts a cap on the number of
      tokens to use, so the fake embedding matrix doesn't take as much memory.
docstr: The below code is based on
  https://github.com/pmichel31415/translate/blob/paul/pytorch_translate/
  research/adversarial/adversaries/brute_force_adversary.py
  
  Replaces the current token_idx with another token_idx to increase the loss. In particular, this
  function uses the grad, alongside the embedding_matrix to select the token that maximizes the
  first-order taylor approximation of the loss.
docstr_tok: ["The","below","code","is","based","on","https",":","\/\/github.com\/pmichel31415\/translate\/blob\/paul\/pytorch_translate\/","research\/adversarial\/adversaries\/brute_force_adversary.py","Replaces","the","current","token_idx","with","another","token_idx","to","increase","the","loss",".","In","particular",",","this","function","uses","the","grad",",","alongside","the","embedding_matrix","to","select","the","token","that","maximizes","the","first-order","taylor","approximation","of","the","loss","."]
code: def _first_order_taylor(
      self, grad: numpy.ndarray, token_idx: torch.Tensor, sign: int
  ) -> int:
      """
      The below code is based on
      https://github.com/pmichel31415/translate/blob/paul/pytorch_translate/
      research/adversarial/adversaries/brute_force_adversary.py
  
      Replaces the current token_idx with another token_idx to increase the loss. In particular, this
      function uses the grad, alongside the embedding_matrix to select the token that maximizes the
      first-order taylor approximation of the loss.
      """
      grad = util.move_to_device(
          torch.from_numpy(grad), self.cuda_device
      )
      if token_idx.size() != ():
          # We've got an encoder that only has character ids as input.  We don't curently handle
          # this case, and it's not clear it's worth it to implement it.  We'll at least give a
          # nicer error than some pytorch dimension mismatch.
          raise NotImplementedError(
              "You are using a character-level indexer with no other indexers. This case is not "
              "currently supported for hotflip. If you would really like to see us support "
              "this, please open an issue on github."
          )
      if token_idx >= self.embedding_matrix.size(0):
          # This happens when we've truncated our fake embedding matrix.  We need to do a dot
          # product with the word vector of the current token; if that token is out of
          # vocabulary for our truncated matrix, we need to run it through the embedding layer.
          inputs = self._make_embedder_input(
              [self.vocab.get_token_from_index(token_idx.item())]
          )
          word_embedding = self.embedding_layer(inputs)[0]
      else:
          word_embedding = torch.nn.functional.embedding(
              util.move_to_device(
                  torch.LongTensor([token_idx]), self.cuda_device
              ),
              self.embedding_matrix,
          )
      word_embedding = word_embedding.detach().unsqueeze(0)
      grad = grad.unsqueeze(0).unsqueeze(0)
      # solves equation (3) here https://arxiv.org/abs/1903.06620
      new_embed_dot_grad = torch.einsum(
          "bij,kj->bik", (grad, self.embedding_matrix)
      )
      prev_embed_dot_grad = torch.einsum(
          "bij,bij->bi", (grad, word_embedding)
      ).unsqueeze(-1)
      neg_dir_dot_grad = sign * (
          prev_embed_dot_grad - new_embed_dot_grad
      )
      neg_dir_dot_grad = neg_dir_dot_grad.detach().cpu().numpy()
      # Do not replace with non-alphanumeric tokens
      neg_dir_dot_grad[
          :, :, self.invalid_replacement_indices
      ] = -numpy.inf
      best_at_each_step = neg_dir_dot_grad.argmax(2)
      return best_at_each_step[0].data[0]
  
imports: from copy import deepcopy
  from typing import Dict, List, Tuple
  import numpy
  import torch
  from allennlp.common.util import JsonDict, sanitize
  from allennlp.data import Instance, Token
  from allennlp.data.fields import TextField
  from allennlp.data.token_indexers import ELMoTokenCharactersIndexer, TokenCharactersIndexer, SingleIdTokenIndexer
  from allennlp.interpret.attackers import utils
  from allennlp.interpret.attackers.attacker import Attacker
  from allennlp.modules.token_embedders import Embedding
  from allennlp.nn import util
  from allennlp.predictors.predictor import Predictor
label_desc: Use image node_id 7 for calling the Hotflip obj's underlying member method code with example usage: obj._first_order_taylor(grad, token_idx, sign) and returns: best_at_each_step