600字范文,内容丰富有趣,生活中的好帮手!
600字范文 > <计算机视觉 六> 深度学习目标检测模型的评估标准

<计算机视觉 六> 深度学习目标检测模型的评估标准

时间:2022-01-14 05:49:47

相关推荐

<计算机视觉 六> 深度学习目标检测模型的评估标准

鼠标点击下载 项目源代码免费下载地址

<计算机视觉一> 使用标定工具标定自己的目标检测

<计算机视觉二> labelme标定的数据转换成yolo训练格式

<计算机视觉三> pytorch读取自己标定的数据集

<计算机视觉四> pytorch版yolov3网络搭建

<计算机视觉 五> 模型训练时候标签数据的变换

<计算机视觉 六> 深度学习目标检测模型的评估标准

<计算机视觉 七> 模型训练模块的代码

在模训练的时候我们总是想知道自己训练的模型是好是坏,我们最早接触的一个指标就是loss损失,很自然的一看到loss非常小就觉得模型训练的已经非常好了。loss值固然是一个指标,但是实际工程中loss值变小只能说明你的模型正在收敛,loss值浮动不变也只是表征模型已经在拟和的差不多。但单一的loss并不能描述模型的好坏,想让loss好看很多时候在loss值上除以一个非常大的数即可。因此需要有一些比较客观的评价标准。

先从数据集上划分,一般训练需要三组数据,训练集、验证集、测试集。训练集用于模型训练,也就是所谓的炼丹。验证集参与模型训练时候的阶段性的检测训练的模型质量。测试集完全不参与训练。用模型直接推理检测结果。这三个数据集中训练集和验证集是需要有标签数据的,测试集可以没有标签数据。

分类任务的只需要评估下验证集中模型推理的分类和真实样本的分类的标签loss即可。这里简单给出一些统计学名词概念,这里不做展开详细讲解有兴趣(非常有必要)的可以查阅相关资料或者其他博主的讲解。正样本、负样本、召回、精度、准确度

#预正 预负 召回率

# 实正 TP FN → TP/(TP + FN)

# 实负 FP TN

# ↓↘ 准确率

# 精度 TP/(TP + FP) (TP + TN)/(TP + TN + FN +FP)

在网络框架中当训练到一定的轮次以后需要评估下当前模型的指标。需要对样本进行统计。先上数据统计的大致流程:

给出上述模型的代码具体实现

