wxDai's picture
[Init]
eb339cb
import torch
from torchmetrics import Metric
from torchmetrics.utilities import dim_zero_cat
from mld.utils.temos_utils import remove_padding
from .utils import calculate_skating_ratio, calculate_trajectory_error, control_l2
class ControlMetrics(Metric):
def __init__(self, dataset_name: str, dist_sync_on_step: bool = True) -> None:
super().__init__(dist_sync_on_step=dist_sync_on_step)
self.name = "Control errors"
self.dataset_name = dataset_name
self.add_state("count_seq", default=torch.tensor(0), dist_reduce_fx="sum")
self.add_state("skate_ratio_sum", default=torch.tensor(0.), dist_reduce_fx="sum")
self.add_state("dist_sum", default=torch.tensor(0.), dist_reduce_fx="sum")
self.add_state("traj_err", default=[], dist_reduce_fx="cat")
self.traj_err_key = ["traj_fail_20cm", "traj_fail_50cm", "kps_fail_20cm", "kps_fail_50cm", "kps_mean_err(m)"]
def compute(self) -> dict:
count_seq = self.count_seq.item()
metrics = dict()
metrics['Skating Ratio'] = self.skate_ratio_sum / count_seq
metrics['Control L2 dist'] = self.dist_sum / count_seq
traj_err = dim_zero_cat(self.traj_err).mean(0)
for (k, v) in zip(self.traj_err_key, traj_err):
metrics[k] = v
return metrics
def update(self, joints: torch.Tensor, hint: torch.Tensor,
hint_mask: torch.Tensor, lengths: list[int]) -> None:
self.count_seq += len(lengths)
joints_no_padding = remove_padding(joints, lengths)
for j in joints_no_padding:
skate_ratio, _ = calculate_skating_ratio(j.unsqueeze(0), self.dataset_name)
self.skate_ratio_sum += skate_ratio[0]
hint_mask = hint_mask.sum(dim=-1, keepdim=True) != 0
for j, h, m in zip(joints, hint, hint_mask):
control_error = control_l2(j, h, m)
mean_error = control_error.sum() / m.sum()
self.dist_sum += mean_error
control_error = control_error.reshape(-1)
m = m.reshape(-1)
err_np = calculate_trajectory_error(control_error, mean_error, m)
self.traj_err.append(err_np[None].to(joints.device))