如何实现Inception Score(IS)评估GAN

生成对抗网络,简称GANs,是一种深度学习神经网络架构,用于训练生成器模型以生成合成图像。

生成模型的一个问题是,没有客观的方法来评估生成图像的质量。

因此,通常的做法是在模型训练过程中定期生成并保存图像,并使用主观的人工评估来评估生成图像的质量,并选择最终的生成器模型。

人们已经进行了许多尝试来建立生成图像质量的客观度量。一个早期且被广泛采用的生成图像客观评估方法的例子是Inception Score,简称IS。

在本教程中,您将了解用于评估生成图像质量的Inception Score。

完成本教程后,您将了解:

  • 如何计算Inception Score以及其衡量背后的直觉。
  • 如何使用NumPy和Keras深度学习库在Python中实现Inception Score。
  • 如何计算CIFAR-10数据集中小图像的Inception Score。

通过我的新书《Python生成对抗网络》**启动您的项目**,其中包括**分步教程**和所有示例的**Python源代码**文件。

让我们开始吧。

  • **2019年10月更新**:修正了均匀分布示例中Inception Score的一个小错误。
How to Implement the Inception Score (IS) From Scratch for Evaluating Generated Images

如何从头开始实现Inception Score (IS) 以评估生成图像
图片由 alfredo affatato 拍摄,保留部分权利。

教程概述

本教程分为五个部分;它们是:

  1. 什么是Inception Score?
  2. 如何计算Inception Score
  3. 如何使用NumPy实现Inception Score
  4. 如何使用Keras实现Inception Score
  5. Inception Score的问题

什么是Inception Score?

Inception Score,简称IS,是一个用于评估生成图像(特别是生成对抗网络模型输出的合成图像)质量的客观指标。

Inception Score由Tim Salimans等人在其2016年论文《改进GAN训练技术》中提出。

在论文中,作者使用众包平台(Amazon Mechanical Turk)评估了大量GAN生成的图像。他们开发了Inception Score,试图消除对图像的主观人工评估。

作者发现他们的分数与主观评估高度相关。

作为人类标注者的替代方案,我们提出了一种自动评估样本的方法,我们发现该方法与人类评估高度相关……

——《改进GAN训练技术》,2016。

Inception Score涉及使用预训练的深度学习神经网络模型对生成图像进行图像分类。具体来说,是使用Inception v3模型,该模型由Christian Szegedy等人在其2015年论文《重新思考计算机视觉的Inception架构》中描述。对Inception模型的依赖使得Inception Score得名。

使用该模型对大量生成的图像进行分类。具体来说,会预测图像属于每个类别的概率。然后将这些预测汇总为Inception Score。

该分数旨在捕获一组生成图像的两个属性:

  • **图像质量**。图像看起来像一个特定的物体吗?
  • **图像多样性**。是否生成了各种各样的物体?

Inception Score的最低值为1.0,最高值为分类模型支持的类别数量;在本例中,Inception v3模型支持ILSVRC 2012数据集的1000个类别,因此,在该数据集上的最高Inception Score为1000。

CIFAR-10数据集是一个包含50,000张图像的集合,分为10个对象类别。引入Inception的原始论文计算了真实CIFAR-10训练数据集上的分数,取得了11.24 +/- 0.12的结果。

使用论文中引入的GAN模型,在为该数据集生成合成图像时,他们获得了8.09 +/- 0.07的Inception Score。

想从零开始开发GAN吗?

立即参加我为期7天的免费电子邮件速成课程(附示例代码)。

点击注册,同时获得该课程的免费PDF电子书版本。

如何计算Inception Score

Inception Score的计算方法是,首先使用预训练的Inception v3模型预测每张生成图像的类别概率。

这些是条件概率,例如,类标签以生成图像为条件。如果图像被强烈分类为某个类别而非所有其他类别,则表明图像质量高。因此,集合中所有生成图像的条件概率应具有低熵

包含有意义对象的图像应具有低熵的条件标签分布 p(y|x)。

——《改进GAN训练技术》,2016。

