gan模型结构讲解(学习GAN模型量化评价)
gan模型结构讲解(学习GAN模型量化评价)在本教程中,你将了解如何通过 FID 评估生成的图像。FID 分数被用于评估由生成性对抗网络生成的图像的质量,较低的分数与较高质量的图像有很高的相关性。要说谁是当下最火的生成模型,GAN 当之无愧!然而,模式坍塌、训练不稳定等问题严重制约着 GAN 家族的发展。为了提图像质量、样本多样性的角度量化评价 GAN 模型的性能,研究者们提出了一系列度量指标,其中 FID 就是近年来备受关注的明星技术,本文将详细介绍如何在 python 环境下实现 Frechet Inception 距离(FID)。Frechet Inception 距离得分(Frechet Inception Distance score,FID)是计算真实图像和生成图像的特征向量之间距离的一种度量。FID 从原始图像的计算机视觉特征的统计方面的相似度来衡量两组图像的相似度,这种视觉特征是使用 Inception v3 图像分
选自machinelearningmastery
作者:Jason Brownlee
机器之心编译
编译:高璇,Geek AI
要说谁是当下最火的生成模型,GAN 当之无愧!然而,模式坍塌、训练不稳定等问题严重制约着 GAN 家族的发展。为了提图像质量、样本多样性的角度量化评价 GAN 模型的性能,研究者们提出了一系列度量指标,其中 FID 就是近年来备受关注的明星技术,本文将详细介绍如何在 python 环境下实现 Frechet Inception 距离(FID)。
Frechet Inception 距离得分(Frechet Inception Distance score,FID)是计算真实图像和生成图像的特征向量之间距离的一种度量。
FID 从原始图像的计算机视觉特征的统计方面的相似度来衡量两组图像的相似度,这种视觉特征是使用 Inception v3 图像分类模型计算的得到的。分数越低代表两组图像越相似,或者说二者的统计量越相似,FID 在最佳情况下的得分为 0.0,表示两组图像相同。
FID 分数被用于评估由生成性对抗网络生成的图像的质量,较低的分数与较高质量的图像有很高的相关性。
在本教程中,你将了解如何通过 FID 评估生成的图像。
图像失真程度的提高与高 FID 分数之间的关系。
如何计算 Frechet Inception 距离?
首先,通过加载经过预训练的 Inception v3 模型来计算 FID 分数。
删除模型原本的输出层,将输出层换为最后一个池化层(即全局空间池化层)的激活函数输出值。此输出层有 2 048 维的激活向量,因此,每个图像被预测为 2 048 个激活特征。该向量被称为图像的编码向量或特征向量。
针对一组来自问题域的真实图像,预测 2 048 维的特征向量,用来提供真实图像表征的参考。然后可以计算合成图像的特征向量。
结果就是真实图像和生成图像各自的 2 048 维特征向量的集合。
然后使用以下公式计算 FID 分数:
该分数被记为 d^2,表示它是一个有平方项的距离。
「mu_1」和「mu_2」指的是真实图像和生成图像的特征均值(例如,2 048 维的元素向量,其中每个元素都是在图像中观察到的平均特征)。
C_1 和 C_2 是真实图像的和生成图像的特征向量的协方差矩阵,通常被称为 sigma。
|| mu_1-mu_2 ||^2 代表两个平均向量差的平方和。Tr 指的是被称为「迹」的线性代数运算(即方阵主对角线上的元素之和)。
sqrt 是方阵的平方根,由两个协方差矩阵之间的乘积给出。
矩阵的平方根通常也被写作 M^(1/2),即矩阵的 1/2 次方。此运算可能会失败,由于该运算是使用数值方法求解的,是否成功取决于矩阵中的值。通常,所得矩阵中的一些元素可能是虚数,它们通常可以被检测出来并删除。
如何用 NumPy 实现 Frechet Inception 距离?
使用 NumPy 数组在 Python 中实现 FID 分数的计算非常简单。
首先,让我们定义一个函数,它将为真实图像和生成图像获得一组激活函数值,并返回 FID 分数。
下面列出的「calculate_fid()」函数实现了该过程。
通过该函数,我们几乎直接实现了 FID 分数的计算。值得注意的是,TensorFlow 中的官方实现计算元素的顺序稍有不同(可能是为了提高效率),并在加入了矩阵平方根附近的额外检查,以处理可能的数值不稳定性。
如果在自己的数据集上计算 FID 时遇到问题,我建议你查看官方教程并扩展下面的实现,以添加这些检查。
def calculate_fid(act1 act2): # calculate mean and covariance statistics mu1 sigma1 = act1.mean(axis=0) cov(act1 rowvar=False) mu2 sigma2 = act2.mean(axis=0) cov(act2 rowvar=False) # calculate sum squared difference between means ssdiff = numpy.sum((mu1 - mu2)*2.0) # calculate sqrt of product between cov covmean = sqrtm(sigma1.dot(sigma2)) # check and correct imaginary numbers from sqrt if iscomplexobj(covmean): covmean = covmean.real # calculate score fid = ssdiff trace(sigma1 sigma2 - 2.0 covmean) return fid
接下来,我们可以测试这个函数来计算一些人造特征向量的 Inception 分数。
特征向量可能包含小的正值,长度为 2 048 个元素。我们可以用包含小随机数的特征向量构建两组图像(每组 10 幅),如下所示:
act1 = random(102048) act1 = act1.reshape((10 2048)) act2 = random(102048) act2 = act2.reshape((10 2048))
一个测试是计算一组激活与其自身之间的 FID,我们期望分数为 0.0。
然后计算两组随机激活之间的距离,我们期望它们是一个很大的数字。
fid = calculate_fid(act1 act1) print('FID (same): %.3f' % fid) fid = calculate_fid(act1 act2) print('FID (different): %.3f' % fid)
将所有这些结合在一起,完整的示例如下:
import numpy from numpy import cov from numpy import trace from numpy import iscomplexobj from numpy.random import random from scipy.linalg import sqrtm def calculate_fid(act1 act2): # calculate mean and covariance statistics mu1 sigma1 = act1.mean(axis=0) cov(act1 rowvar=False) mu2 sigma2 = act2.mean(axis=0) cov(act2 rowvar=False) # calculate sum squared difference between means ssdiff = numpy.sum((mu1 - mu2)*2.0) # calculate sqrt of product between cov covmean = sqrtm(sigma1.dot(sigma2)) # check and correct imaginary numbers from sqrt if iscomplexobj(covmean): covmean = covmean.real # calculate score fid = ssdiff trace(sigma1 sigma2 - 2.0 covmean) return fid act1 = random(102048) act1 = act1.reshape((10 2048)) act2 = random(102048) act2 = act2.reshape((10 2048)) fid = calculate_fid(act1 act1) print('FID (same): %.3f' % fid) fid = calculate_fid(act1 act2) print('FID (different): %.3f' % fid)
运行这段代码示例,首先会显示出激活函数值「act1」和它自己之间的 FID 分数,正如我们所预想的那样,该值为 0.0(注:该分数的符号可以忽略)
同样,正如我们所预料的,两组随机激活函数值之间的距离是一个很大的数字,在本例中为 358
FID (same): -0.000 FID (different): 358.927
原文链接:https://machinelearningmastery.com/how-to-implement-the-frechet-inception-distance-fid-from-scratch/