Fréchet Inception Distance (FID)
无业游民
等
之前写了一篇文章介绍 Inception Score 的原理和局限性
Inception Score 的问题
首先回顾一下 Inception Score 的两个假设:
越真实的图片,输入预训练的 Inception V3 ,分类的结果越明确。即在1000维的输出向量中,某一维很大,其余维很小。也就是说,输出的概率分布函数图越尖锐。
生成的图片多样性越强,那么类别的边缘分布就越平均,边缘分布的概率函数图像就越平整。
Inception Score 通过计算 1 和 2 中两个概率分布的散度,来衡量生成模型的表现。
我们乍一看这两条假设,不难发现最明显的两个问题:
针对第一个假设,是否越真实的图片,分类网络输出的概率分布函数越尖锐?显然是不见得的,如果某一个物体所属的类别在分类网络中并不存在,那么它的分布函数依然尖锐吗?
针对第二个假设,是否输出图片均匀地覆盖每个类别,就意味着生成模型不存在 mode collapse?Inception net 输出 1000 类,假设生成模型在每类上都生成了 50 个图片,那么生成的图片的类别边缘分布是严格均匀分布的,按照 Inception Score 的假设,这种模型不存在 mode collapse,但是,如果各类中的50个图片,都是一模一样的,仍然是 mode collapse。Inception Score 无法检测这种情况。
除了上面最直观的两个硬伤,本文开头提到的文章中对 Inception Score 缺点做了详细分析。其中涉及到:使用 IS 时,分类模型应该和生成模型在同一个训练集上训练,否则分类模型计算的边缘分布将不准确,而分类模型对单个图片的预测,也将不能真实反映图片的清晰程度。
出现这一问题的本质原因是:计算 IS 时只考虑了生成样本,没有考虑真实数据,即 IS 无法反映真实数据和样本之间的距离,IS 判断数据真实性的依据,源于 Inception V3 的训练集: ImageNet,在 Inception V3 的“世界观”下,凡是不像 ImageNet 的数据,都是不真实的,都不能保证输出一个 sharp 的 predition distribution。
Fréchet Inception Distance
而 Fréchet Inception Distance (FID) 则是计算了真实图片和假图片在 feature 层面的距离,因此显得更有道理一点。FID 的公式如下:
众所周知,预训练好的神经网络顶层可以提取图片的高级信息,一定程度能反映图片的本质。因此,FID 的提出者通过预训练的 Inception V3 来提取全连接层之前的 2048 维向量,作为图片的特征。公式 (1) 中:
:真实图片的特征的均值
:生成的图片的特征的均值
: 真实图片的特征的协方差矩阵
: 生成图片的特征的协方差矩阵
FID 用以衡量两个多元正态分布的距离,具体的来源见论文:
The Fréchet distance between multivariate normal distributions
我数学能力有限,实在读不懂,好在最后的距离公式还是比较简单的,直接套进去就能用了。
FID 只把 Inception V3 作为特征提取器,并不依赖它判断图片的具体类别,hang因此不必担心 Inception V3 的训练数据和生成模型的训练数据不同。同时,由于直接衡量生成数据和真实数据的分布之间的距离,也不必担心每个类别内部只产生一模一样的图片这种形式的 mode collapse。完美避开了很多 Inception Score 的缺陷。
总结
综上所述,对比 IS,FID 有如下优点:
生成模型的训练集和 Inception V3 的训练集可以不同。
计算 FID 时同时用到了生成的数据和真实数据,比起 IS 来更灵活。可以理解成,IS 判断真实性与否,是把生成数据和 ImageNet 数据做比较,而 FID 是把生成数据和训练数据做比较,因此更 reasonable。
以优化 FID 为目标,不会产生对抗样本。因为优化的是 lantent space feature,不是最终的输出图片,不会导致最终的生成图片失真。
但是基于我的上篇文章 尹相楠:Inception Score 的原理和局限性,FID 仍然存在一些和 IS 同样的问题:
FID 只是某一层的特征的分布,是否足以衡量真实数据分布与生成数据分布的距离?同时,提出 FID 公式计算的是多元正态分布的距离,显然神经网络提取的特征并不是多元正态分布。
针对同一个生成模型,不同框架下预训练的 Inception V3 算出的 FID 差别是否可以忽略?
FID 无法反映生成模型过拟合的情况,如果某个生成模型只是简单拷贝训练数据,FID 会非常小,认为这是一个完美的生成模型,因此,使用 FID 时同时也要通过别的手段证明生成模型没有过拟合。
代码实现
下面的链接是基于 pytorch 的计算 FID 的代码。
~~注意作者在源码中并没有加载 Inception V3 的权重,因此千万不要直接套用。建议读者自己继承一下 pytorch Inception V3 的类,修改 forward 函数,让它返回全连接层前面的 2048 维向量,这样就可以直接加载 pytorch 官方的Inception V3 的权重了。~~
之前没有仔细看代码贸然提了个 issue,发现作者其实加载了 Inception V3 的权重,在inception.py文件的第 60 行。
编辑于 2019-01-07