相比前代的改进
YOLOv5其实就是YOLOv4的工程化的版本,v5版本并没有对v4版本进行大规模的改进创新,所以有人称v5是v4.5。v5或者是v4的版本改进我觉的是一下几点。
- 数据增强。采用了马赛克数据增强,就是从train的数据集中选择四张图片,在一张大图上的一定范围随机选择中心点,在中心点的左上,左下,右上,右下放置一张图片。这样做在一定程度上增加了batch size,四合一图片吗。当然,四张图片上面的label也要做相应的更新;
- DropBlock机制。防止过拟合很常用的方法就是Dropout,即随机杀死一些神经元,DropBlock则是随机杀死一片区域的神经元。例如,之前是把狗狗图片的眼睛一个像素点删掉了,现在是整个眼睛都删掉了;
- Label Smoothing。让标签平滑一些,目的是让神经网络不那么自信。例如,softmax的结果:(1,0)->[1,0]*(1-0.1)+0.05=[0.95,0.05];
- 损失函数:
边框回归:采用了CIoU
Objectness(置信度损失):采用了BCEWithLogitsLoss和CIoU
分类损失:采用了交叉熵损失函数BCEWithLogitsLoss
三种损失平衡:边框:Objectness:分类=0.05:1:0.5
三个检测层的损失平衡是:4.0, 1.0, 0.4对应8,16,32的输出层
在GitHub的yolov5代码中,lbox表示边框回归,lobj表示置信度损失,lcls表示分类损失,我对主要的compute_loss函数做注释如下:
def compute_loss(p, targets, model): # predictions, targets, model
device = targets.device
lcls, lbox, lobj = torch.zeros(1, device=device), torch.zeros(1, device=device), torch.zeros(1, device=device) # 初始化各个部分损失
tcls, tbox, indices, anchors = build_targets(p, targets, model) # 经过坐标变换获得标签分类,边框,索引,anchor
h = model.hyp # hyperparameters
# Define criteria BCELoss(损失函数) 该类主要用来创建衡量目标和输出之间的二进制交叉熵的标准,BCEWithLogitsLoss 这个loss类将sigmoid操作和与BCELoss集合到了一个类
BCEcls = nn.BCEWithLogitsLoss(pos_weight=torch.Tensor([h['cls_pw']])).to(device)
BCEobj = nn.BCEWithLogitsLoss(pos_weight=torch.Tensor([h['obj_pw'