def main(): x_features = torch.rand(2000, 128) y_features = torch.rand(2000, 128) if torch.cuda.is_available(): # Move to GPU to make computaions faster x_features = x_features.cuda() y_features = y_features.cuda() # Use FID class to compute FID score from image features, pre-extracted from some feature extractor network fid: torch.Tensor = piq.FID()(x_features, y_features) print(f"FID: {fid:0.4f}") # If image features are not available, extract them using compute_feats of FID class. # Please note that compute_feats consumes a data loader of predefined format. # Use GS class to compute Geometry Score from image features, pre-extracted from some feature extractor network. # Computation is heavily CPU dependent, adjust num_workers parameter according to your system configuration. gs: torch.Tensor = piq.GS(sample_size=64, num_iters=100, i_max=100, num_workers=4)(x_features, y_features) print(f"GS: {gs:0.4f}") # Use inception_score function to compute IS from image features, pre-extracted from some feature extractor network. # Note, that we follow recomendations from paper "A Note on the Inception Score" isc_mean, _ = piq.inception_score(x_features, num_splits=10) # To compute difference between IS for 2 sets of image features, use IS class. isc: torch.Tensor = piq.IS(distance='l1')(x_features, y_features) print(f"IS: {isc_mean:0.4f}, difference: {isc:0.4f}") # Use KID class to compute KID score from image features, pre-extracted from some feature extractor network: kid: torch.Tensor = piq.KID()(x_features, y_features) print(f"KID: {kid:0.4f}") # Use MSID class to compute MSID score from image features, pre-extracted from some feature extractor network: msid: torch.Tensor = piq.MSID()(x_features, y_features) print(f"MSID: {msid:0.4f}")
def test_inception_score_on_cifar10_train_equals_to_paper_value() -> None: cifar10 = torchvision.datasets.CIFAR10( root="downloads/", download=True, train=True, transform=torchvision.transforms.Compose([ torchvision.transforms.ToTensor(), torchvision.transforms.Normalize([0.5, 0.5, 0.5], [0.5, 0.5, 0.5]) ])) loader = torch.utils.data.DataLoader(cifar10, batch_size=100, num_workers=6) model = torchvision.models.inception_v3(pretrained=True, transform_input=False).cuda() model.eval() y_features = [] with torch.no_grad(): upsample = torch.nn.Upsample(size=(299, 299), mode='bilinear') for i, batch in enumerate(loader): images, labels = batch output = model(upsample(images).cuda()) y_features.append(output) # Take only 10000 images, to make everything faster if i == 100: break y_features = torch.cat(y_features, dim=0) mean, variance = inception_score(y_features) # # Values from paper https://arxiv.org/pdf/1801.01973.pdf # # CIFAR10 train: 9.737±0.148 mean_diff, var_diff = abs(mean - 9.737), abs(variance - 0.148) assert (mean_diff <= 1.0) and (var_diff <= 0.5), \ f'Mean and var not close to paper. Mean diff: {mean_diff}, var diff: {var_diff}'
def test_inception_score_equal_to_scipy_version(features_y_normal) -> None: score, var = inception_score(features_y_normal) score_scipy, var_scipy = torch.tensor(logits_to_score_scipy(features_y_normal)) mean_diff = abs(score - score_scipy) var_diff = abs(var - var_scipy) assert (mean_diff <= 1e-4) and (var_diff <= 0.5), \ f'PyTorch and Scipy implementation should match, got mean diff {mean_diff}'\ f'and var diff {var_diff}'
def test_inception_score_returns_two_values(features_y_normal) -> None: result = inception_score(features_y_normal) assert len(result) == 2, \ f'Expected to get score and variance, got {result}'
def forward(self, prediction_features: torch.Tensor, target_features: torch.Tensor): mean, std = piq.inception_score(features=prediction_features, num_splits=self.num_splits) return mean