DeepLearning - Techniques
记录一些深度学习中使用的零散小技巧📖

什么是IOU?

IOU (Intersection over Union) 是一个常用的指标,用于评估图像分割或目标检测任务的性能。它计算了预测的边界框或分割区域与实际的边界框或分割区域的重叠部分占总区域的比例。具体来说,IOU 是实际区域与预测区域的交集面积与并集面积之比。

IOU计算示意图

公式如下:

IOU=Intersection AreaUnion Area\text{IOU} = \frac{\text{Intersection Area}}{\text{Union Area}}

其中:

  • Intersection Area 是预测区域与实际区域的重叠部分。
  • Union Area 是预测区域和实际区域的并集部分。

什么是 mIOU?

mIOU (Mean Intersection over Union) 是对多个样本的IOU进行平均,以评估模型在整个数据集上的表现。它通过计算所有样本的IOU,并取平均值来得到。

mIOU 的计算公式如下:

mIOU=1Ni=1NIOUi\text{mIOU} = \frac{1}{N} \sum_{i=1}^{N} \text{IOU}_i

其中:

  • NN 是样本的数量。
  • IOUi\text{IOU}_i 是第 ii 个样本的 IOU 值。

什么是 oIOU?

oIOU (Overall Intersection over Union) 是通过累计所有样本的交集面积和并集面积来计算的IOU。与 mIOU 不同的是,oIOU 直接计算总的交集面积和并集面积的比例,而不是对单个样本的IOU进行平均。

oIOU 的计算公式如下:

oIOU=i=1NIntersection Areaii=1NUnion Areai\text{oIOU} = \frac{\sum_{i=1}^{N} \text{Intersection Area}_i}{\sum_{i=1}^{N} \text{Union Area}_i}

其中:

  • NN 是样本的数量。
  • Intersection Areai\text{Intersection Area}_iUnion Areai\text{Union Area}_i 分别是第 ii 个样本的交集面积和并集面积。

IOU、mIOU 和 oIOU 的计算代码

下面是一个用于计算 IOU、mIOU 和 oIOU 的代码示例,实现了一个测试器类,使用方法是初始化后传入每次的预测和目标mask,会计算出iou,最后调用evalute方法可以输出整个测试数据集的mIOU和oIOU值

实现代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
import numpy as np
import torch

class Evaluator():
def __init__(self):
self.counters_by_iou = {iou: 0 for iou in [0.5, 0.6, 0.7, 0.8, 0.9]}
self.total_intersection_area = 0
self.total_union_area = 0
self.ious_list = []
pass
def compute_mask_iou(self, outputs: torch.Tensor, labels: torch.Tensor, EPS=1e-6):
assert outputs.shape[0] == 1; assert outputs.shape == labels.shape; assert len(outputs.shape) == 3
outputs = outputs.int(); labels = labels.int()
intersection = (outputs & labels).float().sum((1, 2)) # Will be zero if Truth=0 or Prediction=0
union = (outputs | labels).float().sum((1, 2)) # Will be zero if both are 0
iou = (intersection + EPS) / (union + EPS) # EPS is used to avoid division by zero

iou, intersection, union = iou.item(), intersection.item(), union.item()

for iou_threshold in self.counters_by_iou.keys():
if iou > iou_threshold:
self.counters_by_iou[iou_threshold] += 1

self.total_intersection_area += intersection
self.total_union_area += union
self.ious_list.append(iou)

return iou, intersection, union

def evaluate(self):
num_samples = len(self.ious_list)

if num_samples == 0:
print("No samples to evaluate.")
return

precision_at_k = np.array(list(self.counters_by_iou.values())) / num_samples
overall_iou = self.total_intersection_area / self.total_union_area
mean_iou = np.mean(self.ious_list)

print("Evaluation Result")
iou_thresholds = [0.5, 0.6, 0.7, 0.8, 0.9]
for iou, prec in zip(iou_thresholds, precision_at_k):
print(f"IoU: {iou:.2f}, Precision: {prec:.4f}")
print("========================================")
print(f"Overall IoU: {overall_iou:.4f}")
print(f"Mean IoU: {mean_iou:.4f}")

结论

IOU 是评估图像分割和目标检测任务性能的重要指标。通过计算每个样本的 IOU,然后求平均值可以得到 mIOU,而通过计算所有样本的总交集和总并集的比例可以得到 oIOU。理解和计算这些指标有助于全面评估模型在分割任务中的表现。上述代码提供了一个计算 IOU、mIOU 和 oIOU 的实现示例,可以帮助你在实际任务中进行评估。


本站由 @anonymity 使用 Stellar 主题创建。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。