class_docstr: 对YOLO的输出进行处理
class_docstr_tok: ["\u5bf9YOLO\u7684\u8f93\u51fa\u8fdb\u884c\u5904\u7406"]
code: def forward(self, p):
      if ONNX_EXPORT:
          bs = 1  # batch size
      else:
          (
              bs,
              _,
              ny,
              nx,
          ) = (
              p.shape
          )  # batch_size, predict_param(255), grid(13), grid(13)
          if (self.nx, self.ny) != (
              nx,
              ny,
          ) or self.grid is None:  # fix no grid bug
              self.create_grids((nx, ny), p.device)
  
      # view: (batch_size, 255, 13, 13) -> (batch_size, 3, 85, 13, 13)
      # permute: (batch_size, 3, 85, 13, 13) -> (batch_size, 3, 13, 13, 85)
      # [bs, anchor, grid, grid, xywh + obj + classes]
      p = (
          p.view(bs, self.na, self.no, self.ny, self.nx)
          .permute(0, 1, 3, 4, 2)
          .contiguous()
      )  # prediction
  
      if self.training:
          return p
      elif ONNX_EXPORT:
          # Avoid broadcasting for ANE operations
          m = self.na * self.nx * self.ny  # 3*
          ng = 1.0 / self.ng.repeat(m, 1)
          grid = self.grid.repeat(1, self.na, 1, 1, 1).view(m, 2)
          anchor_wh = (
              self.anchor_wh.repeat(1, 1, self.nx, self.ny, 1).view(
                  m, 2
              )
              * ng
          )
  
          p = p.view(m, self.no)
          # xy = torch.sigmoid(p[:, 0:2]) + grid  # x, y
          # wh = torch.exp(p[:, 2:4]) * anchor_wh  # width, height
          # p_cls = torch.sigmoid(p[:, 4:5]) if self.nc == 1 else \
          #     torch.sigmoid(p[:, 5:self.no]) * torch.sigmoid(p[:, 4:5])  # conf
          p[:, :2] = (torch.sigmoid(p[:, 0:2]) + grid) * ng  # x, y
          p[:, 2:4] = torch.exp(p[:, 2:4]) * anchor_wh  # width, height
          p[:, 4:] = torch.sigmoid(p[:, 4:])
          p[:, 5:] = p[:, 5 : self.no] * p[:, 4:5]
          return p
      else:  # inference
          # [bs, anchor, grid, grid, xywh + obj + classes]
          io = p.clone()  # inference output
          io[..., :2] = (
              torch.sigmoid(io[..., :2]) + self.grid
          )  # xy 计算在feature map上的xy坐标
          io[..., 2:4] = (
              torch.exp(io[..., 2:4]) * self.anchor_wh
          )  # wh yolo method 计算在feature map上的wh
          io[..., :4] *= self.stride  # 换算映射回原图尺度
          torch.sigmoid_(io[..., 4:])
          return io.view(bs, -1, self.no), p
  
file_path: deep-learning-for-image-processing/pytorch_object_detection/yolov3_spp/models.py
imports: from build_utils.layers import *
  from build_utils.parse_config import *
label_desc: Use image node_id 3 for calling the YOLOLayer obj's underlying member method code with example usage: obj.forward(p) and returns: p, p, io,  p