docstr: input:
      batch_H : contextual_feature H = hidden state of encoder. [batch_size x num_steps x num_classes]
      text : the text-index of each image. [batch_size x (max_length+1)]. +1 for [GO] token. text[:, 0] = [GO].
  output: probability distribution at each step [batch_size x num_steps x num_classes]
docstr_tok: ["input",":","batch_H",":","contextual_feature","H","=","hidden","state","of","encoder",".","[","batch_size","x","num_steps","x","num_classes","]","text",":","the","text-index","of","each","image",".","[","batch_size","x","(","max_length+1",")","]",".","+1","for","[","GO","]","token",".","text","[",":",",","0","]","=","[","GO","]",".","output",":","probability","distribution","at","each","step","[","batch_size","x","num_steps","x","num_classes","]"]
code: def forward(self, batch_H, text, is_train=True, batch_max_length=25):
      """
      input:
          batch_H : contextual_feature H = hidden state of encoder. [batch_size x num_steps x num_classes]
          text : the text-index of each image. [batch_size x (max_length+1)]. +1 for [GO] token. text[:, 0] = [GO].
      output: probability distribution at each step [batch_size x num_steps x num_classes]
      """
      batch_size = batch_H.size(0)
      num_steps = batch_max_length + 1  # +1 for [s] at end of sentence.
  
      output_hiddens = (
          torch.FloatTensor(batch_size, num_steps, self.hidden_size)
          .fill_(0)
          .to(device)
      )
      hidden = (
          torch.FloatTensor(batch_size, self.hidden_size)
          .fill_(0)
          .to(device),
          torch.FloatTensor(batch_size, self.hidden_size)
          .fill_(0)
          .to(device),
      )
  
      if is_train:
          for i in range(num_steps):
              # one-hot vectors for a i-th char. in a batch
              char_onehots = self._char_to_onehot(
                  text[:, i], onehot_dim=self.num_classes
              )
              # hidden : decoder's hidden s_{t-1}, batch_H : encoder's hidden H, char_onehots : one-hot(y_{t-1})
              hidden, alpha = self.attention_cell(
                  hidden, batch_H, char_onehots
              )
              output_hiddens[:, i, :] = hidden[
                  0
              ]  # LSTM hidden index (0: hidden, 1: Cell)
          probs = self.generator(output_hiddens)
  
      else:
          targets = (
              torch.LongTensor(batch_size).fill_(0).to(device)
          )  # [GO] token
          probs = (
              torch.FloatTensor(batch_size, num_steps, self.num_classes)
              .fill_(0)
              .to(device)
          )
  
          for i in range(num_steps):
              char_onehots = self._char_to_onehot(
                  targets, onehot_dim=self.num_classes
              )
              hidden, alpha = self.attention_cell(
                  hidden, batch_H, char_onehots
              )
              probs_step = self.generator(hidden[0])
              probs[:, i, :] = probs_step
              _, next_input = probs_step.max(1)
              targets = next_input
  
      return probs
  
file_path: EasyOCR/trainer/modules/prediction.py
imports: import torch
  import torch.nn
  import torch.nn.functional
label_desc: Use image node_id 3 for calling the Attention obj's underlying member method code with example usage: obj.forward(batch_H, text, is_train, batch_max_length) and returns: probs