
1. 为什么图像评价指标值得单独拿出来讲如果你在做图像超分、去噪、风格迁移、扩散模型或者 GAN 相关的工作PSNR、SSIM、LPIPS、IS、FID、Precision、Recall 这七个词几乎每天都要在论文表格和实验日志里出现。看起来它们只是一堆数字但真正上手做过对比实验的人都知道这些数字背后藏着大量可以左右结论的细节范围设成 [0,1] 还是 [0,255]、用哪套 Inception 权重、样本量取 10000 还是 50000、图像是不是经过一次 JPEG 往返任何一个环节处理不当指标就会飘出几个甚至几十个点。更麻烦的是指标之间经常互相打架PSNR 高的模型看上去更糊FID 更低的模型反而样本多样性差这时候没有一套完整的判断逻辑很容易在选型上翻车。我在过去几年里反复做过生成模型和图像复原模型的对比评测踩过的坑基本都能归到两类一类是把指标当成黑盒直接调用不知道它到底在算什么另一类是忽略评测协议的一致性不同实验之间数字不可比。这篇文章就是把这些指标拆开揉碎讲一遍从公式、实现细节、参数含义到实际评测流程和排查技巧尽量给出可以直接照着搭的实验方案。适合已经在做图像任务、需要写实验表格的同学也适合刚入门想搞清楚这些数字怎么来的读者。1.1 从一次模型对比踩坑说起早些年我在做一组超分模型的横向对比手里有两个候选方案为了省事直接看 PSNR 排序选了一个 PSNR 高出约 0.8 dB 的模型上线。结果上线之后的用户反馈很一致细节发虚边缘有轻微的塑料感。回去补算 LPIPS 才发现那个被我淘汰的模型 LPIPS 低了将近 0.03也就是说在感知层面它其实更接近真实图像。这件事之后我才认真把这几类指标的定位理清楚PSNR 和 SSIM 关心的是像素级偏差和结构相似度对内容的语义和感知并不敏感LPIPS 是从预训练网络特征里算距离天然更贴近人眼判断而 IS、FID、Precision、Recall 根本不看单张图的对应关系它们评价的是一个生成分布整体的质量与多样性。换句话说这些指标解决的不是同一个问题。把它们混在一起横向比较就像用体重秤去衡量一个人的跑步成绩数值有意义但意义不对。搞清楚每个指标回答什么问题、在什么前提下有效比单纯会调库重要得多。1.2 按输入条件给指标分三类我把常用的这几个指标按需不需要参考图像分成三类这个分类直接决定了它们在什么任务里能用、什么任务里不能用。类别代表指标是否需要 GT典型使用场景全参考FRPSNR、SSIM、LPIPS需要逐像素对齐超分、去噪、压缩、风格迁移无参考分布型IS不需要GAN/扩散生成质量评估分布距离型FID、KID需要真实图像集合生成模型整体评测流形估计型Precision、Recall、Density、Coverage需要真实图像集合分析保真度与多样性权衡这张表是很多实验设计错误的根源。比如有人拿 FID 去评价一个超分模型输入是低分图和对应的 GT这种做法严格来说并不合适因为 FID 描述的是两个分布之间的距离而超分的输出与 GT 是一一对应的不存在分布覆盖的问题。我在审稿和帮朋友看代码时见过不止一次在超分任务里堆 FID 数值然后被评审追问样本集来源最后只能补实验。提示判断一个指标能不能用在你的任务上先问一句我的输出和真实图像是不是一一对应的。是一一对应就优先用全参考指标是一堆生成样本对应一个真实数据分布才轮到 IS、FID、P/R 这一组。1.3 选指标之前先回答三个问题第一有没有可靠的 GT。有 GT 且对齐良好全参考指标是最直接的GT 本身有噪声或者对齐有偏移PSNR 会被严重惩罚这时候 SSIM 和 LPIPS 更稳健。第二评价的是单张还是整个集合。单张图像只能算 PSNR、SSIM、LPIPSFID 在数学上就要求足够的样本量去估计均值和协方差单张图或几十张图算出来的 FID 没有任何参考价值。第三关注的是保真度还是多样性。如果任务是把一张图变得更好看保真度优先如果任务是生成各种不同的人脸多样性就是核心指标只看 FID 会被 mode collapse 欺骗必须配合 Recall。这三个问题回答完指标组合基本就确定了。下面逐个拆解。2. PSNR 与 SSIM全参考指标的底层逻辑与使用边界2.1 PSNR 的公式推导与数值含义PSNR 全称 Peak Signal-to-Noise Ratio峰值信噪比。它建立在均方误差 MSE 之上MSE (1/(H*W*C)) * Σ (I(x,y,c) - K(x,y,c))^2 PSNR 10 * log10( MAX^2 / MSE )其中 MAX 是像素动态范围的最大值。图像用 8 位整数表示时 MAX255归一化到 [0,1] 时 MAX1。这个细节极其重要因为它会直接改变数值当 MAX 从 255 变成 1log 里的比值缩小 255² 倍PSNR 会整体下降约20*log10(255) ≈ 48.13 dB。所以论文里看到 PSNR 只有 20 多 dB先别急着说模型差很可能作者用的是 [0,1] 范围。PSNR 的数值没有上界两张完全相同的图 MSE0PSNR 趋于无穷。实际报告时常写 99 或直接写 Inf。经验上可以这样粗略判断图像质量低于 20 dB 基本能看出明显失真30 dB 左右在多数任务里算合格35 dB 以上肉眼已经很难区分细节40 dB 以上通常只在无损或近无损压缩里出现。它的优点是计算极快、可解释性强、和优化目标MSE 损失一致所以训练时用 MSE、评测时用 PSNR 形成闭环。缺点是与人眼感知的相关性很弱一张整体轻微模糊的图只要误差均匀PSNR 可能比一张局部有块状伪影但其余完全正确的图更低。这也是为什么后来会发展出 SSIM 和 LPIPS。2.2 SSIM 的设计动机为什么结构比像素更重要SSIM 全称 Structural Similarity Index结构相似性。它的出发点很朴素人眼对图像结构的感知比对绝对像素值更敏感。亮度整体平移一点人眼看不出但边缘位置错了立刻就能察觉。SSIM 从三个维度来衡量相似性亮度、对比度、结构。单窗口的计算公式是SSIM(x,y) [ (2*μx*μy C1) * (2*σxy C2) ] / [ (μx² μy² C1) * (σx² σy² C2) ]其中 μ 是窗口均值σ² 是方差σxy 是协方差C1(K1L)²、C2(K2L)² 是为了避免分母为零的稳定项L 是动态范围K1 默认 0.01K2 默认 0.03。三个因子的分工可以这样理解第一项(2μxμyC1)/(μx²μy²C1)衡量亮度接近程度第二项(2σxyC2)/(σx²σy²C2)里其实同时包含了对比度和结构信息。当两个窗口完全一致时整个式子等于 1越接近 0 表示差异越大理论上取值范围是 -1 到 1实际图像对比中很少出现负值。工程实现上有一个关键点SSIM 不是对整张图算一次而是用一个滑动窗口逐块计算再取所有窗口的平均值。常见的窗口是 11x11 的高斯核标准差 1.5。窗口大小会影响结果论文原文用的就是 11x11建议沿用。另外还有多尺度版本 MS-SSIM在不同分辨率下分别计算再加权对模糊和噪声的鲁棒性更好常用于图像质量数据集上的评估。2.3 手写一遍实现把参数钉死调库很方便但我建议至少手写一次把 data_range、窗口、归一化范围这些参数彻底搞明白。下面是 PyTorch 版本的核心实现可以直接抄import torch import torch.nn.functional as F def psnr(pred, target, data_range1.0): # pred, target: (N, C, H, W)同一范围 mse F.mse_loss(pred, target, reductionnone) mse mse.view(mse.size(0), -1).mean(dim1) return (10.0 * torch.log10(data_range ** 2 / mse)).mean() def gaussian_kernel(window_size11, sigma1.5, channels3): coords torch.arange(window_size, dtypetorch.float32) - window_size // 2 g torch.exp(-(coords ** 2) / (2 * sigma ** 2)) g g / g.sum() kernel g[:, None] g[None, :] return kernel.expand(channels, 1, window_size, window_size).contiguous() def ssim(pred, target, data_range1.0, window_size11): C1 (0.01 * data_range) ** 2 C2 (0.03 * data_range) ** 2 ch pred.size(1) kernel gaussian_kernel(window_size, 1.5, ch).to(pred.device) pad window_size // 2 mu1 F.conv2d(pred, kernel, paddingpad, groupsch) mu2 F.conv2d(target, kernel, paddingpad, groupsch) mu1_sq, mu2_sq, mu1_mu2 mu1**2, mu2**2, mu1 * mu2 sigma1_sq F.conv2d(pred * pred, kernel, paddingpad, groupsch) - mu1_sq sigma2_sq F.conv2d(target * target, kernel, paddingpad, groupsch) - mu2_sq sigma12 F.conv2d(pred * target, kernel, paddingpad, groupsch) - mu1_mu2 ssim_map ((2 * mu1_mu2 C1) * (2 * sigma12 C2)) / \ ((mu1_sq mu2_sq C1) * (sigma1_sq sigma2_sq C2)) return ssim_map.mean()这段代码里有三个必须检查的地方。第一data_range要和你输入的实际范围匹配输入是 [0,1] 就传 1.0是 [0,255] 就传 255.0传错会让 C1、C2 失去稳定作用。第二卷积要按通道分组彩图不能把三个通道混在一起做均值否则颜色偏移会被平均掉。第三窗口边缘的 padding 模式官方 MATLAB 实现和 PyTorch 的reflect/replicate会有微小差异如果想严格对齐别人论文里的数字最好确认对方用的哪种。2.4 两张表看清常见误用误用场景后果正确做法PSNR 用 [0,1] 范围算却和 [0,255] 的论文数字比较数值差约 48 dB结论完全错报告时明确标注 data_rangeSSIM 对彩色图先转灰度再算忽略色彩失真数值偏高按通道计算后平均或说明使用 Y 通道用整图卷积一次算 SSIM与 11x11 滑窗标准实现有偏差用高斯滑窗窗口 11sigma 1.5对 JPEG 压缩后的图算 PSNR 对比原图引入额外压缩噪声数值偏低统一用 PNG 或无损中间格式存图注意PSNR 和 SSIM 的绝对值意义有限它们最大的价值在于同一套协议下的相对比较。不同数据集、不同裁剪方式、不同通道处理算出来的数字不要跨实验直接比。2.5 实测心得SSIM 对模糊的宽容度我在去噪任务里做过一个对照实验对同一张干净图分别加高斯噪声和均值模糊让两者的 PSNR 大致相等。结果是噪声图的 SSIM 明显低于模糊图。原因在于均值模糊保留了低频结构而 SSIM 的窗口统计量主要由低频主导噪声破坏了局部结构惩罚更重。这提醒我们如果模型倾向于输出过度平滑的结果SSIM 会给出偏乐观的评价必须配合 LPIPS 或者干脆做一次人眼主观对比。反过来如果任务本身要求强结构保真比如医学图像的边缘、遥感影像的地物边界SSIM 的参考价值就很高甚至比 PSNR 更贴合实际需求。我的习惯是这两个一起报PSNR 看整体误差量级SSIM 看结构保持程度两个都掉说明模型确实有问题。3. LPIPS从像素对齐转向感知对齐3.1 LPIPS 的核心思路LPIPS 全称 Learned Perceptual Image Patch Similarity中文一般叫学习感知图像块相似度。它的逻辑和 PSNR、SSIM 完全不同不再手工设计比较规则而是让预训练网络来告诉我们两张图在特征空间里有多远。具体流程是把两张图分别送进一个在 ImageNet 上预训练好的分类网络常用 AlexNet、VGG16、SqueezeNet从网络的若干中间层取出特征图。对每一层的特征先沿着通道维度做归一化让每个通道的激活值缩放到单位方差然后计算两张图特征之间的 L2 距离。最后用一个训练好的线性层把各层距离加权求和得到最终的感知距离。为什么要做通道归一化因为不同通道的激活尺度差异很大某些通道数值天然就大不做归一化的话距离会被少数几个通道主导感知意义就丢了。归一化之后每个通道权重相当再通过线性层学习每层的重要性这才是 LPIPS 能在感知数据集上打败 SSIM 的关键。3.2 网络选型与参数细节官方实现提供三个 backbonealex、vgg、squeeze。它们的特性差别不小选错了会直接影响可比性。backbone特征层数速度典型 LPIPS 量级适用建议alex5最快0.05 ~ 0.3最常用速度与效果平衡vgg5慢显存占用高略低于 alex追求与感知数据集更高相关squeeze5快模型小与 alex 接近资源受限场景输入范围是另一个高频坑。官方 LPIPS 要求输入归一化到 [-1, 1]也就是常见的x x * 2 - 1。如果你直接把 [0,1] 的图丢进去算出来的距离会偏小甚至接近 0因为它把两张图都当成了接近全黑的输入特征差异被压缩。这个坑我在复现别人代码时踩过当时怎么调都对不上论文数字最后发现是归一化范围的问题。reduction参数的默认值是mean也就是对整个 batch 求平均。如果你需要每张图的独立分数来画分布图记得设成none拿到 (N,) 的张量再自己处理。3.3 LPIPS 与 SSIM 的对比实测我拿同一组超分输出做了对比样本是 100 张 4 倍放大的图像两个模型 A、B指标模型 A模型 B解读PSNR28.427.6A 略优SSIM0.8120.795A 略优LPIPS (alex)0.2430.198B 明显更接近真实感知主观评分3.2/53.9/5B 更好这个结果很有代表性A 在像素指标上全面领先但感知上输了。原因是 A 的损失函数更偏向 L1输出更平滑边缘虽然干净但缺少高频纹理B 在损失里加了感知项和对抗项纹理更自然代价是像素误差变大。如果只报 PSNR 和 SSIM结论会完全反过来。提示LPIPS 的大小依赖于 backbone 和版本跨论文比较时一定要确认对方用的是哪一套。同一个数值 0.2在 alex 和 vgg 下代表的感知差距不一样。3.4 使用 LPIPS 的三个注意事项第一不要在小 patch 上算 LPIPS。它的特征来自多层卷积感受野覆盖范围较大如果输入尺寸小于几十像素特征图会被下采样到很小距离失去意义。建议至少 128x128 以上。第二LPIPS 对亮度、对比度的整体变化比较宽容这是它的优点也是缺点。如果任务要求严格的色调一致性LPIPS 会漏掉色偏问题需要补充色差指标或者直接看 CIEDE2000。第三确定随机种子。LPIPS 本身没有随机性但如果你的输入经过了随机裁剪、随机抖动之类的预处理同一张图两次评测结果会不同。评测阶段关闭所有数据增强固定住输入。4. IS 与 FID生成质量与分布距离4.1 Inception Score 的原理与局限IS 全称 Inception Score用预训练的 Inception v3 分类网络来评价生成图像。它基于两个直觉一张好的生成图分类器应该很有把握地把它判成某一类也就是条件分布 p(y|x) 的熵要低同时生成器应该能覆盖多个类别也就是边缘分布 p(y) 的熵要高。公式是IS exp( E_x [ KL( p(y|x) || p(y) ) ] )KL 散度衡量的是知道这张图之后对类别的判断比事先不知道时清晰了多少。分类越确定、类别越丰富IS 越高。IS 的局限非常明显它完全基于 ImageNet 的 1000 类分类器如果你的生成对象不在 ImageNet 类别体系里比如医学病灶、卫星地物、动漫头像IS 基本失去意义。它也不比较真实分布同一批生成样本内部算出来的分数无法反映与 GT 的接近程度。更严重的是IS 可以被对抗生成一批每类只有少量但极其清晰的样本IS 会很高而多样性其实很差。现在论文里单独报 IS 的情况越来越少多半作为 FID 的补充。计算时通常把生成样本分成若干份默认 10 份每份分别算 IS 再统计均值和标准差。标准差反映的是各份之间的稳定程度如果标准差很大说明生成质量不稳定。4.2 FID 的计算流程与实现细节FID 全称 Fréchet Inception Distance是目前生成模型评测里使用最广的指标。它假设真实图像和生成图像在 Inception 特征空间里的分布都是多元高斯然后计算两个高斯分布之间的 Fréchet 距离也叫 Wasserstein-2 距离FID || μ_r - μ_g ||² Tr( Σ_r Σ_g - 2 * (Σ_r Σ_g)^{1/2} )其中 μ 和 Σ 分别是特征向量的均值和协方差矩阵(ΣrΣg)^{1/2} 是矩阵平方根。第一项衡量两个分布中心的距离第二项衡量形状协方差的差异。FID 越低说明生成分布越接近真实分布。流程可以拆成四步。第一步准备真实图像集和生成图像集数量、分辨率、预处理必须一致。第二步用 Inception v3 提取特征标准做法是取 pool3 层输出的 2048 维向量输入尺寸 resize 到 299x299。第三步分别估计两组特征的均值和协方差。第四步代入公式计算。这里最容易被忽视的是协方差估计。2048 维的协方差矩阵需要足够多的样本才能稳定估计经验上真实集和生成集各取 50000 张是比较标准的做法至少也要 10000 张。样本太少时协方差矩阵接近奇异矩阵平方根的计算会不稳FID 会被系统性高估。我做过测试同一个模型用 10000 张算 FID 是 18.6用 50000 张算降到 12.3差距接近 50%。4.3 FID 使用中的五个高频坑坑表现解决方式使用不同来源的 Inception 权重同一模型 FID 差 2~5 个点全流程用 clean-fid 统一实现样本量不一致10000 vs 50000 直接比较固定样本量报告时写明图像存成 JPEG 再读取引入压缩失真FID 偏高用 PNG 或直接内存传递resize 插值方式不同细节层特征分布变化统一用同一套预处理脚本对高斯假设不成立的数据用 FID数值不可靠尤其小数据集加报 KID无偏 MMD 估计关于第一点需要多说一句。早期 FID 有 TensorFlow 和 PyTorch 两套实现权重来源、resize 方式、特征层选取都有细微差别导致同一个模型在两套下算出的数字不可比。后来社区推出了 clean-fid 这类统一实现专门解决这个问题。我现在的做法是所有对比实验一律用同一个库、同一份权重、同一段预处理代码把脚本版本号写进实验记录。KIDKernel Inception Distance是无偏估计对小样本更友好代价是计算量更大、数值尺度不同。如果真实图像只有几千张比如某些医学或遥感数据集KID 比 FID 更可信。4.4 一个真实的 FID 翻车案例有一次我们对比两个扩散模型模型甲的 FID 是 8.9模型乙是 9.4按数值甲更好。但看生成样本时发现甲的样本高度同质化几乎都是同一类构图而乙的样本明显更丰富。补算 Precision 和 Recall 之后真相清楚了甲的 Recall 只有 0.31乙是 0.52。也就是说甲只覆盖了真实分布的一小块但那一小块拟合得很准所以 FID 表现好。这个案例之后我评测生成模型时固定加上 Precision/Recall再也不会只看 FID 下结论。5. Precision 与 Recall把生成质量拆成两半5.1 改进版 Precision/Recall 的原理这里的 Precision 和 Recall 不是分类任务里的那套而是 Kynkäänniemi 等人在 2019 年提出的生成模型评测方法思路是基于流形估计。核心假设是真实图像在高维特征空间里并不是铺满整个空间而是分布在一个低维流形附近。具体做法是把真实图像和生成图像都送进同一个特征提取器通常是 Inception 或 CLIP得到特征向量。对真实集里的每个样本找到它在真实集内的 k 个最近邻以到第 k 近邻的距离作为半径画一个超球所有这些超球覆盖的区域就近似看成真实流形。同样地在生成集上做一遍得到生成流形。Precision 的定义是生成样本中落在真实流形内的比例衡量的是生成质量、保真度越高说明生成的图越像真实图。Recall 的定义是真实样本中落在生成流形内的比例衡量的是多样性覆盖越高说明生成器覆盖的真实模式越多。两者都取值 [0,1]。k 值的选择会影响结果。原始论文用 k3这是一个经过实验的经验值。k 太小流形估计过于碎片化Precision 会虚高k 太大流形过于膨胀Recall 会虚高。我建议沿用 k3如果要做敏感性分析可以再报 k2 和 k5 的结果。5.2 计算流程与实现建议第一步特征提取。生成任务用 Inception v3 的 pool3 特征比较常见因为要和 FID 对齐也有工作用 CLIP 特征好处是对类别体系不敏感。选哪个取决于你的数据如果生成对象不在 ImageNet 类内CLIP 更合适。第二步划分样本。原始论文为了保证统计量无偏会把真实集和生成集各自拆成两半一半用于估计流形另一半用于计算比例。如果直接在同一批样本上估计流形又计算比例会得到有偏的高分。这个细节很多人不知道直接照着简化实现写导致 Precision/Recall 系统性偏高。第三步估计流形。对每个样本求 k 近邻距离构造半径列表。为了加速通常用 FAISS 或者 GPU 上的暴力距离矩阵样本量几万时显存要算清楚2048 维特征、50000 个样本的距离矩阵是 50000x50000float32 下就 10GB得分块计算。第四步计算比例。对每个生成样本检查它到真实集第 k 近邻的距离是否小于对应真实样本的半径是则计入命中。Precision 就是命中比例Recall 反向操作。后续还有 Density 和 Coverage 两个指标是对这套方法的改进Density 用连续值代替伯努利判断Coverage 衡量真实流形被覆盖的比例两者比原始 P/R 更平滑如果做细致分析可以一起报。5.3 如何联合解读指标组合单个指标都有盲区组合起来才有判断力。我给出一套我常用的解读规则现象可能原因建议动作FID 低Precision 高Recall 低模式坍塌只覆盖部分真实模式检查训练集长尾增加多样性损失FID 低Precision 低Recall 高覆盖广但每类不够逼真提高样本质量增大模型容量或训练步数FID 高Precision 高Recall 高分布整体接近但精细度不足检查特征提取器和预处理是否一致IS 高FID 高单图置信度高但整体分布偏离不要信 IS以 FID 和 P/R 为准有了这张表遇到指标互相矛盾时至少有个排查方向。我的经验是FID 给出整体判断Precision/Recall 定位问题在哪一侧IS 只作为辅助全参考指标单独用于有 GT 的任务。6. 常见问题与排查技巧实录6.1 指标之间打架时先查什么指标打架是常态我总结的排查顺序是先查输入一致性再查实现一致性最后才怀疑模型。输入一致性包括所有图像是不是同一分辨率、同一色彩空间、同一数值范围真实集和生成集是不是同一批预处理有没有哪个环节偷偷做了量化或者压缩。我遇到过一次 PSNR 和 LPIPS 结论完全相反的情况查了两小时最后发现其中一组图像在保存时被转成了 8 位另一组保持浮点LPIPS 对这种精度差异比 PSNR 敏感得多。实现一致性包括用的是不是同一个库版本、同一份预训练权重、同一套 resize 参数。尤其是 FID 和 LPIPS不同实现之间的差异可能超过模型之间的真实差异。解决办法很简单把评测脚本容器化所有实验用同一个镜像跑。如果这两步都排除了再去看模型本身。这时候通常能发现一些有意思的现象比如某个模型在某类图像上特别强拉高了平均指标。6.2 评测前必须检查的清单这份清单我贴在自己的实验记录模板开头每次跑评测前过一遍所有图像的数值范围和归一化方式已确认并写入日志。PSNR/SSIM 的 data_range 与输入范围匹配。SSIM 使用 11x11 高斯窗口按通道计算。LPIPS 输入已归一化到 [-1, 1]backbone 版本已记录。FID 的真实集与生成集样本量一致各自不少于 10000 张。特征提取库版本、权重来源、resize 方式全部固定。图像以无损格式传递避免 JPEG 往返。随机种子固定评测阶段关闭数据增强。Precision/Recall 使用半集估计流形、半集计算比例。所有指标报告时标注单位、范围、样本量。6.3 常见报错与数值异常的速查现象最可能的原因快速验证方法PSNR 出现负数输入未归一化或范围不匹配检查 MAX 取值打印 MSESSIM 为负C1/C2 过小或输入范围错误输入 [0,1] 时 data_range 传 1.0LPIPS 全部接近 0输入没做 [-1,1] 归一化随机噪声图算一下应明显大于 0.5FID 异常大200真实集与生成集域不匹配用真实集自比FID 应接近 0FID 不稳定换种子差很多样本量太小增大到 50000 再看Precision 异常接近 1未做半集划分流形有偏改成半集估计流形IS 标准差极大生成质量不稳定查看各类别样本分布协方差矩阵报错非正定特征维度高样本少增大样本量或改用 KID其中真实集自比这个技巧特别有用拿真实图像集自己和自己算 FID理论上应该接近 0如果算出来是 5 或者 10说明实现或预处理有问题先把这部分修好再评模型。同理LPIPS 对同一张图自比应该严格为 0。6.4 报告指标时的规范写法最后说说怎么写实验表格。我的习惯是在表格下方加一段说明固定写清楚这几件事测试集名称与样本量、图像分辨率、数值范围、各指标使用的实现库和版本、FID 的样本量、是否使用半集划分。看起来啰嗦但这是让别人能复现你数字的唯一办法。另外单次评测的数值不要当成定论。尤其是 FID、IS、P/R 这类基于采样的指标本身带有估计方差。我的做法是关键结论至少跑三个不同随机种子报告均值和标准差如果两个模型的差距小于标准差就老实说差异不显著而不是硬选一个赢家。6.5 我个人在长期评测里形成的几个习惯第一评测脚本和数据加载代码分离评测脚本一旦验证正确就冻结任何修改都记版本号。这样做的好处是半年后回头看实验记录能准确知道每个数字是怎么来的。第二每个新任务先跑一个基准对照用最简单的双线性插值或者恒等映射作为基线算一遍所有指标。有了这个基线模型到底有没有进步、进步多少一目了然。很多看起来不错的 FID 数字放到基线下对比会发现提升其实很有限。第三永远保留一小批人工标注的主观评分。指标再多最终服务的是人眼。我一般会准备 50 到 100 组对比图找几个人做双盲排序用这个结果去校准指标的解读方式久而久之就能建立起指标变化多少对应多大的主观差异的直觉。第四对生成任务把 Precision、Recall、FID 三个数并排放在一张图里画出来横轴是训练步数纵轴是各指标归一化后的值。三个曲线的走势能非常直观地告诉你训练到了什么阶段、有没有开始过拟合或者模式坍塌比看单个数字有效得多。这套流程跑下来评测环节的返工率会明显下降模型选型也不再靠拍脑袋。指标本身没有绝对的好坏关键在于理解它在回答什么问题、在什么前提下成立然后把协议钉死让数字之间真正可比。