• 该教程为改进入门指南,属于《芒果书》系列,包含大量的原创首发改进方式, 所有文章都是全网首发原创改进内容

  • 本篇文章 基于 YOLOv5、YOLOv7芒果改进YOLO系列:YOLOv7改进IoU损失函数:YOLOv7涨点Trick,改进添加SIoU损失函数、EIoU损失函数、GIoU损失函数、α-IoU损失函数、打造全新YOLOv7检测器

  • 重点:有不少同学已经反应有效涨点!!! 其他改进内容:CSDN原创YOLO进阶目录 | 《芒果改进YOLO进阶指南》推荐!

  • 最全《芒果书》改进目录:YOLOv5改进、YOLOv7改进(芒果书系列)目录一览|原创YOLO改进模型全系列目录 | 人工智能专家老师联袂推荐

    文章目录

        • 解析|YOLOv7网络模型源代码训练推理教程解析
        • 总结|YOLO系列期刊创新点总结
        • 核心代码改进
          • 改进核心代码
          • 改进α-IoU核心代码
          • SIoU改进
          • EIoU改进
          • GIoU改进
          • α-IoU改进
          • 代码直接运行

解析|YOLOv7网络模型源代码训练推理教程解析

  • 手把手调参最新 YOLOv7 模型 推理部分(一)
  • 手把手调参最新 YOLOv7 模型 训练部分(二)

总结|YOLO系列期刊创新点总结

  • ☁️:国庆假期浏览了几十篇YOLO改进英文期刊,总结改进创新的一些相同点(期刊创新点持续更新)

  • ☁️:国庆假期看了一系列图像分割Unet、DeepLabv3+改进期刊论文,总结了一些改进创新的技巧

核心代码改进

以下SIoU、EIoU、GIoU、α-IoU改进,代码均在博主开源的YOLOAir中有写

改进核心代码

在YOLOv5中,使用以下函数替换原有的utils/metrics.py文件中的bbox_iou函数

如果在YOLOv7中,使用以下函数替换原有的utils/general.py文件中的bbox_iou函数

def bbox_iou(box1, box2, x1y1x2y2=True, GIoU=False, DIoU=False, CIoU=False, EIoU=False, SIoU=False, eps=1e-7):# Returns the IoU of box1 to box2. box1 is 4, box2 is nx4box2 = box2.T# Get the coordinates of bounding boxesif x1y1x2y2:# x1, y1, x2, y2 = box1b1_x1, b1_y1, b1_x2, b1_y2 = box1[0], box1[1], box1[2], box1[3]b2_x1, b2_y1, b2_x2, b2_y2 = box2[0], box2[1], box2[2], box2[3]else:# transform from xywh to xyxyb1_x1, b1_x2 = box1[0] - box1[2] / 2, box1[0] + box1[2] / 2b1_y1, b1_y2 = box1[1] - box1[3] / 2, box1[1] + box1[3] / 2b2_x1, b2_x2 = box2[0] - box2[2] / 2, box2[0] + box2[2] / 2b2_y1, b2_y2 = box2[1] - box2[3] / 2, box2[1] + box2[3] / 2# Intersection areainter = (torch.min(b1_x2, b2_x2) - torch.max(b1_x1, b2_x1)).clamp(0) * \(torch.min(b1_y2, b2_y2) - torch.max(b1_y1, b2_y1)).clamp(0)# Union Areaw1, h1 = b1_x2 - b1_x1, b1_y2 - b1_y1 + epsw2, h2 = b2_x2 - b2_x1, b2_y2 - b2_y1 + epsunion = w1 * h1 + w2 * h2 - inter + epsiou = inter / unionif CIoU or DIoU or GIoU or EIoU or SIoU:cw = torch.max(b1_x2, b2_x2) - torch.min(b1_x1, b2_x1)# convex (smallest enclosing box) widthch = torch.max(b1_y2, b2_y2) - torch.min(b1_y1, b2_y1)# convex heightif CIoU or DIoU or EIoU or SIoU:# Distance or Complete IoU https://arxiv.org/abs/1911.08287v1c2 = cw ** 2 + ch ** 2 + eps# convex diagonal squaredrho2 = ((b2_x1 + b2_x2 - b1_x1 - b1_x2) ** 2 +(b2_y1 + b2_y2 - b1_y1 - b1_y2) ** 2) / 4# center distance squaredif DIoU: #DIoUreturn iou - rho2 / c2# DIoUelif CIoU:#CIoUhttps://github.com/Zzh-tju/DIoU-SSD-pytorch/blob/master/utils/box/box_utils.py#L47v = (4 / math.pi ** 2) * torch.pow(torch.atan(w2 / h2) - torch.atan(w1 / h1), 2)with torch.no_grad():alpha = v / (v - iou + (1 + eps))return iou - (rho2 / c2 + v * alpha)# CIoUelif SIoU:# SIoUs_cw = (b2_x1 + b2_x2 - b1_x1 - b1_x2) * 0.5s_ch = (b2_y1 + b2_y2 - b1_y1 - b1_y2) * 0.5sigma = torch.pow(s_cw ** 2 + s_ch ** 2, 0.5)sin_alpha_1 = torch.abs(s_cw) / sigmasin_alpha_2 = torch.abs(s_ch) / sigmathreshold = pow(2, 0.5) / 2sin_alpha = torch.where(sin_alpha_1 > threshold, sin_alpha_2, sin_alpha_1)angle_cost = torch.cos(torch.arcsin(sin_alpha) * 2 - math.pi / 2)rho_x = (s_cw / cw) ** 2rho_y = (s_ch / ch) ** 2gamma = angle_cost - 2distance_cost = 2 - torch.exp(gamma * rho_x) - torch.exp(gamma * rho_y)omiga_w = torch.abs(w1 - w2) / torch.max(w1, w2)omiga_h = torch.abs(h1 - h2) / torch.max(h1, h2)shape_cost = torch.pow(1 - torch.exp(-1 * omiga_w), 4) + torch.pow(1 - torch.exp(-1 * omiga_h), 4)return iou - 0.5 * (distance_cost + shape_cost)else:# EIoUw_dis=torch.pow(b1_x2-b1_x1-b2_x2+b2_x1, 2)h_dis=torch.pow(b1_y2-b1_y1-b2_y2+b2_y1, 2)cw2=torch.pow(cw , 2)+epsch2=torch.pow(ch , 2)+epsreturn iou-(rho2/c2+w_dis/cw2+h_dis/ch2)else:c_area = cw * ch + eps# convex areareturn iou - (c_area - union) / c_area# GIoU https://arxiv.org/pdf/1902.09630.pdfreturn iou# IoU

