Source code for scorers.exponential_scorer

import torch
import numpy as np

from .positive_scorer import PositiveScorer
from disco.utils.device import get_device


[docs]class ExponentialScorer(PositiveScorer): """Exponential scorer to add distributional constraints when building an EBM. """ def __init__(self, features, coefficients): """ Parameters ---------- features: list(Scorer) scoring features coefficients: list(float) features' coefficients """ if not len(features) == len(coefficients): raise ValueError("there should be as many as many coefficients as there are features.") self.features = features if type(coefficients) in [list, np.ndarray]: self.coefficients = torch.tensor(coefficients) else: self.coefficients = coefficients if torch.Tensor != type(self.coefficients): raise TypeError("coefficients should come in a tensor, or a tensorable structure.")
[docs] def log_score(self, samples, context): """Log-scores the samples given the context using the instance's features and their coefficients Parameters ---------- samples : list(str) list of samples to log-score context: text context used for the samples Returns ------- tensor of log-scores""" device = get_device(self.coefficients) feature_log_scores = torch.stack( ([feature.score(samples, context).to(device) for feature in self.features]) ) # [n_features, n_samples] weighted_log_scores = self.coefficients.repeat(len(samples), 1) * feature_log_scores.t() return weighted_log_scores.sum(dim=1)
def __str__(self): return f"ExponentialScorer({self.features}, {self.coefficients})"