def get_batch_statistics(outputs, targets, iou_threshold):'''@description:一般用于测试训练结果,统计当前batch下的经过NMS的outputs和真实目标的iou值这个过滤只是针对box的iou和outputs的目标是否是存在与targets中,并不针对label的位置进行过滤.@Args:outputs :([None,[[x,y,x,y,conf,cls_val, cls_id]...],None,]) model(img)经过NMS后的结果targets :([num][batch_id, label_id,x,y,w,h])标记的真实box信息@Return:batch_metrics : ([true_positives, pred_confs, pred_labels]..)true_positives: 经过iou计算大于阈值位置给1的编号pred_confs : 预测的目标conf信息pred_labels : 预测的class label信息'''batch_metrics = []# 遍历每个batch,获取每个image的推理结果for image_i in range(len(outputs)):if outputs[image_i] is None: # 未检测到结果,继续下个imagecontinue output = outputs[image_i] # 获取当前batch的信息pred_boxes = output[:, :4] # 预测xyxy信息pred_confs = output[:, 4]# 有无目标的confpred_labels = output[:, -1] # 预测的分类id编号# 依据output检测到的box框数量创建一个全0的数据 i.e [0,0,0,0]true_positives = np.zeros(output.size(0)) # 依据image_i的编号过滤下targets的数据,即找到targets中和outputs对应的batchannotations = targets[targets[:, 0] == image_i][:, 1:]target_labels = annotations[:, 0] if len(annotations) else []target_boxes = annotations[:, 1:] if len(annotations) else []# 如果过滤后的annotations存在,进行匹配信息if len(annotations): detected_boxed_index = [] # 用于存放预测到的box索引# 遍历当前预测到的每个box和labelfor pred_i, (pred_box, pred_label) in enumerate(zip(pred_boxes, pred_labels)):# 如果所有的真实targtes都被找到了就结束遍历if len(detected_boxed_index) == len(annotations):break# 如果预测的label根本不再targets中就继续下一组数据if pred_label not in target_labels:continue# 计算每个pred_box和真实target的iou值,# iou大于阈值并且真实的target没有被预测到的将会让当前的true_positives 为1# 此时true_positives 类似[0,1,0,0,0]iou, box_index = bbox_iou(pred_box.unsqueeze(0), target_boxes).max(0)if iou >= iou_threshold and box_index not in detected_boxed_index:true_positives[pred_i] = 1detected_boxed_index.append(box_index)batch_metrics.append([true_positives, pred_confs, pred_labels])return batch_metricsdef ap_per_class(true_positives, pred_confs, pred_labels, target_labels):'''@description:计算每个class的ap信息@Args:true_positives : ([0,0,1,1,0,...])由get_batch_statistics统计的正位置编号pred_confs: ([0.4,0.6....])经过NMS的目标conf信息和true_positives一一对应pred_labels : ([1,0,3,0,..])所有的预测labels和true_positives一一对应target_labels : ([1,2,3,0,..])所有的真实labels和true_positives一一对应@Return:'''# 这里必须要经过pred_confs降序排序,保证后续recall和precision的曲线平滑sort_i = np.argsort(-pred_confs) true_positives = true_positives[sort_i]pred_confs= pred_confs[sort_i]pred_labels= pred_labels[sort_i]# 统计所有类别的个数,即有多杀哦个classunique_classes = np.unique(target_labels)ap, p, r = [], [], []# 遍历每个unique_classes的分类,统计每个class的各项指标for c in tqdm.tqdm(unique_classes, desc= "计算AP中..."):i = (pred_labels == c) # 预测中为当前c的位置 [True,True,...,False]n_gt = (target_labels == c).sum() # 当前真实的c一共有多少个n_p = i.sum() # 当前预测的c一共有多少个if n_p == 0 and n_gt == 0:continueif n_p == 0 or n_gt == 0:ap.append(0)p.append(0)r.append(0)else:# 预正 预负召回率# 实正 TP FN → TP/(TP + FN)# 实负 FP TN# ↓ ↘ 准确率 # 精度 TP/(TP + FP) (TP + TN)/(TP + TN + FN +FP)# 计算 FPc和TPctpc = (true_positives[i]).cumsum()fpc = (1 - true_positives[i]).cumsum()# 计算 recallrecall_curve = tpc / (n_gt + 1e-16)r.append(recall_curve[-1])# 计算precisionprecision_curve = tpc / (tpc + fpc)p.append(precision_curve[-1])# 计算每个c的PR曲线下面积,即每个c的apapc = compute_ap(recall_curve, precision_curve)ap.append(apc)# 计算f1得分p, r, ap = np.array(p), np.array(r), np.array(ap)f1 = 2 * p * r / (p + r + 1e-16)return p, r, ap, f1, np.int32(unique_classes)def compute_ap(recall, precision):'''@description:依据recall曲线和precision曲线计算PR曲线的面积(ap)@Args:recall : ap_per_class中计算的recall_curveprecision : ap_per_class中计算的precision_curve@Return:ap : 每个class的ap值'''# 1 首先对数据进行扩展填充mrec = np.concatenate(([0,0], recall, [1.0])) # 召回的终点为1表示全部都被检测到mpre = np.concatenate(([0,0], precision, [0.0]))# 首尾精度都给0值# 2 对精度曲线值进行过滤,由于ap_per_class的cumsum操作使得后面的值肯定小于前面的值for i in range(mpre.size - 1, 0, -1): #反向排序mpre[ i -1] = np.maximum(mpre[i - 1], mpre[i])# 3 过滤掉recall中相同的值,计算面积的时候需要过滤,画图展示则不用i = np.where( mrec[1:] != mrec[:-1])[0]# 4 计算曲线PR面积ap = np.sum(( mrec[i + 1] - mrec[i]) * mpre[i + 1])return ap

下面将要围绕训练脚本中一些注意事项进行介绍

鼠标点击下载 项目源代码免费下载地址

<计算机视觉一> 使用标定工具标定自己的目标检测

<计算机视觉二> labelme标定的数据转换成yolo训练格式

<计算机视觉三> pytorch读取自己标定的数据集

<计算机视觉四> pytorch版yolov3网络搭建

<计算机视觉 五> 模型训练时候标签数据的变换

<计算机视觉 六> 深度学习目标检测模型的评估标准

<计算机视觉 七> 模型训练模块的代码

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。