def torch_calculate_frechet_distance(mu1, sigma1, mu2, sigma2, eps=1e-6): mu1 = torch.Tensor(mu1.astype("float32")) sigma1 = torch.Tensor(sigma1.astype("float32")) mu2 = torch.Tensor(mu2.astype("float32")) sigma2 = torch.Tensor(sigma2.astype("float32")) """Pytorch implementation of the Frechet Distance. Taken from https://github.com/bioinf-jku/TTUR The Frechet distance between two multivariate Gaussians X_1 ~ N(mu_1, C_1) and X_2 ~ N(mu_2, C_2) is d^2 = ||mu_1 - mu_2||^2 + Tr(C_1 + C_2 - 2*sqrt(C_1*C_2)). Stable version by Dougal J. Sutherland. Params: -- mu1 : Numpy array containing the activations of a layer of the inception net (like returned by the function 'get_predictions') for generated samples. -- mu2 : The sample mean over activations, precalculated on an representive data set. -- sigma1: The covariance matrix over activations for generated samples. -- sigma2: The covariance matrix over activations, precalculated on an representive data set. Returns: -- : The Frechet Distance. """ assert mu1.shape == mu2.shape, \ 'Training and test mean vectors have different lengths' assert sigma1.shape == sigma2.shape, \ 'Training and test covariances have different dimensions' diff = mu1 - mu2 # Run 50 itrs of newton-schulz to get the matrix sqrt of sigma1 dot sigma2 covmean = torch.Tensor( sqrt_newton_schulz(torch.Tensor(sigma1).mm(sigma2).unsqueeze(0), 50)).squeeze() out = (torch.dot(diff, diff) + torch.trace(sigma1) + torch.trace(sigma2) - 2 * torch.trace(covmean)) return out
def dot(self, x): return torch.dot(self, x)