File size: 3,461 Bytes
a9ecc32 d40e838 a9ecc32 d40e838 a9ecc32 d40e838 a9ecc32 d40e838 af1ba97 a9ecc32 d40e838 a9ecc32 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 |
import datasets
import evaluate
from typing import List
import torch
_DESCRIPTION = """
Quantifying encoder feature distribution properties, Alignment and Uniformity on the Hypersphere.
(https://github.com/ssnl/align_uniform)
"""
_KWARGS_DESCRIPTION = """
Args:
xs (`list` of a list of `int`): a group of embeddings
ys (`list` of `int`): the other group of embeddings paired with the ys
Returns:
"align_loss": float(align_loss_val),
"x_unif_loss": float(x_unif_loss_v),
"y_unif_loss": float(y_unif_loss_v),
"unif_loss": float(unif_loss)
Examples:
Example 1-A simple example
>>> metrics = evaluate.load("ahnyeonchan/Alignment-and-Uniformity")
>>> results = metrics.compute(xs=[[1.0, 1.0], [0.0, 1.0]], ys=[[1.0, 1.0], [0.0, 1.0]])
>>> print(results)
{'align_loss': 0.0, 'x_unif_loss': -2.0, 'y_unif_loss': -2.0, 'unif_loss': -2.0}
"""
_CITATION = """"""
def align_loss(x, y, alpha=2):
return (x - y).norm(p=2, dim=1).pow(alpha).mean()
def uniform_loss(x, t=2):
return torch.pdist(x, p=2).pow(2).mul(-t).exp().mean().log()
def nonneg_uniform_loss(x, t=2):
tmp = torch.pdist(x, p=2).pow(2)
original = tmp.mul(-t).exp().mean().log()
boundary = -t * tmp.mean()
return original - boundary
@evaluate.utils.file_utils.add_start_docstrings(_DESCRIPTION, _KWARGS_DESCRIPTION)
class AlignmentandUniformity(evaluate.Metric):
def __init__(self, align_alpha: float = 2.0, unif_t: float = 2.0,
*args, **kwargs):
super(AlignmentandUniformity, self).__init__(*args, **kwargs)
self.align_alpha = align_alpha
self.unif_t = unif_t
def _info(self):
return evaluate.MetricInfo(
description=_DESCRIPTION,
citation=_CITATION,
inputs_description=_KWARGS_DESCRIPTION,
features=datasets.Features(
{
"xs": datasets.Sequence(datasets.Value("float32")),
"ys": datasets.Sequence(datasets.Value("float32")),
}
),
reference_urls=[],
)
def _compute(self, xs: List[List], ys: List[List]):
if isinstance(xs, torch.Tensor):
xs = torch.Tensor(xs)
elif isinstance(ys, list):
xs = torch.Tensor(xs)
else:
raise NotImplementedError()
if isinstance(ys, torch.Tensor):
ys = torch.Tensor(ys)
elif isinstance(ys, list):
ys = torch.Tensor(ys)
else:
raise NotImplementedError()
align_loss_val = align_loss(xs, ys, self.align_alpha)
x_unif_loss_v = uniform_loss(xs, t=self.unif_t)
y_unif_loss_v = uniform_loss(ys, t=self.unif_t)
unif_loss = (x_unif_loss_v + y_unif_loss_v) / 2
nn_x_unif_loss_v = nonneg_uniform_loss(xs, t=self.unif_t)
nn_y_unif_loss_v = nonneg_uniform_loss(ys, t=self.unif_t)
nn_unif_loss = (nn_x_unif_loss_v + nn_y_unif_loss_v) / 2
return {
"align_loss": float(align_loss_val),
"x_unif_loss": float(x_unif_loss_v),
"y_unif_loss": float(y_unif_loss_v),
"unif_loss": float(unif_loss),
"nonneg_x_unif_loss": float(nn_x_unif_loss_v),
"nonneg_y_unif_loss": float(nn_y_unif_loss_v),
"nonneg_unif_loss": float(nn_unif_loss)
}
|