熵的计算方法是每个观测概率乘以概率的对数,然后取负数。这里的直觉是,大概率的信息量小于小概率的信息量。

  • 熵 = -sum(p_i * log(p_i))

条件概率捕捉了我们对图像质量的兴趣。

为了捕捉我们对各种图像的兴趣,我们使用边际概率。这是所有生成图像的概率分布。因此,我们希望边际概率分布的积分具有高熵。

此外,我们期望模型能生成各种图像,因此边际积分 p(y|x = G(z))dz 应该具有高熵。

——《改进GAN训练技术》,2016。

这些元素通过计算条件概率分布和边际概率分布之间的Kullback-Leibler散度(或KL散度,相对熵)进行组合。

计算两个分布之间的散度使用“||”运算符,因此我们可以说我们对条件分布C和边际分布M之间的KL散度感兴趣,即

  • KL (C || M)

具体来说,我们对所有生成图像的KL散度平均值感兴趣。

结合这两个要求,我们提出的度量是:exp(Ex KL(p(y|x)||p(y)))。

——《改进GAN训练技术》,2016。

我们不需要翻译Inception Score的计算方法。幸运的是,论文作者还在GitHub上提供了源代码,其中包含Inception Score的实现

该分数的计算假设有大量的图像用于一系列对象,例如50,000张。

图像被分成10组,例如每组5000张图像,然后计算每组图像的Inception Score,最后报告分数的平均值和标准差。

在一组图像上计算Inception Score,首先是使用Inception v3模型计算每张图像的条件概率 (p(y|x))。然后,边际概率被计算为该组图像条件概率的平均值 (p(y))。

然后,对每张图像计算KL散度,即条件概率乘以条件概率的对数减去边际概率的对数。

  • KL散度 = p(y|x) * (log(p(y|x)) – log(p(y)))

然后将KL散度对所有图像求和,并对所有类别取平均值,再计算结果的指数,得到最终分数。

这定义了官方的Inception Score实现,大多数使用该分数的论文中报告的都是这种实现,尽管也存在计算分数的方法变体。

如何使用NumPy实现Inception Score

用Python和NumPy数组实现Inception Score的计算非常简单。

首先,我们定义一个函数,它接受条件概率集合并计算Inception Score。

下面列出的 `calculate_inception_score()` 函数实现了该过程。

一个小的改动是在计算对数概率时引入一个epsilon(一个接近零的微小数字),以避免在尝试计算零概率的对数时出现爆炸。这在实践中(例如,对于真实生成的图像)可能不需要,但在这里很有用,并且在使用对数概率时是一种良好的实践。

然后我们可以测试这个函数,计算一些虚构的条件概率的Inception Score。

我们可以想象这样一个情况:有三个图像类别,对于三张图像,每个类别都有一个完美的自信预测。

我们预计在这种情况下Inception Score将为3.0(或非常接近)。这是因为每个图像类别(三个类别各一张图像)的图像数量相同,并且每个条件概率都具有最大的置信度。

下面列出了计算这些概率的Inception Score的完整示例。

运行示例会得到预期的3.0分数(或非常接近的数字)。

我们也可以尝试最坏的情况。

在这种情况下,每个类别(三个类别各一个)的图像数量仍然相同,但物体未知,因此每个类别的预测概率分布是均匀的。

在这种情况下,我们期望Inception Score是尽可能差的,即条件分布和边际分布之间没有差异,Inception Score为1.0。

将这些结合起来,完整的示例列在下面。

运行该示例会报告预期的Inception Score 1.0。

您可能希望尝试计算Inception Score并测试其他病理情况。

如何使用Keras实现Inception Score

现在我们知道了如何计算Inception Score并在Python中实现它,我们可以在Keras中开发一个实现。

这包括使用真实的Inception v3模型对图像进行分类,并对图像集合的多个分割进行分数计算的平均。

首先,我们可以直接在Keras中加载Inception v3模型。

该模型要求图像是彩色的,并且形状为299×299像素。

此外,在对像素值进行分类之前,必须像训练数据图像一样对其进行缩放。

