yolov5--loss.py --v5.0版本-最新代码详细解释-2021-7-1更新

一、简述

yolov5–v5.0版本(最新)代码解析导航


github ultralytics/yolov5
使用的yolov5为2021年6月23号的版本v5.0


此篇作为学习笔记,也花了比较大的功夫,尽可能对每一个要点进行了解释
如有一些问题或错误,欢迎大家一起交流。

简述训练target生成的过程

涉及的部分原理,可以翻到文章最后补充内容,之所以解释不放到最前,是因为涉及了代码中的一些内容,直接可能并不明白,阅读了一遍代码,再看解释的时候可能就明白了.

简述代码流程

在train.py中

1.训练前 实例化 损失类

 compute_loss = ComputeLoss(model)  # init loss class

2.在训练中,调用__call__函数来返回损失

loss, loss_items = compute_loss(pred, targets.to(device))

二、代码部分

ComputeLoss中    init    部分

class ComputeLoss:
    # Compute losses
    def __init__(self, model, autobalance=False):
        super(ComputeLoss, self).__init__()
        device = next(model.parameters()).device  # get model device
        h = model.hyp  # hyperparameters

		'''
		对于目标obj损失来说无疑是用BCELoss(二分类损失)
		YOLOV5中使用的分类损失是BCEloss,对每个类别作sigmoid(而不是softmax),
		对于每个类别来说可以是一个2分类任务.
		其中nn.BCEWithLogitsLoss自带sigmoid
		'''
        # Define criteria
        BCEcls = nn.BCEWithLogitsLoss(pos_weight=torch.tensor([h['cls_pw']], device=device))
        BCEobj = nn.BCEWithLogitsLoss(pos_weight=torch.tensor([h['obj_pw']], device=device))

        '''
        对标签做平滑,eps=0就代表不做标签平滑,那么默认cp=1,cn=0
        后续对正类别赋值cp,负类别赋值cn
        '''
        # class label smoothing
        self.cp, self.cn = smooth_BCE(eps=h.get('label_smoothing', 0.0))  # positive, negative BCE targets
		
		'''
		如果g的值为0,则代表不使用focal loss
		'''
        # Focal loss
        g = h['fl_gamma']  # focal loss gamma
        if g > 0:
            BCEcls, BCEobj = FocalLoss(BCEcls, g), FocalLoss(BCEobj, g)
		
		'''
		balance用来设置三个特征图对应输出的损失系数
		从左到右对应大特征图(检测小物体)到小特征图(检测大物体),也就是说小物体的损失权重更大.
		当然模型不一定要三个特征图,其他情况比如四个五个特征图,同样可以设置相应的损失权重
		'''
        det = model.module.model[-1] if is_parallel(model) else model.model[-1]  # Detect() module
        self.balance = {
   3: [4.0, 1.0, 0.4]}.get(det.nl, [4.0, 1.0, 0.25, 0.06, .02])  # P3-P7
        self.ssi = list(det.stride).index(16) if autobalance else 0  # stride 16 index
        self.BCEcls, self.BCEobj, self.gr, self.hyp, self.autobalance = BCEcls, BCEobj, model.gr, h, autobalance
        for k in 'na', 'nc', 'nl', 'anchors':
            setattr(self, k, getattr(det, k))

ComputeLoss中build_targets

        def build_targets(self, p, targets):
        # Build targets for compute_loss(), input targets(image,class,x,y,w,h)
        '''
        p:    List[torch.tensor * 3], p[i].shape = (b, 3, h, w, nc+5)
        targets:  targets.shape(nt, 6) , 6=icxywh ,  i表示第i张图片,c为类别,xywh为坐标
        '''
        
        na, nt = self.na, targets.shape[0]  # number of anchors, targets
        tcls, tbox, indices, anch = [], [], [], []
        
        '''
        gain是为了对后续的target(na,nt,7)中的归一化的xywh转为特征图中的网格坐标    
        其中7表示: i c x y w h ai
        '''
        gain = torch.ones(7, device=targets.device)  # normalized to gridspace gain    gain:(7)

        '''
        需要na个尺度,都进行训练,那么标签就需要复制na个, ai就代表每个尺度的索引,默认里面的值为0,1,2
        '''
        ai = torch.arange(na, device=targets.device).float().view(na, 1).repeat(1,
                                                                                nt)  # same as .repeat_interleave(nt)   ai:(na,nt)
        '''
        targets.repeat(na, 1, 1):  (na,nt,6)
        ai[:, :, None]:  (na,nt,1)  --广播--> (na,nt,1)
        targets:  (na,nt,7)    7: i c x y w h ai
        '''
        targets = torch.cat((targets.repeat(na, 1, 1), ai[:, :, None]), 2)  # append anchor indices

        g = 0.5  # bias
        off = torch.tensor([[0, 0],
                            [1, 0], [0, 1
评论 25
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

菊头蝙蝠

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值