def predict_by_feat(self,
                        cls_scores: List[Tensor],
                        bbox_preds: List[Tensor],
                        objectnesses: Optional[List[Tensor]] = None,
                        kpt_preds: Optional[List[Tensor]] = None,
                        vis_preds: Optional[List[Tensor]] = None,
                        batch_img_metas: Optional[List[dict]] = None,
                        cfg: Optional[ConfigDict] = None,
                        rescale: bool = True,
                        with_nms: bool = True) -> List[InstanceData]:
        """Transform a batch of output features extracted by the head into bbox
        and keypoint results.

        In addition to the base class method, keypoint predictions are also
        calculated in this method.
        """

        # calculate predicted bboxes and get the kept instances indices
        with OutputSaveFunctionWrapper(
                filter_scores_and_topk,
                super().predict_by_feat.__globals__) as outputs_1:
            with OutputSaveFunctionWrapper(
                    batched_nms,
                    super()._bbox_post_process.__globals__) as outputs_2:
                results_list = super().predict_by_feat(cls_scores, bbox_preds,
                                                       objectnesses,
                                                       batch_img_metas, cfg,
                                                       rescale, with_nms)
                keep_indices_topk = [out[2] for out in outputs_1]
                keep_indices_nms = [out[1] for out in outputs_2]

        num_imgs = len(batch_img_metas)

        # recover keypoints coordinates from model predictions
        featmap_sizes = [vis_pred.shape[2:] for vis_pred in vis_preds]
        priors = torch.cat(self.mlvl_priors)
        strides = [
            priors.new_full((featmap_size.numel() * self.num_base_priors, ),
                            stride) for featmap_size, stride in zip(
                                featmap_sizes, self.featmap_strides)
        ]
        strides = torch.cat(strides)
        kpt_preds = torch.cat([
            kpt_pred.permute(0, 2, 3, 1).reshape(
                num_imgs, -1, self.num_keypoints * 2) for kpt_pred in kpt_preds
        ],
                              dim=1)
        flatten_decoded_kpts = self.decode_pose(priors, kpt_preds, strides)

        vis_preds = torch.cat([
            vis_pred.permute(0, 2, 3, 1).reshape(
                num_imgs, -1, self.num_keypoints) for vis_pred in vis_preds
        ],
                              dim=1).sigmoid()

        # select keypoints predictions according to bbox scores and nms result
        keep_indices_nms_idx = 0
        for pred_instances, kpts, kpts_vis, img_meta, keep_idxs \
            in zip(
                results_list, flatten_decoded_kpts, vis_preds,
                batch_img_metas, keep_indices_topk):

            pred_instances.bbox_scores = pred_instances.scores

            if len(pred_instances) == 0:
                pred_instances.keypoints = kpts[:0]
                pred_instances.keypoint_scores = kpts_vis[:0]
                continue

            kpts = kpts[keep_idxs]
            kpts_vis = kpts_vis[keep_idxs]

            if rescale:
                pad_param = img_meta.get('img_meta', None)
                scale_factor = img_meta['scale_factor']
                if pad_param is not None:
                    kpts -= kpts.new_tensor([pad_param[2], pad_param[0]])
                kpts /= kpts.new_tensor(scale_factor).repeat(
                    (1, self.num_keypoints, 1))

            keep_idxs_nms = keep_indices_nms[keep_indices_nms_idx]
            kpts = kpts[keep_idxs_nms]
            kpts_vis = kpts_vis[keep_idxs_nms]
            keep_indices_nms_idx += 1

            pred_instances.keypoints = kpts
            pred_instances.keypoint_scores = kpts_vis

        return results_list
Transform a batch of output features extracted by the head into bbox
        and keypoint results.

        In addition to the base class method, keypoint predictions are also
        calculated in this method.
        
mmpose/projects/yolox_pose/models/yolox_pose_head.py