| import os |
| from argparse import ArgumentParser, ArgumentDefaultsHelpFormatter |
|
|
| import numpy as np |
| import torch |
| import torch.nn as nn |
| import torch.nn.functional as F |
| import torch.utils.data |
| import torchvision.transforms as transforms |
| from torchvision.models.inception import inception_v3 |
| from scipy.stats import entropy |
| from torch.autograd import Variable |
| from eval_utils.dataset import Dataset |
| from eval_utils.inceptionV3 import InceptionV3 |
|
|
| parser = ArgumentParser(formatter_class=ArgumentDefaultsHelpFormatter) |
| parser.add_argument('--batch-size', type=int, default=64, |
| help='Batch size to use') |
| parser.add_argument('--dims', type=int, default=2048, |
| choices=list(InceptionV3.BLOCK_INDEX_BY_DIM), |
| help=('Dimensionality of Inception features to use. ' |
| 'By default, uses pool3 features')) |
| parser.add_argument('-c', '--gpu', default='', type=str, |
| help='GPU to use (leave blank for CPU only)') |
| parser.add_argument('--path1', type=str, help='path to images') |
|
|
|
|
| def inception_score(imgs, cuda=True, batch_size=32, resize=False, splits=1): |
| """Computes the inception score of the generated images imgs |
| imgs -- Torch dataset of (3xHxW) numpy images normalized in the range [-1, 1] |
| cuda -- whether or not to run on GPU |
| batch_size -- batch size for feeding into Inception v3 |
| splits -- number of splits |
| """ |
| N = len(imgs) |
|
|
| assert batch_size > 0 |
| if batch_size > N: |
| batch_size = N |
|
|
| |
| if cuda: |
| dtype = torch.cuda.FloatTensor |
| else: |
| if torch.cuda.is_available(): |
| print("WARNING: You have a CUDA device, so you should probably set cuda=True") |
| dtype = torch.FloatTensor |
|
|
| |
| dataloader = torch.utils.data.DataLoader(imgs, batch_size=batch_size) |
|
|
| |
| inception_model = inception_v3(pretrained=True, transform_input=False).type(dtype) |
| inception_model.eval() |
| up = nn.Upsample(size=(299, 299), mode='bilinear').type(dtype) |
|
|
| def get_pred(x): |
| if resize: |
| x = up(x) |
| x = inception_model(x) |
| return F.softmax(x).data.cpu().numpy() |
|
|
| |
| preds = np.zeros((N, 1000)) |
|
|
| for i, batch in enumerate(dataloader, 0): |
| batch = batch.type(dtype) |
| batchv = Variable(batch) |
| batch_size_i = batch.size()[0] |
|
|
| preds[i * batch_size:i * batch_size + batch_size_i] = get_pred(batchv) |
|
|
| |
| split_scores = [] |
|
|
| for k in range(splits): |
| part = preds[k * (N // splits): (k + 1) * (N // splits), :] |
| py = np.mean(part, axis=0) |
| scores = [] |
| for i in range(part.shape[0]): |
| pyx = part[i, :] |
| scores.append(entropy(pyx, py)) |
| split_scores.append(np.exp(np.mean(scores))) |
|
|
| return np.mean(split_scores), np.std(split_scores) |
|
|
|
|
| if __name__ == '__main__': |
| args = parser.parse_args() |
| os.environ['CUDA_VISIBLE_DEVICES'] = args.gpu |
|
|
| dataset = Dataset(args.path1, transforms.Compose([ |
| transforms.Resize((299, 299)), |
| transforms.ToTensor(), |
| ])) |
| mean, std = inception_score(dataset, cuda=True, batch_size=32, resize=False, splits=1) |
| print('IS mean: ', mean) |
| print('IS std: ', std) |
|
|