这可以通过将像素值从整数转换为浮点值,然后对图像调用 `preprocess_input()` 函数来实现。

然后可以预测图像的1000个图像类别的条件概率。

然后可以直接像上一节那样,在NumPy概率数组上计算Inception Score。

在此之前,我们必须将条件概率分成几组,由 `n_split` 参数控制,并设置为原始论文中使用的默认值10。

然后我们可以枚举 `n_part` 图像或预测块中的条件概率,并计算Inception Score。

在计算完每个条件概率分割的分数后,我们可以计算并返回平均值和标准差的Inception Score。

将所有这些联系起来,下面的 `calculate_inception_score()` 函数接受一个具有预期大小和像素值在 [0,255] 范围内的图像数组,并使用 Keras 中的 Inception v3 模型计算平均值和标准差的 Inception Score。

我们可以用50张所有像素值为1.0的人造图像来测试这个函数。

这将计算每组五张图像的分数,低质量表明将报告平均Inception Score为1.0。

完整的示例如下所示。

运行示例首先定义了50张假图像,然后计算每批次的Inception Score,并报告了预期的Inception Score 1.0,标准差为0.0。

**注意**:首次使用InceptionV3模型时,Keras将下载模型权重并将其保存到您工作站的 `~/.keras/models/` 目录中。权重约为100兆字节,下载时间可能取决于您的互联网连接速度。

我们可以测试Inception Score在一些真实图像上的计算。

Keras API提供了对CIFAR-10数据集的访问。

这些是32×32像素的小尺寸彩色照片。首先,我们可以将图像分组,然后将图像上采样到预期的299×299尺寸,预处理像素值,预测类别概率,然后计算Inception Score。

如果您打算在自己生成的图像上计算Inception Score,这将是一个有用的示例,因为您可能需要将图像缩放到Inception v3模型的预期尺寸,或者更改模型以为您执行上采样。

首先,可以加载图像并打乱,以确保每个分割都包含多样化的类别。

接下来,我们需要一种缩放图像的方法。

我们将使用scikit-image库将NumPy像素值数组调整到所需的尺寸。下面的 `scale_images()` 函数实现了这一点。

请注意,如果尚未安装scikit-image库,您可能需要安装它。可以通过以下方式实现:

然后我们可以枚举分割次数,选择图像的一个子集,缩放它们,预处理它们,并使用模型预测条件类别概率。

Inception Score的其余计算方式相同。

将所有这些联系起来,下面列出了在真实CIFAR-10训练数据集上计算Inception Score的完整示例。

根据原始Inception Score论文中报告的类似计算,我们预计该数据集的报告分数约为11。有趣的是,截至撰写本文时,使用渐进式增长GAN在CIFAR-10上获得的最佳Inception Score约为8.8。

运行示例加载数据集,准备模型,并计算CIFAR-10训练数据集上的Inception Score。

我们可以看到,得分是11.3,接近预期的11.24。

**注意**:首次使用CIFAR-10数据集时,Keras将下载压缩格式的图像并将其存储在 `~/.keras/datasets/` 目录中。下载大小约为161兆字节,可能需要几分钟,具体取决于您的互联网连接速度。

Inception Score的问题

Inception Score是有效的,但并不完美。

通常,Inception Score适用于由用于计算条件类别概率的模型所知的对象生成的图像。

在这种情况下,由于使用了Inception v3模型,这意味着它最适合用于ILSVRC 2012数据集中的1000种对象类型。这是一个庞大的类别数量,但并非所有我们可能感兴趣的对象都包含在内。

您可以在此处查看所有类别的完整列表

它还要求图像是方形的,并且大小相对较小,约为300×300像素,包括将生成的图像缩放到该尺寸所需的任何缩放。

一个好的分数还需要在模型支持的可能对象中,生成的图像具有良好的分布,并且每个类别的示例数量接近均匀。这对于许多无法控制生成对象类型的GAN模型来说很难实现。

Shane Barratt和Rishi Sharma在其2018年论文《关于Inception Score的注释》中更深入地研究了Inception Score,并列出了许多技术问题和边缘情况。如果您想深入了解,这是一份很好的参考资料。

