Kornia 图像分割评估指标指南:confusion_matrix 与 mean_iou 的完整解析

发布时间:2026/11/2 10:57:10
Kornia 图像分割评估指标指南:confusion_matrix 与 mean_iou 的完整解析
  • 计算机视觉
  • 深度学习
  • 图像处理

【免费下载链接】kornia

🐍 Geometric Computer Vision Library for Spatial AI

项目地址:https://gitcode.com/GitHub_Trending/ko/kornia
点击查看免费下载

导读

本文以 docs/source/metrics.segmentation.rst 为主线,系统讲解 Kornia 中用于分割与分类任务评估的两个核心指标函数:kornia.metrics.confusion_matrix与kornia.metrics.mean_iou。读完本文,你将掌握这两个函数的输入输出约定、归一化与数值稳定性处理、底层实现原理,并能直接在训练/验证循环中落地使用,同时了解测试用例与基准测试对它们的验证方式。

一、指标模块概览:kornia.metrics 中的分割评估

Kornia 的kornia.metrics子模块为计算机视觉任务提供了一组评估指标,官方文档 docs/source/metrics.rst 将其划分为八类:

子模块覆盖指标
metrics.classificationTop-k accuracy
metrics.segmentationConfusion matrix 与 mean IoU
metrics.detectionMean average precision 与 box IoU
metrics.image_qualityPSNR 与 SSIM(2D / 3D)
metrics.optical_flowAverage end-point error
metrics.stereoDisparity 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)

关键注意点:

  1. 两个函数都要求int64输入,务必在调用前完成argmax与.long()转换;
  2. pred与target形状、设备必须完全一致,否则会触发校验异常;
  3. mean_iou输出逐类别 IoU,需要自行在类别维取平均得到 mIoU 标量;
  4. 若数据集存在从未出现的类别,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

项目地址:https://gitcode.com/GitHub_Trending/ko/kornia
点击查看免费下载
上一篇:D2DX:如何让20年老游戏《暗黑破坏神2》在现代电脑上焕发新生
下一篇:3分钟掌握AI图像增强:Real-ESRGAN-GUI让模糊照片重获新生

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考