| | |
| | |
| |
|
| | import pandas as pd |
| | import torch |
| |
|
| |
|
| | |
| | class MetricTracker: |
| | def __init__(self, *keys, writer=None): |
| | self.writer = writer |
| | self._data = pd.DataFrame(index=keys, columns=["total", "counts", "average"]) |
| | self.reset() |
| |
|
| | def reset(self): |
| | for col in self._data.columns: |
| | self._data[col].values[:] = 0 |
| |
|
| | def update(self, key, value, n=1): |
| | if self.writer is not None: |
| | self.writer.add_scalar(key, value) |
| | self._data.loc[key, "total"] += value * n |
| | self._data.loc[key, "counts"] += n |
| | self._data.loc[key, "average"] = self._data.total[key] / self._data.counts[key] |
| |
|
| | def avg(self, key): |
| | return self._data.average[key] |
| |
|
| | def result(self): |
| | return dict(self._data.average) |
| |
|
| | def pixel_mean(pred, gt, valid_mask): |
| | if valid_mask is not None: |
| | masked_pred = pred * valid_mask |
| | masked_gt = gt * valid_mask |
| |
|
| | valid_pixel_count = torch.sum(valid_mask, dim=(0,1)) |
| |
|
| | pred_mean = torch.sum(masked_pred, dim=(0,1)) / valid_pixel_count |
| | gt_mean = torch.sum(masked_gt, dim=(0,1)) / valid_pixel_count |
| | else: |
| | pred_mean = torch.mean(pred, dim=(0,1)) |
| | gt_mean = torch.mean(gt, dim=(0,1)) |
| |
|
| | mean_difference = torch.abs(pred_mean - gt_mean) |
| | return mean_difference |
| |
|
| | def pixel_var(pred, gt, valid_mask): |
| | if valid_mask is not None: |
| | masked_pred = pred * valid_mask |
| | masked_gt = gt * valid_mask |
| |
|
| | valid_pixel_count = torch.sum(valid_mask, dim=(0,1)) |
| |
|
| | pred_mean = torch.sum(masked_pred, dim=(0,1)) / valid_pixel_count |
| | gt_mean = torch.sum(masked_gt, dim=(0,1)) / valid_pixel_count |
| |
|
| | pred_var = torch.sum(valid_mask * (pred - pred_mean)**2, dim=(0,1)) / valid_pixel_count |
| | gt_var = torch.sum(valid_mask * (gt - gt_mean)**2, dim=(0,1)) / valid_pixel_count |
| | else: |
| | pred_var = torch.var(pred, dim=(0,1)) |
| | gt_var = torch.var(gt, dim=(0,1)) |
| |
|
| | var_difference = torch.abs(pred_var - gt_var) |
| |
|
| | return var_difference |
| |
|
| | def abs_relative_difference(output, target, valid_mask=None): |
| | actual_output = output |
| | actual_target = target |
| | abs_relative_diff = torch.abs(actual_output - actual_target) / actual_target |
| | if valid_mask is not None: |
| | abs_relative_diff[~valid_mask] = 0 |
| | n = valid_mask.sum((-1, -2)) |
| | else: |
| | n = output.shape[-1] * output.shape[-2] |
| | abs_relative_diff = torch.sum(abs_relative_diff, (-1, -2)) / n |
| | return abs_relative_diff.mean() |
| |
|
| |
|
| | def squared_relative_difference(output, target, valid_mask=None): |
| | actual_output = output |
| | actual_target = target |
| | square_relative_diff = ( |
| | torch.pow(torch.abs(actual_output - actual_target), 2) / actual_target |
| | ) |
| | if valid_mask is not None: |
| | square_relative_diff[~valid_mask] = 0 |
| | n = valid_mask.sum((-1, -2)) |
| | else: |
| | n = output.shape[-1] * output.shape[-2] |
| | square_relative_diff = torch.sum(square_relative_diff, (-1, -2)) / n |
| | return square_relative_diff.mean() |
| |
|
| |
|
| | def rmse_linear(output, target, valid_mask=None): |
| | actual_output = output |
| | actual_target = target |
| | diff = actual_output - actual_target |
| | if valid_mask is not None: |
| | diff[~valid_mask] = 0 |
| | n = valid_mask.sum((-1, -2)) |
| | else: |
| | n = output.shape[-1] * output.shape[-2] |
| | diff2 = torch.pow(diff, 2) |
| | mse = torch.sum(diff2, (-1, -2)) / n |
| | rmse = torch.sqrt(mse) |
| | return rmse.mean() |
| |
|
| |
|
| | def rmse_log(output, target, valid_mask=None): |
| | diff = torch.log(output) - torch.log(target) |
| | if valid_mask is not None: |
| | diff[~valid_mask] = 0 |
| | n = valid_mask.sum((-1, -2)) |
| | else: |
| | n = output.shape[-1] * output.shape[-2] |
| | diff2 = torch.pow(diff, 2) |
| | mse = torch.sum(diff2, (-1, -2)) / n |
| | rmse = torch.sqrt(mse) |
| | return rmse.mean() |
| |
|
| |
|
| | def log10(output, target, valid_mask=None): |
| | if valid_mask is not None: |
| | diff = torch.abs( |
| | torch.log10(output[valid_mask]) - torch.log10(target[valid_mask]) |
| | ) |
| | else: |
| | diff = torch.abs(torch.log10(output) - torch.log10(target)) |
| | return diff.mean() |
| |
|
| |
|
| | |
| | def threshold_percentage(output, target, threshold_val, valid_mask=None): |
| | d1 = output / target |
| | d2 = target / output |
| | max_d1_d2 = torch.max(d1, d2) |
| | zero = torch.zeros(*output.shape) |
| | one = torch.ones(*output.shape) |
| | bit_mat = torch.where(max_d1_d2.cpu() < threshold_val, one, zero) |
| | if valid_mask is not None: |
| | bit_mat[~valid_mask] = 0 |
| | n = valid_mask.sum((-1, -2)) |
| | else: |
| | n = output.shape[-1] * output.shape[-2] |
| | count_mat = torch.sum(bit_mat, (-1, -2)) |
| | threshold_mat = count_mat / n.cpu() |
| | return threshold_mat.mean() |
| |
|
| |
|
| | def delta1_acc(pred, gt, valid_mask): |
| | return threshold_percentage(pred, gt, 1.25, valid_mask) |
| |
|
| |
|
| | def delta2_acc(pred, gt, valid_mask): |
| | return threshold_percentage(pred, gt, 1.25**2, valid_mask) |
| |
|
| |
|
| | def delta3_acc(pred, gt, valid_mask): |
| | return threshold_percentage(pred, gt, 1.25**3, valid_mask) |
| |
|
| |
|
| | def i_rmse(output, target, valid_mask=None): |
| | output_inv = 1.0 / output |
| | target_inv = 1.0 / target |
| | diff = output_inv - target_inv |
| | if valid_mask is not None: |
| | diff[~valid_mask] = 0 |
| | n = valid_mask.sum((-1, -2)) |
| | else: |
| | n = output.shape[-1] * output.shape[-2] |
| | diff2 = torch.pow(diff, 2) |
| | mse = torch.sum(diff2, (-1, -2)) / n |
| | rmse = torch.sqrt(mse) |
| | return rmse.mean() |
| |
|
| |
|
| | def silog_rmse(depth_pred, depth_gt, valid_mask=None): |
| | diff = torch.log(depth_pred) - torch.log(depth_gt) |
| | if valid_mask is not None: |
| | diff[~valid_mask] = 0 |
| | n = valid_mask.sum((-1, -2)) |
| | else: |
| | n = depth_gt.shape[-2] * depth_gt.shape[-1] |
| |
|
| | diff2 = torch.pow(diff, 2) |
| |
|
| | first_term = torch.sum(diff2, (-1, -2)) / n |
| | second_term = torch.pow(torch.sum(diff, (-1, -2)), 2) / (n**2) |
| | loss = torch.sqrt(torch.mean(first_term - second_term)) * 100 |
| | return loss |
| |
|