目标检测、语义分割性能指标

目标检测

模型训练主要有以下几个性能指标和术语,这边做下记录:

IOU(Intersection over Union):即交并比,看下面这张图就非常直观了~
在这里插入图片描述
三种特殊情况:
1、预测框 = 真实框,可得 IoU = 1,不难看出IoU值越高,预测越准
2、预测框 与 真实框 交集为0,即挨不着,IoU值为0
3、一般IoU = 0.5时,视为预测的框有效,并往上分IoU为0.6、0.7、0.8、0.9值时来讨论对应的召回率,下面会讲解召回率~

引用网上的一个例子,假设我们手上有60个正样本,40个负样本,我们要找出所有的正样本,算法查找出50个(正样本),其中只有40个是真正的正样本:
必须参考这张图:
在这里插入图片描述
那就是一道填空题:
在这里插入图片描述

True positives: 将正类预测为正类数 40
True negatives: 将负类预测为负类数 30
False positives: 将负类预测为正类数 10
False negatives: 将正类预测为负类数 20

标红是容易混淆的,记住True打头的就是预测对了~

引出recall(召回率、查全率)

召回率是针对我们原来的样本而言的,它表示的是样本中的正例有多少被预测正确了
两种可能:
1、一种是把原来的正类预测成正类(TP)
2、另一种就是把原来的正类预测为负类(FN)
在这里插入图片描述
继续看图,一目了然,就是:紫色/(紫色+黄色)
在这里插入图片描述

precision(精度、查准率):

精确率是针对我们预测结果而言的,它表示的是预测为正的样本中有多少是真正的正样本。那么预测为正就有两种可能了,一种就是把正类预测为正类(TP),另一种就是把负类预测为正类(FP),也就是:
在这里插入图片描述
黄/(黄+棕色)
在这里插入图片描述

其实就是分母不同,一个分母是预测为正的样本数,另一个是原来样本中所有的正样本数

ROC视频教程:
http://www.iqiyi.com/w_19rxnhzlnt.html#curid=16898978309_60b6ca8c563c86ce3aec489fffa14170
在这里插入图片描述
P-R曲线:
都知道P-R曲线就是横轴是Recall,纵轴是Percision,也知道Recall、Percision这两个怎么求,曲线长下面这样:
在这里插入图片描述
先来看下Recall 和 Percision 的关系吧~
引用西瓜书的说法:
P和R是一对矛盾的度量,一般来说,P高时,R往往偏低,而R高时,P往往偏低。
举个栗子:
若希望将好瓜尽可能多地选出来,则可通过增加选瓜的数量来实现,如果将所有西瓜都选上,那么所有的好瓜也必然都被选上了,但这样P就会较低;若希望选出的瓜中好瓜比例尽可能高,则可只挑选最有把握的瓜,但这样就难免会漏掉不少好瓜,使得R较低。通常只有在一些简单任务重,才可能使P和R都很高。(西瓜华语录)

再举个具体计算画P-R曲线的例子:
step1:模型训练好啦~
step2:那我们开始测试吧~

二分类问题(预测是car或不是):
描述:有20个测试样本,送入模型,得出的分数(中间列),真正的标签(右边列)
在这里插入图片描述
然后我们按score进行从高到低排序:
在这里插入图片描述
好,有了这张表格,就来计算所谓的top-1到top-N,这里我们就计算一下top-5,让大家明白啥叫top-5(其实很简单)

Top-5:
看到上面的表格没,取score最高的前5个,意思就是这前5个咱们的学习器都认为其label是1,即positive,如下:
在这里插入图片描述
我想TP、FP、FN、TN的计算应该都十分清楚啦~
那就开始计算吧,应该是能懂吧,对照表格数一数就知道了,把表格再放一下:
在这里插入图片描述
计算过程:
在这里插入图片描述
(R,P)对应在P-R曲线上:
在这里插入图片描述
那其他的什么top-3(n),啥的就是取前3个(n)得分高的,说他们的label是1(positive),然后计算相应R和P,又可得到一组(R,P)值。
在这里插入图片描述
mAP(mean Average Precision)
接下来说说AP的计算,此处参考的是PASCAL VOC CHALLENGE的2010年之前计算方法。首先设定一组阈值,[0, 0.1, 0.2, …, 1]。然后对于recall大于每一个阈值(比如recall>0.3),我们都会得到一个对应的最大precision。这样,我们就计算出了11个precision。AP即为这11个precision的平均值。这种方法英文叫做11-point interpolated average precision。​

