在YOLO-Fastest和YOLO-FastestV2中添加评价指标acc@iou

1. 引言

         YOLO-Fastest是第一个把YOLO系列目标检测算法的参数量降到1M以内的检测算法,模型精度相对于其他YOLO系列有所降低,但是参数量大幅下降,不足1M,因此很适合移动平台的模型部署。本文将目标检测算法评价指标acc@iou添加到YOLO-Fastest和YOLO-FastestV2中的评价指标中。

        YOLO-Fastest官方GitHub:https://github.com/dog-qiuqiu/Yolo-Fastest

        YOLO-FastestV2官方GitHub:https://github.com/dog-qiuqiu/Yolo-FastestV2

2. 步骤

        由于V1和V2源码非常相似,本文只对V2版本的代码进行改进

1. 在utils/utils.py文件中,新建函数evaluation_iou,此函数是evaluation函数的改进版本,新增了计算acc@iou的模块,并将验证集的这个指标输出。代码如下:

def evaluation_iou(val_dataloader, cfg, model, device, conf_thres = 0.01, nms_thresh = 0.4, iou_thres = 0.5):

    labels = []
    sample_metrics = []  # List of tuples (TP, confs, pred)
    pbar = tqdm(val_dataloader)


    global thres_lst
    global hit_lst
    global num
    thres_lst = [0.5,0.55,0.6,0.65,0.7,0.75,0.8,0.85,0.9,0.95]
    hit_lst = {}
    num = 0
    for thres in thres_lst:
        hit_lst[thres] = 0

    for imgs, targets in pbar:  #images (64,3,224,224) targets(79,6)
        imgs = imgs.to(device).float() / 255.0
        targets = targets.to(device)       

        # Extract labels
        labels += targets[:, 1].tolist()  #读取所有的分类
        # Rescale target
        targets[:, 2:] = xywh2xyxy(targets[:, 2:])
        targets[:, 2:] *= torch.tensor([cfg["width"], cfg["height"], cfg["width"], cfg["height"]]).to(device)

        #对预测的anchorbox进行nms处理
        with torch.no_grad():
            preds = model(imgs)

            #特征图后处理:生成anchorbox
            output = handel_preds(preds, cfg, device)
            output_boxes = non_max_suppression(output, conf_thres = conf_thres, iou_thres = nms_thresh)

        sample_metrics += get_batch_statistics_iou(output_boxes, targets, iou_thres, device)
        pbar.set_description("Evaluation model:") 

    acc_mean = 0
    for thres in hit_lst.keys():
        hit_lst[thres] /= num
        acc_mean += hit_lst[thres]
    acc_mean /= len(hit_lst)

    acc_log = {}
    for p in ['0.5','0.75','0.95','acc_mean']:
        acc_log[p] = 0
    acc_log['0.5'] = hit_lst[0.5]
    acc_log['0.75'] = hit_lst[0.75]
    acc_log['0.95'] = hit_lst[0.95]
    acc_log['acc_mean'] = acc_mean

    acc_info="<<<<<<<<<Validation>>>>>>>>>>\nACC@iou0.5: {}\nACC@iou0.75: {}\nACC@iou0.95: {}\nACC@iou0.5:0.95: {}\n".format(
               hit_lst[0.5],hit_lst[0.75],hit_lst[0.95], acc_mean)
    #LOGGER.info(acc_info)
    print("acc@iou result>>>>>>>>>>>>>>>>>>>>>>\n", acc_log)
    if len(sample_metrics) == 0:  # No detections over whole validation set.
        print("---- No detections over whole validation set ----")
        return None

    # Concatenate sample statistics
    true_positives, pred_scores, pred_labels = [np.concatenate(x, 0) for x in list(zip(*sample_metrics))]
    metrics_output = ap_per_class(true_positives, pred_scores, pred_labels, labels)
    
    return metrics_output

2. 还是在上一步的代码中新增函数get_batch_statistics_iou,用于计算每一个batch_size的iou值,并返回给全局变量hit_lst中。代码如下:

def get_batch_statistics_iou(outputs, targets, iou_threshold, device):
    """ Compute true positives, predicted scores and predicted labels per sample """
    batch_metrics = []

    global num

    for sample_i in range(len(outputs)):  #对个batch中的每个output进行分析
        num += 1
        if outputs[sample_i] is None:
            continue

        output = outputs[sample_i]
        pred_boxes = output[:, :4]  # N, 4
        pred_scores = output[:, 4]  # 4
        pred_labels = output[:, -1]  # 4

        true_positives = np.zeros(pred_boxes.shape[0])

        annotations = targets[targets[:, 0] == sample_i][:, 1:]
        target_labels = annotations[:, 0] if len(annotations) else []
        
        
        if len(annotations):
            detected_boxes = []
            target_boxes = annotations[:, 1:]
            iou_list = []
            for pred_i, (pred_box, pred_label) in enumerate(zip(pred_boxes, pred_labels)):
                
                pred_box = pred_box.to(device)
                pred_label = pred_label.to(device)

                # If no targets are found break
                if len(detected_boxes) == len(annotations):  #已经对比的预测框达到标记的真实框个数
                    break

                # Ignore if label is not one of the target labels
                if pred_label.to(device) not in target_labels:
                    continue

                iou, box_index = bbox_iou(pred_box.unsqueeze(0), target_boxes).max(0)

                iou_list.append(iou)
                

                if iou >= iou_threshold and box_index not in detected_boxes:
                    true_positives[pred_i] = 1
                    detected_boxes += [box_index]

            max_iou = max(iou_list) if len(iou_list) != 0 else 0
            for thres in thres_lst:
                if max_iou > thres:
                    hit_lst[thres] += 1
        iou_list = []  # 二次置零,避免在没有标记的情况下计算出iou值
        batch_metrics.append([true_positives, pred_scores, pred_labels])
    return batch_metrics

3. 在evaluation.py文件末尾处,将两处utils.utils.evaluation替换为utils.utils.evaluation_iou

    #模型评估
    print("computer mAP...")
    _, _, AP, _ = utils.utils.evaluation_iou(val_dataloader, cfg, model, device)
    print("computer PR...")
    precision, recall, _, f1 = utils.utils.evaluation_iou(val_dataloader, cfg, model, device, 0.3)
    print("Precision:%f Recall:%f AP:%f F1:%f"%(precision, recall, AP, f1))

4. 运行evaluation.py文件,查看输出的acc@iou指标结果。

  • 11
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值