a b/inceptionscore.py
1
# calculate inception score for cifar-10 in Keras
2
from math import floor
3
from numpy import ones
4
from numpy import expand_dims
5
from numpy import log
6
from numpy import mean
7
from numpy import std
8
from numpy import exp
9
from numpy.random import shuffle
10
from keras.applications.inception_v3 import InceptionV3
11
from keras.applications.inception_v3 import preprocess_input
12
from keras.datasets import cifar10
13
from skimage.transform import resize
14
from numpy import asarray
15
from glob import glob
16
from natsort import natsorted
17
import cv2
18
import numpy as np
19
from tqdm import tqdm
20
import tensorflow as tf
21
import os
22
23
os.environ['TF_XLA_FLAGS'] = '--tf_xla_enable_xla_devices'
24
os.environ["CUDA_DEVICE_ORDER"]= "PCI_BUS_ID"
25
os.environ["CUDA_VISIBLE_DEVICES"]= '0'
26
27
model = InceptionV3(weights='tmp/imagenet/inception-2015-12-05.tgz')
28
29
# scale an array of images to a new size
30
def scale_images(images, new_shape):
31
    images_list = list()
32
    for image in images:
33
        # resize with nearest neighbor interpolation
34
        new_image = resize(image, new_shape, 0)
35
        # store
36
        images_list.append(new_image)
37
    return asarray(images_list)
38
39
# assumes images have any shape and pixels in [0,255]
40
def calculate_inception_score(images, n_split=10, eps=1E-16):
41
    # load inception v3 model
42
    global model
43
    # enumerate splits of images/predictions
44
    scores = list()
45
    n_part = floor(images.shape[0] / n_split)
46
    for idx, i in enumerate(range(n_split), start=0):
47
        # retrieve images
48
        ix_start, ix_end = i * n_part, (i+1) * n_part
49
        subset = images[ix_start:ix_end]
50
        # convert from uint8 to float32
51
        subset = subset.astype('float32')
52
        # scale images to the required size
53
        subset = scale_images(subset, (299,299,3))
54
        # pre-process images, scale to [-1,1]
55
        subset = preprocess_input(subset)
56
        # predict p(y|x)
57
        batch = tf.data.Dataset.from_tensor_slices((subset,)).batch(256)
58
        p_yx  = []
59
        for subset in tqdm(batch):
60
            subset = subset[0]
61
            p_y = model.predict(subset)
62
            p_yx.extend(p_y)
63
        p_yx = np.array(p_yx)
64
        print(p_yx.shape)
65
        # calculate p(y)
66
        p_y = expand_dims(p_yx.mean(axis=0), 0)
67
        # calculate KL divergence using log probabilities
68
        kl_d = p_yx * (log(p_yx + eps) - log(p_y + eps))
69
        # sum over classes
70
        sum_kl_d = kl_d.sum(axis=1)
71
        # average over images
72
        avg_kl_d = mean(sum_kl_d)
73
        # undo the log
74
        is_score = exp(avg_kl_d)
75
        # store
76
        scores.append(is_score)
77
        print('Inception score of class {}: {}'.format(idx, is_score))
78
        with open('experiments/thought_inceptionscore.txt', 'a') as file:
79
            file.write('Inception score of class {}: {}\n'.format(idx, is_score))
80
    # average across images
81
    is_avg, is_std = mean(scores), std(scores)
82
    return is_avg, is_std
83
84
# # load cifar10 images
85
# (images, _), (_, _) = cifar10.load_data()
86
# # shuffle images
87
# shuffle(images)
88
# print('loaded', images.shape)
89
# calculate inception score
90
for path in natsorted(glob('experiments/inception/*')):
91
    images = []
92
    for im_path in tqdm(natsorted(glob(path+'/*'))):
93
        images.append(cv2.cvtColor(cv2.imread(im_path), cv2.COLOR_BGR2RGB))
94
    images = np.array(images)
95
    is_mean, is_std = calculate_inception_score(images)
96
97
    print('Inception score for epoch {}: ({}, {})'.format(os.path.split(path)[-1], is_mean, is_std))
98
99
    with open('experiments/thought_inceptionscore.txt', 'a') as file:
100
        file.write('-'*30+'\n')
101
        file.write('Inception score for epoch {}: ({}, {})\n'.format(os.path.split(path)[-1], is_mean, is_std))
102
        file.write('-'*30+'\n\n')