当然PASCAL VOC CHALLENGE自2010年后就换了另一种计算方法。新的计算方法假设这N个样本中有M个正例,那么我们会得到M个recall值(1/M, 2/M, …, M/M),对于每个recall值r,我们可以计算出对应(r’ >= r)的最大precision,然后对这M个precision值取平均即得到最后的AP值。计算方法如下:
在这里插入图片描述
相应的Precision-Recall曲线(这条曲线是单调递减的)如下:
在这里插入图片描述
AP衡量的是学出来的模型在每个类别上的好坏,mAP衡量的是学出的模型在所有类别上的好坏,得到AP后mAP的计算就变得很简单了,就是取所有AP的平均值。
(摘自博客:https://blog.csdn.net/qq_41994006/article/details/81051150)

看懂了!很棒!!!

召回率与IoU曲线:
在这里插入图片描述
直观的想一下,IoU设定阈值越高,能够满足的样本是越少的,即TP小了,但是原样本的正样本数不变,故recal值变小,如上图所示。

语义分割

看完上面目标检测相关内容,你是否消化了?这里就一并把语义分割模型性能评价指标附上:

首先,明确一下语义分割是对图片 像素级 的分类,标注的边框就不是矩形框了,而是多边形

先不放出公式,举个栗子吧~

假设:输入是一张图片,分割图像上的积水区域,也就是说模型要判断图片上每个像素点是背景or积水区域,好,那我们简单的拿5个点像素的求求看:

    y_t = np.array([0, 1, 0, 1, 1])     # 真实数据(0:背景,1:积水)
    y_p = np.array([0, 0, 0, 1, 0])     # 预测数据
    # 进而求得 TP, TN, FP, FN(这个很好求,不多说了吧)
    TP = 1, TN = 2, FP = 0, FN = 2
    # 有了这些,那你岂不是分分钟求出 acc、recall、precision、f1_socre
    acc = 0.6、recall = 0.33333334、
    precision = 0.9999999、f1_socre = 0.49999997 
    # 自己检查一下对不对,有没完全掌握

混淆矩阵:顾名思义就是混淆了嘛,把一堆“金桔”部分认成“乒乓球”,有的还认对了,你品你细品,官方释义请百度。还是上面的例子,画出混淆矩阵:
在这里插入图片描述
有了混淆矩阵,那我们就可以轻松计算iou啦~
back:
iou = (对角线值)/(所在行值总和 + 所在列值总和 - 对角线值)
即:2 / (2 + 0 + 2 + 2 - 2) = 1/2
同理 water:
1 / (2 + 1 + 1 + 0 - 1) = 1 / 3

mean_iou = (1/2 + 1/3)/2 = 5/12

keras完整代码:

import keras.backend as K
import numpy as np
import seaborn as sns
from sklearn.metrics import confusion_matrix
import matplotlib.pyplot as plt
import tensorflow as tf


# 计算 TP, TN, FP, FN
def cal_base(y_true, y_pred):
    y_pred_positive = K.round(K.clip(K.constant(y_pred), 0, 1))
    y_pred_negative = 1 - y_pred_positive

    y_positive = K.round(K.clip(K.constant(y_true), 0, 1))
    y_negative = 1 - y_positive

    TP = K.sum(y_positive * y_pred_positive)
    TN = K.sum(y_negative * y_pred_negative)

    FP = K.sum(y_negative * y_pred_positive)
    FN = K.sum(y_positive * y_pred_negative)

    return TP, TN, FP, FN


# 计算准确率
def acc(y_true, y_pred):
    TP, TN, FP, FN = cal_base(y_true, y_pred)
    ACC = (TP + TN) / (TP + FP + FN + TN + K.epsilon())
    return ACC


# 计算召回率
def recall(y_true, y_pred):
    TP, TN, FP, FN = cal_base(y_true, y_pred)
    Recall = TP / (TP + FN + K.epsilon())
    return Recall


# 计算查准率
def precision(y_true, y_pred):
    TP, TN, FP, FN = cal_base(y_true, y_pred)
    Precision = TP / (TP + FP + K.epsilon())
    return Precision


# F1得分(由 召回率、精度 延伸出来)
def f1_socre(y_true, y_pred):
    SE = recall(y_true, y_pred)
    PC = precision(y_true, y_pred)
    F1 = 2 * SE * PC / (SE + PC + K.epsilon())
    return F1


# 计算某个类别iou,label代表类别(二分类:0, 1)
def iou(y_true, y_pred, label: int):
    y_true = K.cast(K.equal(y_true, label), K.floatx())
    y_pred = K.cast(K.equal(y_pred, label), K.floatx())
    intersection = K.sum(y_true * y_pred)
    union = K.sum(y_true) + K.sum(y_pred) - intersection
    return K.switch(K.equal(union, 0), 1.0, intersection / union)


# 计算miou
def mean_iou(y_true, y_pred, total):
    miou = 0
    for i in range(total):
        miou += iou(y_true, y_pred, i).eval()
    return miou/total


# 绘制混淆矩阵
def draw_confusion_matrix(y_true, y_pred, labels_name):
    sns.set()
    f, ax = plt.subplots()
    c_m = confusion_matrix(y_true, y_pred, labels=[0, 1])
    print("混淆矩阵:")
    print(c_m)
    sns.heatmap(c_m, annot=True, ax=ax)
    num_local = np.array(range(len(labels_name)))
    plt.xticks(num_local, labels_name)  # 将标签印在x轴坐标上
    plt.yticks(num_local, labels_name)  # 将标签印在y轴坐标上
    ax.set_title('confusion matrix')  # 标题
    ax.set_xlabel('predict')  # x轴
    ax.set_ylabel('true')  # y轴
    plt.show()


if __name__ == "__main__":
    y_t = np.array([0, 1, 0, 1, 1])     # 真实数据(0:背景,1:积水)
    y_p = np.array([0, 0, 0, 1, 0])     # 预测数据
    labels_name = ['back', 'water']     # 背景、积水区域
    with tf.Session():
        print("acc:%s", acc(y_t, y_p).eval())
        print("recall:%s", recall(y_t, y_p).eval())
        print("precision:%s", precision(y_t, y_p).eval())
        print("f1_socre:%s", f1_socre(y_t, y_p).eval())
        print("iou:%s", iou(y_t, y_p, 1).eval())   # 计算类别1的iou
        print("mean_iou:%s", mean_iou(y_t, y_p, 2))

    draw_confusion_matrix(y_t, y_p, labels_name)       # 绘制混淆矩阵
  • 7
    点赞
  • 40
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

龚大龙

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值