pytorch源码解析系列-yolov4最核心技巧代码详解(4)- 训练过程

本文深入解析YOLOv4在PyTorch中的训练过程,重点探讨IOU、CIOU_loss和DIOU_LOSS,并通过源代码分析其损失函数。虽然计算过程复杂,但核心思想是将问题转化为回归,简化了训练。文章提供了关键代码片段,帮助理解YOLOv4的损失组成和训练机制。
摘要由CSDN通过智能技术生成

补一下源码地址
我们先从简单的开始说起,怎么判断loss?要先判断目标检测的准确率标准,标准就是IOU(目标图片和预测图片的交并比)

IOU

yolov4用了CIOU_loss 和DIOU_LOSS
简单说一下,有个具体了解,都是从左到右发展来的

IOU GIOU DIOU CIOU
作用 主要考虑检测框和目标框重叠面积 在IOU的基础上,解决边界框不重合时的问题 在IOU和GIOU的基础上,考虑边界框中心点距离的信息 在DIOU的基础上,考虑边界框宽高比的尺度信息
具体实现 交并比 加了一个尺度相交(两个矩形外接最大矩形) GIOU+欧式距离/中心点距离 DIOU+长宽比

看代码就更直观了解他们的运作方式了

if GIoU or DIoU or CIoU:
        if GIoU: #area_c 就是外接矩形
            area_c = torch.prod(con_br - con_tl, 2)  # br tl对应button right和 top left坐标,这个公式就是算最小外接矩形面积
            return iou - (area_c - area_u) / area_c  # GIoU的公式,
        if DIoU or CIoU: 
        	#c2就是欧式距离 加一个小偏置防止除数为0
            c2 = torch.pow(con_br - con_tl, 2).sum(dim=2) + 1e-16
            if DIoU:
            #rho2 就是中心点距离 rho2 = ((bboxes_a[:, None, :2] - bboxes_b[:, :2]) ** 2 / 4).sum(dim=-1)
                return iou - rho2 / c2  # DIoU 的计算公式 加了个中心点距离/欧氏距离
            elif CIoU:  
            #这个V是长宽比
                v = (4 / math.pi ** 2) * torch.pow(torch.atan(w1 / h1).unsqueeze(1) - torch.atan(w2 / h2), 2)
                with torch.no_grad():
                    alpha = v / (1 - iou + v)
                return iou - (rho2 / c2 + v * alpha)  # CIoU 可以看到比Diou多了个长宽比因素
    return iou

如果对上述参数不了解,可以参考一下源代码,这里贴太多反而容易混淆

Loss function

CIOU懂了 那么CIOU loss呢
其实就是CIOU loss = (1-CIOU)
GIOU,CIOU等同理

那么yolo怎么计算loss的呢
偷一下cuijiahua大佬的图
在这里插入图片描述
很复杂 看不懂?
没关系 实际上就是 三个loss组成的
如果有物体 就要加上: 坐标框损失,置信度损失,分类类别损失
大概知道什么意思 然后去看代码就可以了:在这里插入图片描述

代码很长 可以只看我注释的地方 方便了解大体作用

class Yolo_loss(nn.Module):
    def __init__(self, n_classes=80, n_anchors=3, device=None, batch=2):
        super(Yolo_loss, self).__init__()
        # 这些老参数了 看我上一章内容都有
        self.device = device
        self.strides = [8, 16, 32]
        image_size = 608
        self.n_classes = n_classes
        self.n_anchors = n_anchors

        self.anchors = [[12, 16], [19, 36], [40, 28], [36, 75], [76, 55], [72, 146], [142, 110], [192, 243], [459, 401]]
        self.anch_masks = [[0, 1, 2], [3, 4, 5], [6, 7, 8]]
        self.ignore_thre = 0.5

        self.masked_anchors, self.ref_anchors, self.grid_x, self.grid_y, self.anchor_w, self.anchor_h = [], [], [], [], [], []
		#遍历三个anchor框 这下面代码在之前都出现过 具体就是初始化那些anchor
        for i in range(3):
            all_anchors_grid = [(w / self.strides[i], h / self.strides[i]) for w, h in self.anchors]
            masked_anchors = np.array([all_anchors_grid[j] for j in self.anch_masks[i]], dtype=np.float32)
            ref_anchors 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值