26 lines
1.2 KiB
Python
26 lines
1.2 KiB
Python
import torch
|
|
|
|
|
|
def ava_active_speaker_map(scores, labels):
|
|
scores = torch.as_tensor(scores, dtype=torch.float64).flatten()
|
|
labels = torch.as_tensor(labels, device=scores.device).bool().flatten()
|
|
if scores.shape != labels.shape:
|
|
raise ValueError("scores and labels must have the same shape")
|
|
if not torch.isfinite(scores).all():
|
|
raise ValueError("scores contain NaN or infinite values")
|
|
|
|
positives = labels.sum()
|
|
if not len(labels) or positives == 0:
|
|
return 0.0
|
|
|
|
order = torch.argsort(scores, descending=True, stable=True)
|
|
true_positives = labels[order].cumsum(0)
|
|
precision = true_positives / torch.arange(1, len(labels) + 1, dtype=torch.float64, device=scores.device)
|
|
recall = true_positives / positives
|
|
precision = torch.cat([precision.new_zeros(1), precision, precision.new_zeros(1)])
|
|
recall = torch.cat([recall.new_zeros(1), recall, recall.new_ones(1)])
|
|
precision = torch.flip(torch.cummax(torch.flip(precision, dims=[0]), dim=0).values, dims=[0])
|
|
indices = torch.where(recall[1:] != recall[:-1])[0] + 1
|
|
average_precision = ((recall[indices] - recall[indices - 1]) * precision[indices]).sum()
|
|
return 100 * average_precision.item()
|