一、Inception Score的基礎概念和定義
Inception Score,簡稱IS,是用於評估生成模型質量的一種指標,由Salimans等人在2016年提出。IS是基於對圖像生成模型的激活層進行統計計算得出的結果。其核心思想是通過計算每張圖像在模型內部的複雜程度以及不確定性,從而評判模型的生成能力。
在英文論文中,IS的定義如下:
Let p(y|x) be the class predicted by the inception model when generating the image x. The inception score is then defined to be:
$$exp(\mathbb{E}_{x∼p_g}[KL(p(y|x)∥p(y))])$$
其中 p(y) 是在不同的輸入圖像上經驗統計的類別分布。也就是說,在不同的輸入圖像樣本中,IS計算使用的是真實標籤的分布。
二、Inception Score的優點
相比與其他評價指標來說,Inception Score有以下幾個優點:
1、適用性廣,可以很好地應用於不同類型的圖像生成模型,如GAN、VAE等。
2、不依賴於訓練數據的特定特徵,也就意味着對於不同數據集的生成模型,IS的評估方式可以保持不變。
3、IS的結果可以用來比較不同模型的泛化能力,也就是說在對數據的生成能力評價上能夠更全面的描述模型的生成能力。
三、計算Inception Score的具體步驟
1、首先需要下載預訓練的Inception模型權重,這個可以在TensorFlow源碼中找到。在 TensorFlow 源代碼中可找到已經訓練好的 Inception 模型,運行以下命令來下載這些模型(以下命令需聯網操作):
python download_and_preprocess_imagenet.py
2、準備樣本集,並且生成圖像。對樣本集生成的圖片需要做如下處理,即:
– 將生成器依次運行 $n$ 次,每次得到 $m$ 張圖片。
– 將所有得到的圖片灰度標準化,使得像素點值在 0 到1 之間。
– 對於每張生成圖像 x,通過預訓練的 Inception 模型計算其在嵌套的回歸輸出層上每一個類的概率值(也就是對應分類標籤的概率值)。
3、根據每個 $x$ 的類別分布計算每個 $M$ 個樣本的Inception score。 具體地,對於第 $i$ 個樣本集,其 Inception Score 的計算公式為:
$$exp(\mathbb{E}_{x∼p_g}[KL(p(y|x)∥p(y))])$$
這裡的 $p(y|x)$ 表示樣本 $x$ 屬於第 $y$ 個類別的概率,其中 $p(y|x)$ 是已知概率分布,均值及方差的,於是根據推斷理論,可以使用重新參數化技巧從已知分布中生成 $y_{1,…,m}$ 的 i.i.d 樣本。然後統計每個類別在樣本集中出現的概率,得到概率分布 $p(y)$,最後代入上述公式即可得到IS的值。
四、計算Inception Score的示例代碼
import numpy as np
import tensorflow as tf
from tensorflow.contrib.slim import arg_scope
from tensorflow.contrib.layers import softmax
from scipy.stats import entropy
def inception_score(images, num_splits=1):
'''
Compute the inception score of the generated images
images : numpy array, generated images whose inception scores are being calculated
num_splits : int, the number of splits of images
'''
# Load inception v1 pre-trained model
inception_v1 = tf.keras.applications.InceptionV1(
weights=None, include_top=True, input_shape=images.shape[1:]
)
# Obtain the final prediction layer of inception model
output_layer = inception_v1.get_layer("predictions")
# Define the computational Graph for Obtaining the softmax (class probabilities) Output
num_outputs = output_layer.output_shape[-1]
m = images.shape[0]
with tf.Session() as sess:
preds = output_layer.output.op.inputs[0]
preds = tf.reshape(preds, [-1, num_outputs])
softmax_out = softmax(preds)
# Perform the split computing for enhancing the stability and diversity of the obtained samples
classes = []
for i in range(num_splits):
print('Split', i)
# Compute the split interval
lower_bound = i * np.floor(m / num_splits).astype(int)
upper_bound = (i + 1) * np.floor(m / num_splits).astype(int)
# Obtain the softmax Output for the split
split_softmax_out = sess.run(softmax_out, feed_dict={inception_v1.input: images[lower_bound:upper_bound]})
# Compute the mean of the softmax Output for the split - class probabilities are averaged across the different splits
p_y_given_x_split = np.mean(split_softmax_out, axis=0)
# Compute entropy for split - entropy measures the amount of randomness
KL = np.sum(p_y_given_x_split * (np.log(p_y_given_x_split + 1e-8) - np.log(np.repeat(np.expand_dims(np.mean(p_y_given_x_split, axis=0), 0), p_y_given_x_split.shape[0]) + 1e-8) ), axis=1)
# Add the Inception Score
IS = np.exp(np.mean(KL))
# Record the Predicted Class Probabilities and Entropies for the Split
classes.append(p_y_given_x_split)
print('Split {}. Inception Score: {}'.format(i, IS))
# Compute the average class probabilities across the different splits
classes = np.concatenate(classes, axis=0)
p_y = np.mean(classes, axis=0)
# Compute entropy for all samples
entropy_final = entropy(p_y)
# Compute Inception Score
inception_score_val = np.exp(entropy_final)
return inception_score_val
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/160638.html