Kornia 图像分割评估指标指南:confusion_matrix 与 mean_iou 的完整解析
- 计算机视觉
- 深度学习
- 图像处理
【免费下载链接】kornia
🐍 Geometric Computer Vision Library for Spatial AI
导读
本文以 docs/source/metrics.segmentation.rst 为主线,系统讲解 Kornia 中用于分割与分类任务评估的两个核心指标函数:kornia.metrics.confusion_matrix与kornia.metrics.mean_iou。读完本文,你将掌握这两个函数的输入输出约定、归一化与数值稳定性处理、底层实现原理,并能直接在训练/验证循环中落地使用,同时了解测试用例与基准测试对它们的验证方式。
一、指标模块概览:kornia.metrics 中的分割评估
Kornia 的kornia.metrics子模块为计算机视觉任务提供了一组评估指标,官方文档 docs/source/metrics.rst 将其划分为八类:
| 子模块 | 覆盖指标 |
|---|---|
| metrics.classification | Top-k accuracy |
| metrics.segmentation | Confusion matrix 与 mean IoU |
| metrics.detection | Mean average precision 与 box IoU |
| metrics.image_quality | PSNR 与 SSIM(2D / 3D) |
| metrics.optical_flow | Average end-point error |
| metrics.stereo | Disparity error 指标 |
| metrics.pose | 旋转/平移误差与 AUC |
| metrics.monitoring | 训练循环中的运行均值 |
其中 docs/source/metrics.segmentation.rst 正是分割与语义标注任务的核心评估页,它通过 Sphinxautofunction指令对外暴露两个函数:
confusion_matrix:计算混淆矩阵,是后续一切分割指标的基础;mean_iou:计算逐类别 Intersection-over-Union(IoU),是语义分割任务最常用的评估指标。
两个函数均在 kornia/metrics/init.py 中被导出为公开 API,可通过kornia.metrics.confusion_matrix、kornia.metrics.mean_iou直接调用,同时导出的还有检测场景使用的mean_iou_bbox。
二、confusion_matrix:从预测与真值构造混淆矩阵
2.1 函数签名与参数说明
定义位于 kornia/metrics/confusion_matrix.py:
def confusion_matrix( pred: torch.Tensor, target: torch.Tensor, num_classes: int, normalized: bool = False ) -> torch.Tensor:各参数的含义与约束如下:
pred:分类器输出的估计标签张量,形状可为(B, *)(B 为 batch,*为任意空间维度),元素必须是取值在[0, K-1]之间的整数(torch.int64);target:ground truth 标签张量,形状与pred一致,同样要求整数取值[0, K-1];num_classes:类别总数 K,必须为大于等于 2 的整数;normalized:是否返回按行归一化的混淆矩阵,默认False。
返回值是一个形状为(B, K, K)的torch.float32张量,其中[b, i, j]表示第 b 个样本中「真实类别为 i、预测为 j」的像素(或元素)计数。
2.2 输入校验
函数入口处对输入做了严格的类型与形状校验(见 kornia/metrics/confusion_matrix.py):
if not torch.is_tensor(pred) and pred.dtype is not torch.int64: raise TypeError(f"Input pred type is not a torch.Tensor with torch.int64 dtype. Got {type(pred)}")即要求pred、target均为torch.int64张量;两者形状必须一致,否则抛出ValueError(错误信息包含 "same shape");两者必须位于同一设备;num_classes必须为不小于 2 的整数,否则抛出ValueError(错误信息包含 "bigger than two")。这些校验行为在 tests/metrics/test_confusion.py 中有对应的异常测试用例。
使用建议:实际应用中,模型 softmax/logits 输出需先用
torch.argmax(..., dim=1)转换为整数标签,并确保转成torch.long(即int64)后传入。
2.3 实现原理:基于 bincount 的批量计数
实现上利用了这样一个技巧:将pred与target编码进同一个整数——pre_bincount = pred + target * num_classes,从而把「(真实类别, 预测类别)」的二维组合映射为一维索引target * K + pred。由于torch.bincount不支持批量计算(源码注释中明确写到 "NOTE: torch.bincount does not implement batched version"),实现按 batch 维度循环逐样本调用torch.bincount(pb, minlength=num_classes**2),最后堆叠并 reshape 为(B, K, K)形状(见 kornia/metrics/confusion_matrix.py)。
这一设计意味着:K 值过大时(例如超大类别数的分割数据集),num_classes**2的计数长度会显著增长,属于该实现的可扩展性边界,实际使用时应根据类别规模合理选择。
归一化逻辑也很直观(kornia/metrics/confusion_matrix.py):
if normalized: norm_val = torch.sum(confusion_mat, dim=1, keepdim=True) confusion_mat = confusion_mat / (norm_val + 1e-6)即沿真实类别维度求和后逐行归一化,并加上1e-6防止除零——此时每个元素可解释为「真实类别 i 的样本中被预测为 j 的比例」。
2.4 官方示例与测试验证
文档自带 doctest 示例(kornia/metrics/confusion_matrix.py):
>>> logits = torch.tensor([[0, 1, 0]]) >>> target = torch.tensor([[0, 1, 0]]) >>> confusion_matrix(logits, target, num_classes=3) tensor([[[2., 0., 0.], [0., 1., 0.], [0., 0., 0.]]])该例中 3 个元素中类别 0 有 2 个且全部预测正确、类别 1 有 1 个且预测正确,因此对角线为[2, 1, 0]。
测试文件 tests/metrics/test_confusion.py 覆盖了多种场景:二分类单样本与批量、三分类、四分类含缺失类别、归一化后的逐元素数值、2D 分割掩码(如4x4平面)下的完美/非完美/类别缺失情况,以及形状不匹配与num_classes过小的异常路径。其中归一化用例(tests/metrics/test_confusion.py)验证了逐行归一化的精确数值,可作为理解normalized=True行为的手工对照样例。
三、mean_iou:逐类别 IoU 与语义分割评估
3.1 函数签名与参数说明
定义位于 kornia/metrics/mean_iou.py:
def mean_iou(pred: torch.Tensor, target: torch.Tensor, num_classes: int, eps: float = 1e-6) -> torch.Tensor:pred/target:与confusion_matrix相同的约定,均为(B, *)的int64标签张量;num_classes:类别总数 K;eps:数值稳定性常数,默认1e-6,用于避免分母为零以及处理「预测与真值中都不存在的类别」。
返回形状为(B, K)的张量,[b, i]表示第 b 个样本中类别 i 的 IoU 值。
3.2 计算流程与数值细节
mean_iou内部先调用confusion_matrix得到(B, K, K)矩阵,再按如下方式逐类别计算(kornia/metrics/mean_iou.py):
conf_mat = confusion_matrix(pred, target, num_classes) sum_over_row = torch.sum(conf_mat, dim=1) # 每类的真实样本数 sum_over_col = torch.sum(conf_mat, dim=2) # 每类的预测样本数 conf_mat_diag = torch.diagonal(conf_mat, dim1=-2, dim2=-1) # 每类正确分类数 denominator = sum_over_row + sum_over_col - conf_mat_diag # 并集 = TP + FP + FN ious = (conf_mat_diag + eps) / (denominator + eps)这里的核心是经典 IoU 公式:IoU_i = TP_i / (TP_i + FP_i + FN_i),而混淆矩阵对角线正是 TP。源码注释特别说明了加eps的动机:让「预测与真值中都不出现的类别」也能被计入(其分母为 0,加上 eps 后得到 1.0 或一个非零小值),从而避免整体指标被完全跳过的类别扭曲(kornia/metrics/mean_iou.py)。
注意:返回的是(B, K)的逐类别 IoU 张量,并非标量。若需要单个数字的 mIoU,应自行在类别维度取平均(例如mean_iou(...).mean(dim=-1)),这与 benchmark 中「caller wants a scalar」的说明一致。
3.3 官方示例与测试验证
文档自带示例(kornia/metrics/mean_iou.py):
>>> logits = torch.tensor([[0, 1, 0]]) >>> target = torch.tensor([[0, 1, 0]]) >>> mean_iou(logits, target, num_classes=3) tensor([[1., 1., 1.]])预测与真值完全一致,因此所有类别 IoU 均为 1.0。
测试文件 tests/metrics/test_mean_iou.py 覆盖了:二分类完美/非完美/批量场景、四分类 2D 掩码完美分割、以及「类别在真值与预测中均缺失」的边界场景(tests/metrics/test_mean_iou.py)。后者输入中类别 0 完全缺失,最终输出为[[0.0, 1.0, 0.5, 0.5]],清晰展示了 eps 对缺失类别的处理结果。此外,与confusion_matrix一样,mean_iou对形状不匹配、num_classes过小同样会抛出ValueError(tests/metrics/test_mean_iou.py)。
四、延伸:mean_iou_bbox 与检测场景的框级 IoU
虽然metrics.segmentation.rst文档页本身只列出confusion_matrix与mean_iou,但同文件 kornia/metrics/mean_iou.py 还实现了检测任务常用的mean_iou_bbox,它计算两组边界框笛卡尔积的两两 IoU:
def mean_iou_bbox(boxes_1: torch.Tensor, boxes_2: torch.Tensor, box_format: str = "xyxy") -> torch.Tensor:boxes_1/boxes_2:形状为(N, 4)的边界框张量;box_format:支持三种格式——'xyxy'(左上右下,默认)、'xywh'(左上角 + 宽高)、'cxcywh'(中心点 + 宽高);- 返回形状为
(N1, N2)的 IoU 矩阵。
内部通过_convert_boxes_to_xyxy(kornia/metrics/mean_iou.py)统一转换到 xyxy 格式,再以 broadcast 技巧同时计算交叠区域与并集面积。由于该函数读取数据做合法性校验,源码中使用is_exporting()(来自kornia.core.utils)在导出(如 TorchScript/ONNX)场景下跳过数据读取类校验,保证图捕获可用(kornia/metrics/mean_iou.py)。
测试 tests/metrics/test_mean_iou.py 验证了三种格式等价性、非法格式报错以及默认格式为xyxy等行为。该函数已进入公开 API 表面(见 tests/api_surface.json),可通过kornia.metrics.mean_iou_bbox调用。
五、实战:在分割训练循环中集成 mean_iou
以下示例展示了如何将两个指标组合进一个典型的 PyTorch 验证循环,覆盖「argmax 转标签 → 计算混淆矩阵与逐类别 IoU → 汇总 mIoU」的完整链路:
import torch import kornia.metrics as KMetrics def evaluate_segmentation(model, dataloader, num_classes, device): model.eval() conf_mat_total = None with torch.no_grad(): for images, labels in dataloader: images, labels = images.to(device), labels.to(device) # 1. 前向得到 logits,并转换为 int64 标签 logits = model(images) # (B, C, H, W) pred = torch.argmax(logits, dim=1).long() # (B, H, W) # 2. 逐类别 IoU(返回 (B, K)) ious = KMetrics.mean_iou(pred, labels, num_classes, eps=1e-6) # 3. 混淆矩阵(可累积用于后续分析) conf_mat = KMetrics.confusion_matrix(pred, labels, num_classes) conf_mat_total = conf_mat if conf_mat_total is None else conf_mat_total + conf_mat # 4. 每个 batch 的 mIoU(标量) batch_miou = ious.mean(dim=-1).item() print(f"batch mIoU: {batch_miou:.4f}") # 全量数据的整体 mIoU:直接从累计混淆矩阵出发,与逐批求均值略有差异, # 以累计混淆矩阵为准更接近全局评估口径 sum_over_row = conf_mat_total.sum(dim=1) sum_over_col = conf_mat_total.sum(dim=2) diag = torch.diagonal(conf_mat_total, dim1=-2, dim2=-1) denom = sum_over_row + sum_over_col - diag global_iou = (diag + 1e-6) / (denom + 1e-6) # (B, K) return global_iou.mean(dim=-1)关键注意点:
- 两个函数都要求
int64输入,务必在调用前完成argmax与.long()转换; pred与target形状、设备必须完全一致,否则会触发校验异常;mean_iou输出逐类别 IoU,需要自行在类别维取平均得到 mIoU 标量;- 若数据集存在从未出现的类别,
eps会保证这些类别的分母不为零,从而让整体 mIoU 不被异常值污染。
六、性能验证与基准测试视角
仓库的基准测试脚本 benchmarks/metrics/flagship.py 将mean_iou列为分割评估循环中最常计算的指标之一,与图像质量指标psnr、ssim并列(OPS = ("psnr", "ssim", "mean_iou"))。该脚本在 21 类(NUM_CLASSES = 21)的(B, H, W)标签图上以「80% 预测与真值一致」的方式构造数据(benchmarks/metrics/flagship.py),保证每个类别都有非平凡的 IoU,从而公平衡量指标吞吐(单位img/s)。运行方式如下:
python benchmarks/metrics/flagship.py --batches 1,8,32 --size 256 --device cpu python benchmarks/metrics/flagship.py --device cuda --compile --json metrics_cuda.json基准注释明确说明:由于mean_iou在 scikit-image 与 OpenCV 中没有对应实现,该指标仅以 Kornia 的 eager 与torch.compile编译两种模式参与评测(benchmarks/metrics/flagship.py),这也侧面印证了mean_iou属于 Kornia 自研的差异化能力。
七、小结
kornia.metrics的分割指标接口设计小而精:
confusion_matrix以「pred + target * K编码 + 逐样本 bincount」的巧妙实现,输出(B, K, K)的批量混淆矩阵,支持按行归一化;mean_iou基于混淆矩阵的对角线与行列和,直接给出(B, K)逐类别 IoU,并通过eps稳健处理缺失类别;- 二者共享严格的输入校验(int64、同形状、同设备、K≥2),配合 tests/metrics/test_confusion.py 与 tests/metrics/test_mean_iou.py 的完整测试矩阵,可放心用于训练/验证循环。
掌握这两个函数,即可在 Kornia 生态中低成本地完成语义分割模型的标准评估,并与同一模块下的psnr、ssim、AEPE等指标组成统一的评估管线(总览见 docs/source/metrics.rst)。
- 计算机视觉
- 深度学习
- 图像处理
【免费下载链接】kornia
🐍 Geometric Computer Vision Library for Spatial AI
相关推荐
AutoTrain Advanced图像分割评估指标:mIoU与Dice系数详解
AutoTrain Advanced图像分割评估指标:mIoU与Dice系数详解 在深度学习图像分割任务中,准确评估模型性能至关重要。AutoTrain Adv
机器学习深度学习NLP计算机视觉微调后端图像分割模型评估指标完全指南:IoU与F-score计算方法详解
图像分割模型评估指标完全指南:IoU与F score计算方法详解 在图像分割领域,准确评估模型性能是至关重要的环节。Segmentation Models库提供
计算机视觉深度学习人工智能eslint-import-resolver-typescript性能优化:让大型TypeScript项目的ESLint检查飞起来
eslint import resolver typescript性能优化:让大型TypeScript项目的ESLint检查飞起来 eslint import
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考