code: def direction_loss(self, f_direction, l_direction, l_score, l_mask):
      l_direction_split, l_direction_norm = paddle.tensor.split(
          l_direction, num_or_sections=[2, 1], axis=1
      )
      f_direction_split = f_direction
      b, c, h, w = l_direction_norm.shape
      l_direction_norm_split = paddle.expand(
          x=l_direction_norm, shape=[b, 2 * c, h, w]
      )
      b, c, h, w = l_score.shape
      l_direction_score = paddle.expand(
          x=l_score, shape=[b, 2 * c, h, w]
      )
      b, c, h, w = l_mask.shape
      l_direction_mask = paddle.expand(x=l_mask, shape=[b, 2 * c, h, w])
      direction_diff = l_direction_split - f_direction_split
      abs_direction_diff = paddle.abs(direction_diff)
      direction_sign = abs_direction_diff < 1.0
      direction_sign = paddle.cast(direction_sign, dtype="float32")
      direction_sign.stop_gradient = True
      direction_in_loss = (
          0.5 * abs_direction_diff * abs_direction_diff * direction_sign
          + (abs_direction_diff - 0.5) * (1.0 - direction_sign)
      )
      direction_out_loss = l_direction_norm_split * direction_in_loss
      direction_loss = paddle.sum(
          direction_out_loss * l_direction_score * l_direction_mask
      ) / (paddle.sum(l_direction_score * l_direction_mask) + 1e-5)
      return direction_loss
  
file_path: PaddleOCR/ppocr/losses/e2e_pg_loss.py
imports: from __future__ import absolute_import
  from __future__ import division
  from __future__ import print_function
  from paddle import nn
  import paddle
  from .det_basic_loss import DiceLoss
  from ppocr.utils.e2e_utils.extract_batchsize import pre_process
label_desc: Use image node_id 3 for calling the PGLoss obj's underlying member method code with example usage: obj.direction_loss(f_direction, l_direction, l_score, l_mask) and returns: direction_loss