docstr: Transformation stage 
code: def forward(self, input, text, is_train=True):
      """Transformation stage"""
      if not self.stages["Trans"] == "None":
          input = self.Transformation(input)
  
      """ Feature extraction stage """
      visual_feature = self.FeatureExtraction(input)
      visual_feature = self.AdaptiveAvgPool(
          visual_feature.permute(0, 3, 1, 2)
      )  # [b, c, h, w] -> [b, w, c, h]
      visual_feature = visual_feature.squeeze(3)
  
      """ Sequence modeling stage """
      if self.stages["Seq"] == "BiLSTM":
          contextual_feature = self.SequenceModeling(visual_feature)
      else:
          contextual_feature = visual_feature  # for convenience. this is NOT contextually modeled by BiLSTM
  
      """ Prediction stage """
      if self.stages["Pred"] == "CTC":
          prediction = self.Prediction(contextual_feature.contiguous())
      else:
          prediction = self.Prediction(
              contextual_feature.contiguous(),
              text,
              is_train,
              batch_max_length=self.opt.batch_max_length,
          )
  
      return prediction
  
file_path: EasyOCR/trainer/model.py
imports: import torch.nn
  from modules.transformation import TPS_SpatialTransformerNetwork
  from modules.feature_extraction import VGG_FeatureExtractor, RCNN_FeatureExtractor, ResNet_FeatureExtractor
  from modules.sequence_modeling import BidirectionalLSTM
  from modules.prediction import Attention
label_desc: Use image node_id 2 for calling the Model obj's underlying member method code with example usage: obj.forward(input, text, is_train) and returns: prediction