改进α-IoU核心代码

def bbox_alpha_iou(box1, box2, x1y1x2y2=False, GIoU=False, DIoU=False, CIoU=False, alpha=2, eps=1e-9):# Returns tsqrt_he IoU of box1 to box2. box1 is 4, box2 is nx4box2 = box2.T# Get the coordinates of bounding boxesif x1y1x2y2:# x1, y1, x2, y2 = box1b1_x1, b1_y1, b1_x2, b1_y2 = box1[0], box1[1], box1[2], box1[3]b2_x1, b2_y1, b2_x2, b2_y2 = box2[0], box2[1], box2[2], box2[3]else:# transform from xywh to xyxyb1_x1, b1_x2 = box1[0] - box1[2] / 2, box1[0] + box1[2] / 2b1_y1, b1_y2 = box1[1] - box1[3] / 2, box1[1] + box1[3] / 2b2_x1, b2_x2 = box2[0] - box2[2] / 2, box2[0] + box2[2] / 2b2_y1, b2_y2 = box2[1] - box2[3] / 2, box2[1] + box2[3] / 2# Intersection areainter = (torch.min(b1_x2, b2_x2) - torch.max(b1_x1, b2_x1)).clamp(0) * \(torch.min(b1_y2, b2_y2) - torch.max(b1_y1, b2_y1)).clamp(0)# Union Areaw1, h1 = b1_x2 - b1_x1, b1_y2 - b1_y1 + epsw2, h2 = b2_x2 - b2_x1, b2_y2 - b2_y1 + epsunion = w1 * h1 + w2 * h2 - inter + eps# change iou into pow(iou+eps)# iou = inter / unioniou = torch.pow(inter/union + eps, alpha)# beta = 2 * alphaif GIoU or DIoU or CIoU:cw = torch.max(b1_x2, b2_x2) - torch.min(b1_x1, b2_x1)# convex (smallest enclosing box) widthch = torch.max(b1_y2, b2_y2) - torch.min(b1_y1, b2_y1)# convex heightif CIoU or DIoU:# Distance or Complete IoU https://arxiv.org/abs/1911.08287v1c2 = (cw ** 2 + ch ** 2) ** alpha + eps# convex diagonalrho_x = torch.abs(b2_x1 + b2_x2 - b1_x1 - b1_x2)rho_y = torch.abs(b2_y1 + b2_y2 - b1_y1 - b1_y2)rho2 = ((rho_x ** 2 + rho_y ** 2) / 4) ** alpha# center distanceif DIoU:return iou - rho2 / c2# DIoUelif CIoU:# https://github.com/Zzh-tju/DIoU-SSD-pytorch/blob/master/utils/box/box_utils.py#L47v = (4 / math.pi ** 2) * torch.pow(torch.atan(w2 / h2) - torch.atan(w1 / h1), 2)with torch.no_grad():alpha_ciou = v / ((1 + eps) - inter / union + v)# return iou - (rho2 / c2 + v * alpha_ciou)# CIoUreturn iou - (rho2 / c2 + torch.pow(v * alpha_ciou + eps, alpha))# CIoUelse:# GIoU https://arxiv.org/pdf/1902.09630.pdf# c_area = cw * ch + eps# convex area# return iou - (c_area - union) / c_area# GIoUc_area = torch.max(cw * ch + eps, union) # convex areareturn iou - torch.pow((c_area - union) / c_area + eps, alpha)# GIoUelse:return iou # torch.log(iou+eps) or iou

SIoU改进

参考上面的核心代码

将iou = bbox_iou(pbox.T, tbox[i], x1y1x2y2=False, CIoU=True)替换为iou = bbox_iou(pbox.T, tbox[i], x1y1x2y2=False, SIoU=True)

EIoU改进

参考上面的核心代码

将iou = bbox_iou(pbox.T, tbox[i], x1y1x2y2=False, CIoU=True)替换为iou = bbox_iou(pbox.T, tbox[i], x1y1x2y2=False, EIoU=True)

GIoU改进

参考上面的核心代码

将iou = bbox_iou(pbox.T, tbox[i], x1y1x2y2=False, CIoU=True)替换为iou = bbox_iou(pbox.T, tbox[i], x1y1x2y2=False, GIoU=True)

α-IoU改进

参考上面的核心代码

bbox_alpha_iou将iou = bbox_iou(pbox.T, tbox[i], x1y1x2y2=False, CIoU=True)替换为iou = bbox_alpha_iou(pbox.T, tbox[i], x1y1x2y2=False, CIoU=True)

以上是yolov5的改进

yolov7 将 tbox[i] 改为 selected_tbox

比如 iou = bbox_iou(pbox.T, tbox[i], x1y1x2y2=False, CIoU=True)
改为iou = bbox_iou(pbox.T, selected_tbox, x1y1x2y2=False, CIoU=True)

代码直接运行

python train.py cfg yolov7.yaml即可