深度学习指标及代码示例
·
👋 你好!这里有实用干货与深度分享✨✨ 若有帮助,欢迎:
👍 点赞 | ⭐ 收藏 | 💬 评论 | ➕ 关注 ,解锁更多精彩!
📁 收藏专栏即可第一时间获取最新推送🔔。
📖后续我将持续带来更多优质内容,期待与你一同探索知识,携手前行,共同进步🚀。

深度学习指标及代码示例
深度学习指标用于评估模型的性能、训练效果及泛化能力,不同任务(分类、回归、语义分割等)适用的指标不同。以下是常见任务的核心指标及其详细解析:
一、分类任务指标
1. 准确率(Accuracy)
- 公式:
[
\text{Accuracy} = \frac{\text{正确预测的样本数}}{\text{总样本数}} = \frac{TP + TN}{TP + TN + FP + FN}
]
((TP):真阳性,(TN):真阴性,(FP):假阳性,(FN):假阴性) - 适用场景:类别均衡场景(如MNIST手写识别)。
- 局限性:类别不平衡时失效(如癌症检测中健康样本占99%时,模型全预测为健康准确率仍高,但无意义)。
2. 精确率(Precision)与召回率(Recall)
- 精确率(查准率):
[
\text{Precision} = \frac{TP}{TP + FP}
]
含义:预测为正例的样本中实际为正例的比例(关注“误报”)。 - 召回率(查全率):
[
\text{Recall} = \frac{TP}{TP + FN}
]
含义:实际正例中被正确预测的比例(关注“漏报”)。 - 应用:
- 精确率优先:垃圾邮件分类(误判正常邮件为垃圾邮件后果严重)。
- 召回率优先:医学检测(漏诊癌症后果严重)。
3. F1分数(F1-Score)
- 公式:
[
F1 = 2 \times \frac{\text{Precision} \times \text{Recall}}{\text{Precision} + \text{Recall}}
]
含义:精确率与召回率的调和平均数,平衡两者表现,适用于类别不平衡场景。
4. 混淆矩阵(Confusion Matrix)
- 定义:以矩阵形式展示分类结果的TP、TN、FP、FN分布,直观反映模型在各类别上的表现。
- 示例(二分类):
真实\预测 正例(预测1) 负例(预测0) 正例(1) TP FN 负例(0) FP TN
5. ROC曲线与AUC
- ROC曲线(Receiver Operating Characteristic):
- 横轴:假正率(FPR = (\frac{FP}{TN + FP})),纵轴:真正率(TPR = (\frac{TP}{TP + FN}))。
- 曲线越靠近左上角,模型分类能力越强。
- AUC(Area Under Curve):
- ROC曲线下的面积,取值范围[0, 1]。
- AUC=0.5:模型性能等同于随机猜测;AUC=1:完美分类器。
二、回归任务指标
1. 均方误差(MSE, Mean Squared Error)
- 公式:
[
\text{MSE} = \frac{1}{n} \sum_{i=1}^n (y_i - \hat{y}_i)^2
]
含义:预测值与真实值差值平方的均值,对异常值敏感(误差放大)。
2. 均方根误差(RMSE, Root Mean Squared Error)
- 公式:
[
\text{RMSE} = \sqrt{\text{MSE}} = \sqrt{\frac{1}{n} \sum_{i=1}^n (y_i - \hat{y}_i)^2}
]
含义:MSE的平方根,与真实值单位一致,便于解释。
3. 平均绝对误差(MAE, Mean Absolute Error)
- 公式:
[
\text{MAE} = \frac{1}{n} \sum_{i=1}^n |y_i - \hat{y}_i|
]
含义:预测值与真实值绝对误差的均值,对异常值鲁棒性优于MSE。
4. R²分数(R-Squared)
- 公式:
[
R^2 = 1 - \frac{\sum_{i=1}^n (y_i - \hat{y}_i)2}{\sum_{i=1}n (y_i - \bar{y})^2}
]
((\bar{y})为真实值均值) - 含义:模型解释真实值变化的比例:
- (R2=1):完美预测;(R2=0):模型预测等于均值(无价值);(R^2<0):模型差于基线。
三、语义分割任务指标
1. 交并比(IoU, Intersection over Union)
- 公式:
[
\text{IoU} = \frac{\text{预测区域与真实区域的交集面积}}{\text{预测区域与真实区域的并集面积}}
] - 含义:衡量预测分割结果与真实标签的重叠程度,广泛用于目标检测、语义分割。
2. 平均交并比(mIoU, Mean IoU)
- 计算:对每个类别计算IoU,再求平均值。
- 应用:评估模型在多类别分割任务中的整体表现(如ADE20K数据集)。
3. 像素准确率(Pixel Accuracy, PA)
- 公式:
[
\text{PA} = \frac{\text{正确预测的像素数}}{\text{总像素数}}
] - 局限性:对大类别敏感,小目标易被忽略(如卫星图像中的车辆)。
四、目标检测任务指标
1. 平均精度(AP, Average Precision)
- 计算:
- 在单类别中,遍历不同置信度阈值,计算对应的精确率和召回率,生成PR曲线,AP为曲线下面积。
- 多类别场景下取所有类别的AP平均值,即mAP(mean Average Precision)。
- 示例:COCO数据集使用mAP@[0.5:0.95](多IoU阈值下的平均mAP)评估模型。
2. 帧率(FPS, Frames Per Second)
- 含义:模型每秒处理的图像帧数,衡量推理速度,用于实时检测(如YOLO系列)。
五、生成任务指标(如图像生成、NLP)
1. inception分数(IS, Inception Score)
- 原理:基于预训练Inception网络,计算生成样本的类别概率分布熵(衡量多样性)与条件概率分布熵(衡量真实性)之差。
- 公式:
[
\text{IS} = \exp\left(\mathbb{E}x \left[ D{\text{KL}}(p(y|x) | p(y)) \right] \right)
]
(值越大,生成样本越真实且多样)。
2. 弗雷歇 inception距离(FID, Fréchet Inception Distance)
- 原理:比较生成样本与真实样本在Inception网络高层特征空间的均值和协方差距离,衡量分布相似度。
- 优势:比IS更敏感,尤其适用于样本多样性低的场景。
六、其他通用指标
1. 损失函数(Loss Function)
- 分类任务:交叉熵损失(Cross-Entropy Loss)、焦点损失(Focal Loss,缓解类别不平衡)。
- 回归任务:均方损失(MSE Loss)、Huber损失(鲁棒性强,兼顾MAE和MSE)。
- 生成任务:对抗损失(Adversarial Loss,如GAN)。
2. 过拟合与欠拟合指标
- 训练集与验证集损失对比:
- 训练损失低、验证损失高:过拟合(需正则化、数据增强)。
- 训练损失高、验证损失高:欠拟合(需增加模型复杂度、调整超参数)。
3. 计算资源指标
- 参数量(Params):模型可训练参数总数,影响存储和推理速度。
- 浮点运算量(FLOPs):衡量模型计算复杂度,用于比较不同架构的效率(如Transformer与CNN)。
总结:指标选择指南
| 任务类型 | 核心指标 | 场景示例 |
|---|---|---|
| 二分类/多分类 | 准确率、精确率/召回率、F1、AUC-ROC | 情感分析、医学影像分类 |
| 回归 | MSE、RMSE、MAE、R² | 房价预测、温度预测 |
| 语义分割 | IoU、mIoU、像素准确率 | 自动驾驶道路分割 |
| 目标检测 | mAP、FPS | 物体定位与识别 |
| 生成任务 | IS、FID | 图像生成、文本生成 |
关键原则:
- 结合业务需求(如医疗优先召回率,推荐系统优先精确率)。
- 多指标综合评估(避免单一指标偏差)。
- 关注数据分布(类别平衡、异常值影响)。
通过合理选择指标,可更全面地理解模型性能,指导调优方向。
代码示例
import numpy as np
from sklearn.metrics import confusion_matrix, roc_curve, auc, precision_recall_curve
# ================ 分类指标 ================
def accuracy(y_true, y_pred):
"""计算准确率"""
return np.mean(y_true == y_pred)
def precision_recall_f1(y_true, y_pred):
"""计算精确率、召回率和F1分数"""
cm = confusion_matrix(y_true, y_pred)
if cm.shape != (2, 2): # 处理二分类情况
raise ValueError("仅支持二分类问题")
tn, fp, fn, tp = cm.ravel()
precision = tp / (tp + fp) if (tp + fp) > 0 else 0
recall = tp / (tp + fn) if (tp + fn) > 0 else 0
f1 = 2 * (precision * recall) / (precision + recall) if (precision + recall) > 0 else 0
return precision, recall, f1
def roc_auc(y_true, y_score):
"""计算ROC曲线和AUC"""
fpr, tpr, _ = roc_curve(y_true, y_score)
roc_auc = auc(fpr, tpr)
return fpr, tpr, roc_auc
def pr_curve(y_true, y_score):
"""计算PR曲线"""
precision, recall, _ = precision_recall_curve(y_true, y_score)
return precision, recall
# ================ 回归指标 ================
def mse(y_true, y_pred):
"""计算均方误差"""
return np.mean((y_true - y_pred) ** 2)
def rmse(y_true, y_pred):
"""计算均方根误差"""
return np.sqrt(mse(y_true, y_pred))
def mae(y_true, y_pred):
"""计算平均绝对误差"""
return np.mean(np.abs(y_true - y_pred))
def r_squared(y_true, y_pred):
"""计算R²分数"""
ss_res = np.sum((y_true - y_pred) ** 2)
ss_tot = np.sum((y_true - np.mean(y_true)) ** 2)
return 1 - (ss_res / ss_tot) if ss_tot != 0 else 0
# ================ 分割指标 ================
def iou(y_true, y_pred):
"""计算IoU(交并比)"""
intersection = np.logical_and(y_true, y_pred)
union = np.logical_or(y_true, y_pred)
return np.sum(intersection) / np.sum(union) if np.sum(union) > 0 else 0
def miou(y_true, y_pred, num_classes):
"""计算mIoU(平均交并比)"""
miou = 0
for c in range(num_classes):
c_true = (y_true == c)
c_pred = (y_pred == c)
miou += iou(c_true, c_pred)
return miou / num_classes
def pixel_accuracy(y_true, y_pred):
"""计算像素准确率"""
return np.mean(y_true == y_pred)
# ================ 目标检测指标 ================
def calculate_ap(recall, precision):
"""计算AP(平均精度) - 简化版"""
# 插值计算AP
mrec = np.concatenate(([0.0], recall, [1.0]))
mpre = np.concatenate(([0.0], precision, [0.0]))
for i in range(len(mpre) - 1, 0, -1):
mpre[i - 1] = max(mpre[i - 1], mpre[i])
i = np.where(mrec[1:] != mrec[:-1])[0]
ap = np.sum((mrec[i + 1] - mrec[i]) * mpre[i + 1])
return ap
# ================ 生成指标 ================
def calculate_fid(real_features, fake_features):
"""计算FID(简化版)"""
# 计算均值和协方差
mu1, sigma1 = np.mean(real_features, axis=0), np.cov(real_features, rowvar=False)
mu2, sigma2 = np.mean(fake_features, axis=0), np.cov(fake_features, rowvar=False)
# 计算FID
diff = mu1 - mu2
# 矩阵平方根近似
covmean = _sqrtm(sigma1.dot(sigma2))
if not np.isfinite(covmean).all():
offset = np.eye(sigma1.shape[0]) * 1e-6
covmean = _sqrtm((sigma1 + offset).dot(sigma2 + offset))
# 计算最终FID
fid = diff.dot(diff) + np.trace(sigma1 + sigma2 - 2 * covmean)
return fid
def _sqrtm(mat):
"""矩阵平方根的简化实现"""
# 实际应用中应使用更稳定的算法
u, s, vh = np.linalg.svd(mat)
return u @ np.diag(np.sqrt(s)) @ vh
# ================ 示例使用 ================
# 示例数据
y_true_clf = np.array([1, 0, 1, 1, 0, 1])
y_pred_clf = np.array([1, 0, 1, 0, 0, 1])
y_score_clf = np.array([0.8, 0.3, 0.9, 0.4, 0.2, 0.7])
y_true_reg = np.array([3.2, 5.1, 2.8, 7.6])
y_pred_reg = np.array([3.5, 4.9, 3.0, 7.8])
y_true_seg = np.array([[1, 1, 0], [0, 1, 1]])
y_pred_seg = np.array([[1, 0, 0], [0, 1, 1]])
# 计算指标
print("===== 分类指标 =====")
print(f"准确率: {accuracy(y_true_clf, y_pred_clf):.4f}")
p, r, f1 = precision_recall_f1(y_true_clf, y_pred_clf)
print(f"精确率: {p:.4f}, 召回率: {r:.4f}, F1: {f1:.4f}")
fpr, tpr, auc_val = roc_auc(y_true_clf, y_score_clf)
print(f"AUC-ROC: {auc_val:.4f}")
print("\n===== 回归指标 =====")
print(f"MSE: {mse(y_true_reg, y_pred_reg):.4f}")
print(f"RMSE: {rmse(y_true_reg, y_pred_reg):.4f}")
print(f"MAE: {mae(y_true_reg, y_pred_reg):.4f}")
print(f"R²: {r_squared(y_true_reg, y_pred_reg):.4f}")
print("\n===== 分割指标 =====")
print(f"IoU: {iou(y_true_seg, y_pred_seg):.4f}")
print(f"mIoU (假设2类): {miou(y_true_seg, y_pred_seg, 2):.4f}")
print(f"像素准确率: {pixel_accuracy(y_true_seg, y_pred_seg):.4f}")
print("\n===== 目标检测指标 =====")
recall = np.array([0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0])
precision = np.array([1.0, 0.9, 0.8, 0.7, 0.6, 0.5, 0.4, 0.3, 0.2, 0.1, 0.0])
ap = calculate_ap(recall, precision)
print(f"AP: {ap:.4f}")
print("\n===== 生成指标 =====")
real_features = np.random.rand(100, 2048) # 假设特征维度为2048
fake_features = np.random.rand(100, 2048)
fid = calculate_fid(real_features, fake_features)
print(f"FID: {fid:.4f}")
多分类 F1-score 计算
在上面提供的代码中,precision_recall_f1 函数仅支持二分类,无法直接处理多分类问题。这是因为它假设混淆矩阵为 2×2 结构(仅区分正例和负例)。
想要支持多分类,需要重构函数以处理任意数量的类别,并计算宏观(macro)或微观(micro)平均指标。
- 多类别支持:通过处理任意大小的混淆矩阵(n×n)支持多分类。
- 平均策略:
- 微平均(micro):将所有类别的 TP、FP、FN 汇总后计算指标,适用于类别不平衡场景。
- 宏平均(macro):对每个类别单独计算指标后取平均,平等对待所有类别。
- 加权平均(weighted):按类别样本数加权计算平均,避免小类别被忽视。
以下是重构后的代码,支持多分类的 F1-score 计算:
import numpy as np
from sklearn.metrics import confusion_matrix
def precision_recall_f1(y_true, y_pred, average='macro'):
"""
计算多分类的精确率、召回率和F1分数
:param y_true: 真实标签
:param y_pred: 预测标签
:param average: 平均方法,可选'macro'(宏平均)、'micro'(微平均)、'weighted'(加权平均)
:return: 精确率、召回率、F1分数
"""
cm = confusion_matrix(y_true, y_pred)
n_classes = cm.shape[0]
if average == 'micro':
# 微平均:计算全局TP、FP、FN
tp = np.diag(cm).sum()
fp = cm.sum(axis=0) - np.diag(cm)
fn = cm.sum(axis=1) - np.diag(cm)
fp = fp.sum()
fn = fn.sum()
precision = tp / (tp + fp) if (tp + fp) > 0 else 0
recall = tp / (tp + fn) if (tp + fn) > 0 else 0
f1 = 2 * (precision * recall) / (precision + recall) if (precision + recall) > 0 else 0
return precision, recall, f1
else: # macro或weighted
# 为每个类别计算P、R、F1
precisions = np.zeros(n_classes)
recalls = np.zeros(n_classes)
f1s = np.zeros(n_classes)
support = np.sum(cm, axis=1) # 每个类别的样本数
for c in range(n_classes):
tp = cm[c, c]
fp = cm[:, c].sum() - tp
fn = cm[c, :].sum() - tp
precisions[c] = tp / (tp + fp) if (tp + fp) > 0 else 0
recalls[c] = tp / (tp + fn) if (tp + fn) > 0 else 0
f1s[c] = 2 * (precisions[c] * recalls[c]) / (precisions[c] + recalls[c]) if (precisions[c] + recalls[c]) > 0 else 0
if average == 'macro':
# 宏平均:直接平均所有类别的指标
precision = np.mean(precisions)
recall = np.mean(recalls)
f1 = np.mean(f1s)
return precision, recall, f1
elif average == 'weighted':
# 加权平均:按类别样本数加权
precision = np.average(precisions, weights=support)
recall = np.average(recalls, weights=support)
f1 = np.average(f1s, weights=support)
return precision, recall, f1
else:
raise ValueError("average参数必须为'macro'、'micro'或'weighted'")
# 示例:多分类评估
y_true = np.array([0, 1, 2, 0, 1, 2])
y_pred = np.array([0, 2, 1, 0, 0, 1])
# 计算宏平均指标
precision, recall, f1 = precision_recall_f1(y_true, y_pred, average='macro')
print(f"宏平均 - 精确率: {precision:.4f}, 召回率: {recall:.4f}, F1: {f1:.4f}")
# 计算微平均指标
precision, recall, f1 = precision_recall_f1(y_true, y_pred, average='micro')
print(f"微平均 - 精确率: {precision:.4f}, 召回率: {recall:.4f}, F1: {f1:.4f}")
# 计算加权平均指标
precision, recall, f1 = precision_recall_f1(y_true, y_pred, average='weighted')
print(f"加权平均 - 精确率: {precision:.4f}, 召回率: {recall:.4f}, F1: {f1:.4f}")
完整 FID 计算
FID(Fréchet Inception Distance)是一种用于评估生成模型质量的指标,特别适用于生成对抗网络(GAN)。FID通过计算生成样本与真实样本在Inception网络的特征空间中的距离来评估生成模型的质量。
FID 值越低,表示两个图像分布越相似。通常,FID 值在 10-30 之间表示生成质量较好,大于 50 则表示生成质量较差。
完整 FID 计算代码:
import numpy as np
import torch
import torch.nn.functional as F
from torch import nn
from torchvision.models import inception_v3
from scipy import linalg
from tqdm import tqdm
import os
from PIL import Image
import torchvision.transforms as transforms
class InceptionV3(nn.Module):
"""预训练的InceptionV3网络,用于提取特征"""
def __init__(self, output_blocks=[3], resize_input=True, normalize_input=True):
super(InceptionV3, self).__init__()
self.resize_input = resize_input
self.normalize_input = normalize_input
self.output_blocks = sorted(output_blocks)
self.last_needed_block = max(output_blocks)
assert self.last_needed_block <= 3, 'Last possible output block is 3'
# 显式设置aux_logits=True以兼容新版本PyTorch
self.inception = inception_v3(pretrained=True, aux_logits=True)
# 移除不必要的层
for param in self.inception.parameters():
param.requires_grad = False
# 提取特征层
self.block0 = nn.Sequential(
self.inception.Conv2d_1a_3x3,
self.inception.Conv2d_2a_3x3,
self.inception.Conv2d_2b_3x3,
nn.MaxPool2d(kernel_size=3, stride=2)
)
self.block1 = nn.Sequential(
self.inception.Conv2d_3b_1x1,
self.inception.Conv2d_4a_3x3,
nn.MaxPool2d(kernel_size=3, stride=2)
)
self.block2 = nn.Sequential(
self.inception.Mixed_5b,
self.inception.Mixed_5c,
self.inception.Mixed_5d,
self.inception.Mixed_6a,
self.inception.Mixed_6b,
self.inception.Mixed_6c,
self.inception.Mixed_6d,
self.inception.Mixed_6e,
)
self.block3 = nn.Sequential(
self.inception.Mixed_7a,
self.inception.Mixed_7b,
self.inception.Mixed_7c,
)
def forward(self, x):
"""
提取InceptionV3的特征
:param x: 输入图像,Tensor类型,形状为[batch_size, 3, height, width]
:return: 特征向量
"""
if self.resize_input:
x = F.interpolate(x, size=(299, 299), mode='bilinear', align_corners=False)
if self.normalize_input:
x = 2 * x - 1 # 将输入从[0,1]归一化到[-1,1]
x = self.block0(x)
if self.last_needed_block >= 1:
x = self.block1(x)
if self.last_needed_block >= 2:
x = self.block2(x)
if self.last_needed_block >= 3:
x = self.block3(x)
# 全局平均池化
x = F.adaptive_avg_pool2d(x, (1, 1))
x = x.view(x.size(0), -1)
return x
def calculate_activation_statistics(images, model, batch_size=64, dims=2048, device='cpu'):
"""
计算激活值的均值和协方差矩阵
:param images: 图像列表或DataLoader
:param model: 特征提取模型
:param batch_size: 批处理大小
:param dims: 特征维度
:param device: 计算设备
:return: 均值和协方差矩阵
"""
model.eval()
if isinstance(images, torch.utils.data.DataLoader):
dataloader = images
else:
# 创建简单的DataLoader
dataset = torch.utils.data.TensorDataset(images)
dataloader = torch.utils.data.DataLoader(dataset, batch_size=batch_size)
act = np.empty((len(dataloader.dataset), dims))
start_idx = 0
for batch in tqdm(dataloader, desc="计算特征统计量"):
if isinstance(batch, list) or isinstance(batch, tuple):
batch = batch[0] # 处理DataLoader返回的元组
batch = batch.to(device)
with torch.no_grad():
pred = model(batch)
# 如果输出是元组,获取第一个元素
if isinstance(pred, tuple):
pred = pred[0]
# 将特征展平
pred = pred.squeeze(3).squeeze(2).cpu().numpy()
act[start_idx:start_idx + pred.shape[0]] = pred
start_idx += pred.shape[0]
mu = np.mean(act, axis=0)
sigma = np.cov(act, rowvar=False)
return mu, sigma
def calculate_frechet_distance(mu1, sigma1, mu2, sigma2, eps=1e-6):
"""
计算两个分布之间的Frechet距离
:param mu1: 第一个分布的均值
:param sigma1: 第一个分布的协方差矩阵
:param mu2: 第二个分布的均值
:param sigma2: 第二个分布的协方差矩阵
:param eps: 小常数,避免数值不稳定
:return: Frechet距离
"""
mu1 = np.atleast_1d(mu1)
mu2 = np.atleast_1d(mu2)
sigma1 = np.atleast_2d(sigma1)
sigma2 = np.atleast_2d(sigma2)
assert mu1.shape == mu2.shape, '两个均值向量的维度必须相同'
assert sigma1.shape == sigma2.shape, '两个协方差矩阵的维度必须相同'
# 计算均值差的平方
diff = mu1 - mu2
# 计算矩阵平方根
covmean, _ = linalg.sqrtm(sigma1.dot(sigma2), disp=False)
# 数值处理
if not np.isfinite(covmean).all():
msg = ('fid calculation produces singular product; '
'adding %s to diagonal of cov estimates') % eps
print(msg)
offset = np.eye(sigma1.shape[0]) * eps
covmean = linalg.sqrtm((sigma1 + offset).dot(sigma2 + offset))
# 检查虚数部分
if np.iscomplexobj(covmean):
if not np.allclose(np.diagonal(covmean).imag, 0, atol=1e-3):
m = np.max(np.abs(covmean.imag))
raise ValueError('虚部大小: %f' % m)
covmean = covmean.real
# 计算最终FID
tr_covmean = np.trace(covmean)
return (diff.dot(diff) + np.trace(sigma1) + np.trace(sigma2) - 2 * tr_covmean)
def preprocess_image(img_path, image_size=299):
"""预处理图像,用于FID计算"""
transform = transforms.Compose([
transforms.Resize((image_size, image_size)),
transforms.ToTensor(),
transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])
])
img = Image.open(img_path).convert('RGB')
return transform(img).unsqueeze(0)
def calculate_fid_given_paths(paths, batch_size=50, device='cpu', dims=2048):
"""
计算两个图像文件夹之间的FID
:param paths: 两个图像文件夹路径的列表
:param batch_size: 批处理大小
:param device: 计算设备
:param dims: 特征维度
:return: FID值
"""
assert len(paths) == 2, '需要提供两个图像文件夹路径'
model = InceptionV3([3]).to(device)
fid_values = []
for path in paths:
if not os.path.exists(path):
raise RuntimeError('路径 %s 不存在' % path)
# 加载图像
img_files = [os.path.join(path, f) for f in os.listdir(path) if
os.path.isfile(os.path.join(path, f)) and
f.lower().endswith(('.png', '.jpg', '.jpeg'))]
if not img_files:
raise RuntimeError('路径 %s 不包含图像文件' % path)
# 预处理图像
images = []
for img_path in tqdm(img_files, desc=f"加载 {path} 中的图像"):
img = preprocess_image(img_path)
images.append(img)
images = torch.cat(images, dim=0)
# 计算统计量
mu, sigma = calculate_activation_statistics(images, model, batch_size, dims, device)
fid_values.append((mu, sigma))
# 计算FID
mu1, sigma1 = fid_values[0]
mu2, sigma2 = fid_values[1]
fid = calculate_frechet_distance(mu1, sigma1, mu2, sigma2)
return fid
# 示例:计算两个图像文件夹之间的FID
paths = ['path/to/real_images', 'path/to/generated_images']
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
fid_value = calculate_fid_given_paths(paths, device=device)
print(f"FID 值: {fid_value:.4f}")
📌 感谢阅读!若文章对你有用,别吝啬互动~
👍 点个赞 | ⭐ 收藏备用 | 💬 留下你的想法 ,关注我,更多干货持续更新!
更多推荐

所有评论(0)