进一步阅读

如果您想深入了解,本节提供了更多关于该主题的资源。

论文

项目

API

文章

总结

在本教程中,您了解了用于评估生成图像质量的Inception Score。

具体来说,你学到了:

  • 如何计算Inception Score以及其衡量背后的直觉。
  • 如何使用NumPy和Keras深度学习库在Python中实现Inception Score。
  • 如何计算CIFAR-10数据集中小图像的Inception Score。

你有什么问题吗?
在下面的评论中提出你的问题,我会尽力回答。

立即开发生成对抗网络!

Generative Adversarial Networks with Python

在几分钟内开发您的GAN模型

...只需几行python代码

在我的新电子书中探索如何实现
使用 Python 构建生成对抗网络

它提供了关于以下内容的自学教程端到端项目
DCGAN条件GAN图像翻译Pix2PixCycleGAN
以及更多...

最终将GAN模型引入您的视觉项目

跳过学术理论。只看结果。

查看内容

对《如何实现Inception Score (IS) 来评估GANs》的44条回复

  1. vandana kushwaha 2019年8月29日 晚上8:55 #

    我们如何计算MNIST数据集的Inception Score?

    • Jason Brownlee 2019年8月30日 上午6:18 #

      也许将MNIST从黑白像素数据转换为3个颜色通道?

  2. Ralf Wittman 2019年11月21日 上午4:18 #

    感谢您的精彩文章!

    我想将IS用作训练Keras模型(自编码器)的自定义损失函数。

    您的实现使用了numpy,但Keras期望Tensorflow张量。

    有什么简单的方法可以让它与Keras一起工作吗?

    • Jason Brownlee 2019年11月21日 上午6:10 #

      本教程展示了如何使用Keras计算IS。或许可以重新阅读一下?

  3. Uluc Sahin 2019年12月19日 晚上10:30 #

    首先,感谢您的精彩文章。

    我有个问题
    我想使用Inception Score来评估我的GAN生成的人脸图像。这种方法是否适用于评估生成的人脸图像?因为我认为Inception V3模型中没有这种类型数据的类别。

    或者,评估这种网络的好方法是什么?

  4. Nabil Salman 2020年2月19日 上午11:18 #

    首先,感谢您的文章。
    其次
    我有一个问题
    如何在pix2pix项目中获取两个图像(生成的和预期的)在地图上的分数?

    • Jason Brownlee 2020年2月19日 下午1:33 #

      我认为IS不适合该项目,因为图像不像标准Imagenet图像。

      • Nabil Salman 2020年2月22日 下午1:59 #

        你推荐我用什么?

  5. Wolf Rage 2020年2月21日 晚上6:34 #

    Inception v3模型不是针对Imagenet数据集训练的,它有1000个输出神经元吗?
    如果真是这样,我们如何将其用于需要10个输出神经元的CIFAR-10数据集?还是说它本来就应该这样做?

    • Jason Brownlee 2020年2月22日 上午6:21 #

      它可以识别图像的类别,它是类别的一个超集。关键是它是一致的。

      如果你只想限制在10个类别,或许可以使用在 cifar10 上预训练的模型?

      • Rishik Mourya 2020年2月22日 晚上7:01 #

        谢谢您的澄清,我明白了!

  6. Amr Bahaa 2020年2月25日 下午12:51 #

    首先,感谢您的文章。
    其次
    我有一个问题
    IS FID 是否适合评估 pix2pix 地图项目中生成的图像和预期图像?
    如果不是,对于这个项目来说,最好的评估方法是什么?因为我们正面临评估这些GAN生成的图像和预期图像的问题。
    如果您能帮助我解决这个复杂的问题,我将不胜感激,因为我已经搜索了数周,但没有找到好的解决方案。
    提前感谢

    • Jason Brownlee 2020年2月25日 下午1:48 #

      好问题。FID 可能对地图数据进行探索会很有趣。

      问题仍然在于需要一个善于从地图中提取特征的模型,而像 VGG 和 Inception 这样的模型可能不太适合。

      话虽如此,您可以进行实验以查看其有效性/无效性——例如FID论文中的那些实验。

      • Amr Bahaa 2020年2月26日 上午11:00 #

        真的非常感谢您
        我们已经在我们的数据集上尝试过,但效果不够好。
        哪种模型最适合从地图中提取特征?

        • Jason Brownlee 2020年2月26日 上午11:41 #

          我不知道,你必须通过受控实验来发现最好的算法。

  7. Amr Bahaa 2020年2月26日 上午11:33 #

    我读过关于在Google地图上训练的FCN模型。
    您认为这会比Inception模型更好吗?

    • Jason Brownlee 2020年2月26日 上午11:41 #

      也许可以试试。

      • Amr Bahaa 2020年2月26日 上午11:55 #

        非常感谢您,先生,您真的帮了我很多。
        我也想感谢您这篇精彩的文章。

  8. Alan 2020年2月27日 上午10:30 #

    我有一个神经网络,可以对MNIST数据集的图像进行分类。如果我提取测试集中所有样本的中间层输出(在最后一层应用softmax之后),并将此数组传递给您的numpy Inception Score实现,它会给出正确的分数吗?

    谢谢你

    • Jason Brownlee 2020年2月27日 下午1:34 #

      Inception不适用于MNIST图像。它旨在用于对象照片,例如来自Imagenet的照片。

      要获得更好的度量,请参阅
      https://machinelearning.org.cn/how-to-evaluate-generative-adversarial-networks/

      • Alan 2020年2月27日 下午2:58 #

        好的,那么改变Inception Score计算中的分割次数有多重要?为什么不总是使用n=1呢?

        • Jason Brownlee 2020年2月28日 上午5:56 #

          也许可以进行敏感性分析,看看分割如何影响您的特定数据集上分数的方差。

          • Alan 2020年2月28日 下午1:42 #

            谢谢您的回复,Jason。将分割次数增加到大于1,我的Inception Scores急剧下降。然而,使用分类器,这些图像的准确率非常高,约为98%。

            我应该如何解释这一点?

          • Jason Brownlee 2020年2月29日 上午7:06 #

            您需要在拥有的图像数量和分割数量之间找到一个平衡点,以使每个组都具有“代表性”。

  9. Rachel 2020年4月24日 晚上8:29 #

    嗨!感谢您非常清晰的解释!我尝试自己实现这个分数,您的博客非常有帮助。
    只是一个小提醒。在博客的开头您写道

    “KL散度 = p(y|x) * (log(p(y|x)) – log(p(y)))
    然后将KL散度**对所有图像求和并对所有类别取平均值**,并计算结果的指数,得到最终分数。”

    但在您实际的IS实现中,您是对类别求和并对图像取平均值,所以我相信最好添加这个小修正。

    再次感谢这篇伟大的文章

  10. Aditya Bodkhe 2020年6月29日 晚上6:34 #

    嗨,我有个疑问,如果我从头开始训练一个Inception网络,用于像Fashion MNIST这样更简单的黑白单通道图像数据集,然后用它作为模型来计算生成图像的Inception Score。将这个自定义开发的网络分数视为可靠基准是个好主意吗?

    • Jason Brownlee 2020年6月30日 上午6:16 #

      也许吧。如果它相对于其他模型表现良好。

  11. Jack 2020年10月24日 上午4:19 #

    嗨,一个快速的问题

    在第一部分,指出:“Inception Score的最高值为分类模型支持的类别数量”。

    然而,也指出:“CIFAR-10数据集是50,000张图像的集合,分为10个对象类别。引入Inception的原始论文计算了真实CIFAR-10训练数据集上的分数,获得了11.24 +/- 0.12的结果。”

    我的问题是,如果CIFAR-10数据集只分为10个对象类别,原始论文是如何计算出11.24的Inception Score,这比10高?

    感谢这篇精彩的文章。

    • Jason Brownlee 2020年10月24日 上午7:12 #

      请注意,我们在上面的教程中也获得了11分。

      也许可以重新阅读该部分的代码,看看我们正在做什么。

    • Michael 2022年11月10日 下午3:40 #

      Inception v3分类模型支持的类别数量是1000个。因此,即使CIFAR-10只有10个类别,该模型仍然会输出其训练预测的所有1000个可能类别的预测。例如,两张不同的CIFAR-10狗图像可能导致不同的类别预测(不同的品种)。

      简而言之,从Inception模型的角度来看,CIFAR-10拥有的类别不止10个。

  12. Prachi 2022年9月11日 上午11:40 #

    嗨Jason,感谢您的信息丰富的文章。
    问:当我们打乱数据时,Inception分数会改变吗?打乱数据只是改变顺序,数据大小保持不变。
    谢谢。

  13. Prachi 2022年9月11日 上午11:44 #

    而且,Inception分数对每个人来说都一样吗?我得到了11.10。

  14. Mike 2022年11月13日 上午3:29 #

    Inception分数的最低值为1.0,最高值为分类模型支持的类别数量;在这种情况下,Inception v3模型支持ILSVRC 2012数据集的1,000个类别,因此该数据集上的最高Inception分数为1,000。

    CIFAR-10数据集包含50,000张图片,分为10个对象类别。引入Inception的原始论文计算了真实CIFAR-10训练数据集上的分数,结果为11.24 +/- 0.12

    我想知道这个说法是否正确?如果CIFAR-10包含10个类别,并且可能的最大分数是分类模型支持的#类别数,那么IS怎么会是11.24呢??

    我错过了什么??

  15. Kirsten Crane 2022年11月25日 下午10:56 #

    嗨 James,

    关于内存、所需的GPU数量等方面的最低要求有什么想法吗?

    出现如下错误

    2022-11-25 11:07:06.502459: W tensorflow/core/framework/cpu_allocator_impl.cc:80] 分配5364060000字节超出可用系统内存的10%。
    2022-11-25 11:07:09.204554: I tensorflow/compiler/mlir/mlir_graph_optimization_pass.cc:185] 没有启用任何MLIR优化通道(已注册2个)
    2022-11-25 11:07:10.278466: W tensorflow/core/framework/cpu_allocator_impl.cc:80] 分配90935296字节超出可用系统内存的10%。
    2022-11-25 11:07:10.542839: W tensorflow/core/framework/cpu_allocator_impl.cc:80] 分配88510464字节超出可用系统内存的10%。
    2022-11-25 11:07:10.732282: W tensorflow/core/framework/cpu_allocator_impl.cc:80] 分配177020928字节超出可用系统内存的10%。
    2022-11-25 11:07:11.098629: W tensorflow/core/framework/cpu_allocator_impl.cc:80] 分配123887616字节超出可用系统内存的10%。

    谢谢

  16. Israa J. Saeed 2023年2月22日 下午11:48 #

    tensorflow/core/common_runtime/gpu/gpu_bfc_allocator.cc:42] 因为设置了TF_FORCE_GPU_ALLOW_GROWTH环境变量,所以覆盖了原始值设置。原始配置值为0。
    这段代码到达这一点后就不工作了。为什么?

  17. Prakhar Gupta 2024年1月19日 上午6:22 #

    嗨,感谢这篇精彩的文章!我对IS有个疑问——

    “Inception分数的最低值为1.0,最高值为分类模型支持的类别数量;在这种情况下,Inception v3模型支持ILSVRC 2012数据集的1,000个类别,因此该数据集上的最高Inception分数为1,000。

    CIFAR-10数据集包含50,000张图片,分为10个对象类别。引入Inception的原始论文计算了真实CIFAR-10训练数据集上的分数,结果为11.24 +/- 0.12。”

    这里提到最高IS = 类别数量。如果是这样,那么当CIFAR-10只有10个类别时,IS值怎么会是11.24,大于10呢?关于“最高IS = 类别数量”的说法是特殊情况吗?

发表回复

Machine Learning Mastery 是 Guiding Tech Media 的一部分,Guiding Tech Media 是一家领先的数字媒体出版商,专注于帮助人们了解技术。访问我们的公司网站以了解更多关于我们的使命和团队的信息。