docstr: Hierarchical attention, primarily used for getting best inference
  results.
  
  We use attention at multiple scales, giving priority to the lower
  resolutions. For example, if we have 4 scales {0.5, 1.0, 1.5, 2.0},
  then evaluation is done as follows:
  
        p_joint = attn_1.5 * p_1.5 + (1 - attn_1.5) * down(p_2.0)
        p_joint = attn_1.0 * p_1.0 + (1 - attn_1.0) * down(p_joint)
        p_joint = up(attn_0.5 * p_0.5) * (1 - up(attn_0.5)) * p_joint
  
  The target scale is always 1.0, and 1.0 is expected to be part of the
  list of scales. When predictions are done at greater than 1.0 scale,
  the predictions are downsampled before combining with the next lower
  scale.
  
  x_1x:
    scales - a list of scales to evaluate
    x_1x - dict containing 'images', the x_1x, and 'gts', the ground
             truth mask
  
  Output:
    If training, return loss, else return prediction + attention
docstr_tok: ["Hierarchical","attention",",","primarily","used","for","getting","best","inference","results",".","We","use","attention","at","multiple","scales",",","giving","priority","to","the","lower","resolutions",".","For","example",",","if","we","have","4","scales","{","0.5",",","1.0",",","1.5",",","2.0","}",",","then","evaluation","is","done","as","follows",":","p_joint","=","attn_1.5","*","p_1.5","+","(","1","-","attn_1.5",")","*","down","(","p_2.0",")","p_joint","=","attn_1.0","*","p_1.0","+","(","1","-","attn_1.0",")","*","down","(","p_joint",")","p_joint","=","up","(","attn_0.5","*","p_0.5",")","*","(","1","-","up","(","attn_0.5",")",")","*","p_joint","The","target","scale","is","always","1.0",",","and","1.0","is","expected","to","be","part","of","the","list","of","scales",".","When","predictions","are","done","at","greater","than","1.0","scale",",","the","predictions","are","downsampled","before","combining","with","the","next","lower","scale",".","x_1x",":","scales","-","a","list","of","scales","to","evaluate","x_1x","-","dict","containing","'images","'",",","the","x_1x",",","and","'gts","'",",","the","ground","truth","mask","Output",":","If","training",",","return","loss",",","else","return","prediction","+","attention"]
code: def nscale_forward(self, x_1x, scales):
      """
      Hierarchical attention, primarily used for getting best inference
      results.
  
      We use attention at multiple scales, giving priority to the lower
      resolutions. For example, if we have 4 scales {0.5, 1.0, 1.5, 2.0},
      then evaluation is done as follows:
  
            p_joint = attn_1.5 * p_1.5 + (1 - attn_1.5) * down(p_2.0)
            p_joint = attn_1.0 * p_1.0 + (1 - attn_1.0) * down(p_joint)
            p_joint = up(attn_0.5 * p_0.5) * (1 - up(attn_0.5)) * p_joint
  
      The target scale is always 1.0, and 1.0 is expected to be part of the
      list of scales. When predictions are done at greater than 1.0 scale,
      the predictions are downsampled before combining with the next lower
      scale.
  
      x_1x:
        scales - a list of scales to evaluate
        x_1x - dict containing 'images', the x_1x, and 'gts', the ground
                 truth mask
  
      Output:
        If training, return loss, else return prediction + attention
      """
      assert 1.0 in scales, "expected 1.0 to be the target scale"
      # Lower resolution provides attention for higher rez predictions,
      # so we evaluate in order: high to low
      scales = sorted(scales, reverse=True)
  
      pred = None
  
      for s in scales:
          x = nn.functional.interpolate(
              x_1x,
              scale_factor=s,
              align_corners=self.align_corners,
              mode="bilinear",
          )
          outs = self.single_scale_forward(x)
  
          cls_out = outs["cls_out"]
          attn_out = outs["logit_attn"]
  
          if pred is None:
              pred = cls_out
          elif s >= 1.0:
              # downscale previous
              pred = scale_as(pred, cls_out, self.align_corners)
              pred = cls_out * attn_out + pred * (1 - attn_out)
          else:
              # s < 1.0: upscale current
              cls_out = cls_out * attn_out
  
              cls_out = scale_as(cls_out, pred, self.align_corners)
              attn_out = scale_as(attn_out, pred, self.align_corners)
  
              pred = cls_out + pred * (1 - attn_out)
  
      return [pred]
  
imports: import math
  import paddle
  import paddle.nn
  from paddleseg.cvlibs import manager, param_init
  from paddleseg.utils import utils
  from paddleseg.models import layers
  from .ocrnet_nv import OCRNetNV
label_desc: Use image node_id 7 for calling the MscaleOCRNet obj's underlying member method code with example usage: obj.nscale_forward(x_1x, scales) and returns: list