|
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') |