import torch from torchmetrics import Metric from mld.utils.temos_utils import remove_padding from .utils import calculate_mpjpe class PosMetrics(Metric): def __init__(self, dist_sync_on_step: bool = True) -> None: super().__init__(dist_sync_on_step=dist_sync_on_step) self.name = "MPJPE (aligned & unaligned), Feature l2 error" self.add_state("count", default=torch.tensor(0), dist_reduce_fx="sum") self.add_state("mpjpe_sum", default=torch.tensor(0.), dist_reduce_fx="sum") self.add_state("mpjpe_unaligned_sum", default=torch.tensor(0.), dist_reduce_fx="sum") self.add_state("feature_error_sum", default=torch.tensor(0.), dist_reduce_fx="sum") def compute(self) -> dict: metric = dict(MPJPE=self.mpjpe_sum / self.count, MPJPE_unaligned=self.mpjpe_unaligned_sum / self.count, FeaError=self.feature_error_sum / self.count) return metric def update(self, joints_ref: torch.Tensor, joints_rst: torch.Tensor, feats_ref: torch.Tensor, feats_rst: torch.Tensor, lengths: list[int]) -> None: self.count += sum(lengths) joints_rst = remove_padding(joints_rst, lengths) joints_ref = remove_padding(joints_ref, lengths) feats_ref = remove_padding(feats_ref, lengths) feats_rst = remove_padding(feats_rst, lengths) for f1, f2 in zip(feats_ref, feats_rst): self.feature_error_sum += torch.norm(f1 - f2, p=2) for j1, j2 in zip(joints_ref, joints_rst): mpjpe = torch.sum(calculate_mpjpe(j1, j2)) self.mpjpe_sum += mpjpe mpjpe_unaligned = torch.sum(calculate_mpjpe(j1, j2, align_root=False)) self.mpjpe_unaligned_sum += mpjpe_unaligned