0


详解:yolov5中推理时置信度,设置的conf和iou_thres具体含义

一、模型输出解析:

  1. **设输出图片大小为1280768,类别个数为2**,则yolov5输出的三种特征图,其维度分别为:[1,3,961607],[1,3,48,80,7],[1,3,24,40,7];相当于yolov5模型总共输出(96*160+48*80+24*40)*3=60480个目标框;
  2. **其中,[1,3,96,160,7] 1指代输入图像个数为13指的是该尺度下的3anchor,(96,160) 指的是特征图的尺寸,7具体指的是:(center_x,center_y, width, height, obj_conf, class_1_prob class_2_prob ),即分别为box框中心点x,y,长和宽 width,height,以及该框存在目标的置信度obj_conf,类别1和类别2 的置信度,若class_1_prob > class_2_prob,则该框的类别为class1;因此,obj_confclass_1_prob一个指得是该框存在目标的概率,一个指是该框分类为类别1的概率;**

二、yolov5后处理解析;

** 从一可知模型输出了60480个目标框,因此,要经过NMS进行过滤,进NMS之前需要经过初筛(即将obj_conf小于我们设置的置信度的框去除),再计算每个box框的综合置信度conf:conf = obj_conf * max(class_1_prob ,class_2_prob),此时的conf是综合了obj_conf以及class_prob的综合概率;再经过进一步的过滤(即将conf小于我们设置的置信度的框去除)**,最后,将剩余的框通过NMS算法,得出最终的框;(NMS中用到了我们设置的iou_thres);

  1. **因此,最终我们可视化在box上方的置信度是综合了obj_conf以及class_prob的综合概率;**
  2. 以下是yolov5NMS源码,可查看细节:
  1. def non_max_suppression(prediction,
  2. conf_thres=0.25,
  3. iou_thres=0.45,
  4. classes=None,
  5. agnostic=False,
  6. multi_label=False,
  7. labels=(),
  8. max_det=300):
  9. """Non-Maximum Suppression (NMS) on inference results to reject overlapping bounding boxes
  10. Returns:
  11. list of detections, on (n,6) tensor per image [xyxy, conf, cls]
  12. """
  13. bs = prediction.shape[0] # batch size
  14. nc = prediction.shape[2] - 5 # number of classes
  15. xc = prediction[..., 4] > conf_thres # candidates
  16. # Checks
  17. assert 0 <= conf_thres <= 1, f'Invalid Confidence threshold {conf_thres}, valid values are between 0.0 and 1.0'
  18. assert 0 <= iou_thres <= 1, f'Invalid IoU {iou_thres}, valid values are between 0.0 and 1.0'
  19. # Settings
  20. # min_wh = 2 # (pixels) minimum box width and height
  21. max_wh = 7680 # (pixels) maximum box width and height
  22. max_nms = 30000 # maximum number of boxes into torchvision.ops.nms()
  23. time_limit = 0.3 + 0.03 * bs # seconds to quit after
  24. redundant = True # require redundant detections
  25. multi_label &= nc > 1 # multiple labels per box (adds 0.5ms/img)
  26. merge = False # use merge-NMS
  27. t = time.time()
  28. output = [torch.zeros((0, 6), device=prediction.device)] * bs
  29. for xi, x in enumerate(prediction): # image index, image inference
  30. # Apply constraints
  31. # x[((x[..., 2:4] < min_wh) | (x[..., 2:4] > max_wh)).any(1), 4] = 0 # width-height
  32. x = x[xc[xi]] # confidence
  33. # Cat apriori labels if autolabelling
  34. if labels and len(labels[xi]):
  35. lb = labels[xi]
  36. v = torch.zeros((len(lb), nc + 5), device=x.device)
  37. v[:, :4] = lb[:, 1:5] # box
  38. v[:, 4] = 1.0 # conf
  39. v[range(len(lb)), lb[:, 0].long() + 5] = 1.0 # cls
  40. x = torch.cat((x, v), 0)
  41. # If none remain process next image
  42. if not x.shape[0]:
  43. continue
  44. # Compute conf
  45. x[:, 5:] *= x[:, 4:5] # conf = obj_conf * cls_conf
  46. # Box (center x, center y, width, height) to (x1, y1, x2, y2)
  47. box = xywh2xyxy(x[:, :4])
  48. # Detections matrix nx6 (xyxy, conf, cls)
  49. if multi_label:
  50. i, j = (x[:, 5:] > conf_thres).nonzero(as_tuple=False).T
  51. x = torch.cat((box[i], x[i, j + 5, None], j[:, None].float()), 1)
  52. else: # best class only
  53. conf, j = x[:, 5:].max(1, keepdim=True)
  54. x = torch.cat((box, conf, j.float()), 1)[conf.view(-1) > conf_thres]
  55. # Filter by class
  56. if classes is not None:
  57. x = x[(x[:, 5:6] == torch.tensor(classes, device=x.device)).any(1)]
  58. # Apply finite constraint
  59. # if not torch.isfinite(x).all():
  60. # x = x[torch.isfinite(x).all(1)]
  61. # Check shape
  62. n = x.shape[0] # number of boxes
  63. if not n: # no boxes
  64. continue
  65. elif n > max_nms: # excess boxes
  66. x = x[x[:, 4].argsort(descending=True)[:max_nms]] # sort by confidence
  67. # Batched NMS
  68. c = x[:, 5:6] * (0 if agnostic else max_wh) # classes
  69. boxes, scores = x[:, :4] + c, x[:, 4] # boxes (offset by class), scores
  70. i = torchvision.ops.nms(boxes, scores, iou_thres) # NMS
  71. if i.shape[0] > max_det: # limit detections
  72. i = i[:max_det]
  73. if merge and (1 < n < 3E3): # Merge NMS (boxes merged using weighted mean)
  74. # update boxes as boxes(i,4) = weights(i,n) * boxes(n,4)
  75. iou = box_iou(boxes[i], boxes) > iou_thres # iou matrix
  76. weights = iou * scores[None] # box weights
  77. x[i, :4] = torch.mm(weights, x[:, :4]).float() / weights.sum(1, keepdim=True) # merged boxes
  78. if redundant:
  79. i = i[iou.sum(1) > 1] # require redundancy
  80. output[xi] = x[i]
  81. if (time.time() - t) > time_limit:
  82. LOGGER.warning(f'WARNING: NMS time limit {time_limit:.3f}s exceeded')
  83. break # time limit exceeded
  84. return output

本文转载自: https://blog.csdn.net/pangxing6491/article/details/125297384
版权归原作者 辣大辣条 所有, 如有侵权,请联系我们删除。

“详解:yolov5中推理时置信度,设置的conf和iou_thres具体含义”的评论:

还没有评论