YOLOv5全面解析教程④:目标检测模型精确度评估
撰文 | Fengwen, BBuf
代码仓库地址,欢迎Star:
https://github.com/Oneflow-Inc/one-yolov5
1
指标评估(一些重要的定义)
IOU
(Intersection Over Union) 基于Jaccard索引,用于评估两个边界框之间的重叠程度。它需要一个真实回归框 (a ground truth bounding box)
和一个预测回归框(a predicted bounding box)
计算得到。通过应用 IOU 我们能够判断出预测结果是有效(True Positive) 或者无效(False Positive)。
也称重叠度表示计算预测回归框和真实回归框的交并比,计算公式如下:
其中:
下图可视化了真实回归框(绿色)和 预测回归框(红色)之间的IOU。
图1.1: 的计算。绿色:
,红色:
TP&FP&FN&TN
指标的一些基本概念:
TP(True Postives):分类器把正例正确的分类-预测为正例。(IOU >= 阈值)
FN(False Negatives):分类器把正例错误的分类-预测为负例。(IOU < 阈值)
FP(False Postives):分类器把负例错误的分类-预测为正例
TN(True Negatives):分类器把负例正确的分类-预测为负例(YOLOv5中没有应用到)
YOLOv5中没有应用TN的原因: TN代表的是所有可能的未正确检测到的边界框。然而在YOLO在目标检测任务中,每个网格会生成很多的预测边界框,有许多的预测边界框是没有相应的真实标签框,导致未正确检测到的边界框数量远远大于正确检测到的边界框,这就是为什么不使用TN的原因。
threshold: depending on the metric, it is usually set to 50%, 75% or 95%.
Precision
Precision 定义:模型识别相关目标的能力。分类正确的样本在所有样本中的数量比例,公式如下:
Recall
Recall 定义:是模型找到真实回归框(即标签标注的框)的能力。计算公式如下:
mAP
多标签图像分类任务中图片的标签不止一个,因此评价不能用普通单标签图像分类的标准,即mean accuracy,该任务采用的是和信息检索中类似的方法—mAP,虽然其字面意思和mean average precision看起来差不多,但是计算方法要繁琐得多,mAP 会统计所有 Confidence 值下的 PR值,而实际使用时,会设定一个 Confidence 阈值,低于该阈值的目标会被丢弃,这部分目标在统计 mAP 时也会有一定的贡献。
Confidence(置信度):在统计学中,一个概率样本的置信区间(Confidence interval)是对这个样本的某个总体参数的区间估计。置信区间展现的是这个参数的真实值有一定概率落在测量结果的周围的程度。置信区间给出的是被测量参数测量值的可信程度范围,即前面所要求的“一定概率”。这个概率也被称为置信水平。
(红色曲线代表,人为的方式将PR曲线变成单调递减,使得计算面积更容易。)
AP(Average Percision):AP为平均精度,指的是所有图片内的具体某一类的PR曲线下的面积(横轴为Recall,纵轴为Precision)。
AP衡量的是对一个类检测好坏,mAP就是对多个类的检测好坏。在多类多目标检测中,计算出每个类别的AP后,再除于类别总数,即所有类别AP的平均值,比如有两类,类A的AP值是0.5,类B的AP值是0.2,那么
=(0.5+0.2)/2=0.35。
MAP:是指所有图片内的所有类别的AP的平均值,map越高代表模型预测精度值越高。
:
是用
和
作为两轴作图后围成的面积,
表示平均,@后面的数表示判定正负样本的
阈值,其中@0.5表示IOU阈值取0.5。
:只以
的阀值的时候不一定就是好的模型,可能仅仅在0.5阀值表现得很好,在0.6,0.7...阀值表现得很差,为了更好地评估整体模型的准确度,因此计算一个模型在各个IOU值的AP(mAP)取平均值。
方法是:计算每个分类的AP,求和再平均,得到的就是mAP,它是直接把mAP当成AP,然后再把IOU值大于0.5的 ,以0.05的增量,到0.95,也就是以
的
平均值当成
,通过
的方式得到
结果。
2
目标检测中的mAP计算
yolov5计算IOU源码解析
源代码地址:
https://github.com/Oneflow-Inc/one-yolov5/blob/main/utils/metrics.py#L224-L261
# 计算两框的特定iou (DIou, DIou, CIou) def bbox_iou(box1, box2, xywh=True, GIoU=False, DIoU=False, CIoU=False, eps=1e-7): # Returns Intersection over Union (IoU) of box1(1,4) to box2(n,4) # Get the coordinates of bounding boxes 下面条件语句作用是:进行坐标转换从而获取yolo格式边界框的坐标 if xywh: # transform from xywh to xyxy (x1, y1, w1, h1), (x2, y2, w2, h2) = box1.chunk(4, 1), box2.chunk(4, 1) w1_, h1_, w2_, h2_ = w1 / 2, h1 / 2, w2 / 2, h2 / 2 b1_x1, b1_x2, b1_y1, b1_y2 = x1 - w1_, x1 + w1_, y1 - h1_, y1 + h1_ b2_x1, b2_x2, b2_y1, b2_y2 = x2 - w2_, x2 + w2_, y2 - h2_, y2 + h2_ else: # x1, y1, x2, y2 = box1 b1_x1, b1_y1, b1_x2, b1_y2 = box1.chunk(4, 1) b2_x1, b2_y1, b2_x2, b2_y2 = box2.chunk(4, 1) w1, h1 = b1_x2 - b1_x1, b1_y2 - b1_y1 w2, h2 = b2_x2 - b2_x1, b2_y2 - b2_y1 # Intersection area 获取两个框相交的面积。 """ left_line = max(b1_x1, b2_x1) reft_line = min(b1_x2, b2_x2) top_line = max(b1_y1, b2_y1) bottom_line = min(b1_y2, b2_y2) intersect = (reight_line - left_line) * (bottom_line - top_line) """ inter = (flow.min(b1_x2, b2_x2) - flow.max(b1_x1, b2_x1)).clamp(0) * \ (flow.min(b1_y2, b2_y2) - flow.max(b1_y1, b2_y1)).clamp(0) # Union Area 两个框并到面积 union = w1 * h1 + w2 * h2 - inter + eps # IoU iou = inter / union if CIoU or DIoU or GIoU: cw = flow.max(b1_x2, b2_x2) - flow.min(b1_x1, b2_x1) # convex (smallest enclosing box) width ch = flow.max(b1_y2, b2_y2) - flow.min(b1_y1, b2_y1) # convex height if CIoU or DIoU: # Distance or Complete IoU https://arxiv.org/abs/1911.08287v1 c2 = cw ** 2 + ch ** 2 + eps # convex diagonal squared rho2 = ((b2_x1 + b2_x2 - b1_x1 - b1_x2) ** 2 + (b2_y1 + b2_y2 - b1_y1 - b1_y2) ** 2) / 4 # center dist ** 2 if CIoU: # https://github.com/Zzh-tju/DIoU-SSD-pyflow.blob/master/utils/box/box_utils.py#L47 v = (4 / math.pi ** 2) * flow.pow(flow.atan(w2 / (h2 + eps)) - flow.atan(w1 / (h1 + eps)), 2) with flow.no_grad(): alpha = v / (v - iou + (1 + eps)) return iou - (rho2 / c2 + v * alpha) # CIoU return iou - rho2 / c2 # DIoU c_area = cw * ch + eps # convex area return iou - (c_area - union) / c_area # GIoU https://arxiv.org/pdf/1902.09630.pdf return iou # IoU
YOLOv5计算AP源码逐行解析
源代码地址:
https://github.com/Oneflow-Inc/one-yolov5/blob/main/utils/metrics.py#L96-L121
# 根据PR曲线计算AP def compute_ap(recall, precision): """ Compute the average precision, given the recall and precision curves # Arguments recall: The recall curve (list) precision: The precision curve (list) # Returns Average precision, precision curve, recall curve """ # Append sentinel values to beginning and end 将开区间给补上,补成闭合的区间。 mrec = np.concatenate(([0.0], recall, [1.0])) mpre = np.concatenate(([1.0], precision, [0.0])) # Compute the precision envelope """ 人为的把PR曲线变成单调递减的,例如: np.maximum(accumulate(np.array([21, 23, 18, 19, 20, 13, 12, 11]) ) => np.array([23, 23, 20, 20, 20, 13, 12, 11]) """ mpre = np.flip(np.maximum.accumulate(np.flip(mpre))) # Integrate area under curve method = 'interp' # methods: 'continuous', 'interp' if method == 'interp': # 默认采用 interpolated-precision 曲线, x = np.linspace(0, 1, 101) # 101-point interp (COCO) ap = np.trapz(np.interp(x, mrec, mpre), x) # integrate else: # 'continuous' i = np.where(mrec[1:] != mrec[:-1])[0] # points where x axis (recall) changes ap = np.sum((mrec[i + 1] - mrec[i]) * mpre[i + 1]) # area under curve return ap, mpre, mrec
3
参考文章
https://github.com/rafaelpadilla/Object-Detection-Metrics
其他人都在看
欢迎Star、试用OneFlow最新版本:https://github.com/Oneflow-Inc/oneflow/
本文分享自微信公众号 - OneFlow(OneFlowTechnology)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
Outcome VS. Output:研发效能提升中,谁更胜一筹?
2007 年,网景通信公司(Netscape)的联合创始人 Marc Andreessen 在博客The Pmarca Guide to Startups 中提出 「Product/Market Fit」 ,他写道, 「这意味着在一个良好的市场中,拥有能够满足该市场的产品。」 Product/market fit means being in a good market with a product that can satisfy that market. —— The Pmarca Guide to Startups 聚焦到产品研发环节,验证 PMF(即 Product/Market Fit)要求研发团队在找准市场定位的同时,根据市场和需求的变化及时调整战略,为用户创造价值,并实现经济效益的增长——这也是敏捷开发的基本核心。 理想情况下,敏捷团队的产品负责人(PO)、Scrum Master 和开发团队各司其职,在价值优先、增量构建和紧密协作中,持续交付可工作的软件,逐步验证市场价值和商业价值。 而现实情况往往是,需求源源不断地涌入,产品和开发团队迷失在所谓的「用户需求」和「用户反...
- 下一篇
ChatGPT数据集之谜
半个月以来,ChatGPT这把火越烧越旺。国内很多大厂相继声称要做中文版ChatGPT,还公布了上线时间表,不少科技圈已功成名就的大佬也按捺不住,携巨资下场,要创建“中国版OpenAI“。 不过,看看过去半个月在群众眼里稍显窘迫的Meta的Galactica,以及Google紧急发布的Bard,就知道在短期内打造一个比肩甚至超越ChatGPT效果的模型没那么简单。 让很多人不免感到诧异的是,ChatGPT的核心算法Transformer最初是由Google提出的,并且在大模型技术上的积累可以说不弱于OpenAI,当然他们也不缺算力和数据,但为什么依然会被ChatGPT打的措手不及? Meta首席AI科学家Yann LeCun最近抨击ChatGPT的名言实际上解释了背后的门道。他说,ChatGPT“只是巧妙的组合而已”,这句话恰恰道出了一种无形的技术壁垒。 简单来说,即使其他团队的算法、数据、算力都准备的与OpenAI相差无几,但就是没想到以一种精巧的方式把这些元素组装起来,没有OpenAI,全行业不知道还需要去趟多少坑。 即使OpenAI给出了算法上的一条路径,后来者想复现Ch...
相关文章
文章评论
共有0条评论来说两句吧...