导入图片
我的图片是以256*256的矩阵形式存储,将其张量化。inception_v3模型输入图片要求最小是75*75,最佳是299*299。
images_t = torch.tensor(images1)# 真实图片集合
images_g = torch.tensor(images2)# 生成图片集合
计算特征
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
model = inception_v3(pretrained=True, transform_input=False)
# 将通道数改为1
model.Conv2d_1a_3x3.conv = nn.Conv2d(1, 32, kernel_size=(3, 3), stride=(2, 2), bias=False)
# 删除最后一层全连接层
model.fc = nn.Sequential()
model.to(device)
model.eval()
with torch.no_grad():
act1 = model(images_t).detach().cpu()
act2 = model(images_g).detach().cpu()
act_values1 = act1.numpy()
act_values2 = act2.numpy()
FID分数计算需要先将图片输入到预训练的inception_v3模型中,我输入的图片通道数为1,将inception_v3第一层的卷积通道数改为1。此外,计算FID分数,我们需要inception_v3模型输出的2048维度特征矩阵,需要删除最后一层全连接层。
计算均值向量和协方差矩阵
用numpy中的mean()和np.cov()计算特征均值和协方差矩阵,在计算特征时利用numpy()将输出转化为nd.array
mu1, sigma1 = act_values1.mean(axis=0), np.cov(act_values1, rowvar=False)
mu2, sigma2 = act_values2.mean(axis=0), np.cov(act_values2, rowvar=False)
#
# calculate sum squared difference between means
ssdiff = np.sum((mu1 - mu2) ** 2.0)
# calculate sqrt of product between cov, sqrtm( ) 对矩阵整体开平方
covmean = sqrtm(sigma1.dot(sigma2))
# check and correct imaginary numbers from sqrt,如果covmean中有复数,则返回true
if np.iscomplexobj(covmean):
covmean = covmean.real
计算FID分数
根据FID公式计算FID分数
# calculate score
fid = ssdiff + np.trace(sigma1 + sigma2 - 2.0 * covmean)
参考链接:
图像质量评估---FID_fid分数_xiaoxuan1120的博客-CSDN博客
深度学习生成模型的 Inception Score 和FID 以及在pytorch的代码 - 知乎 (zhihu.com)