YOLOv5 Detect 训练过程简单记录

2023-12-29 16:33:12

目录

训练配置

网络的搭建过程

?数据的处理

mosaic数据增强方法

模型的前向处理过程


训练配置

在主项目文件夹下创建 datasets文件夹,并配置coco数据集

# ├── yolov5
#     └── datasets
#           └── coco  ← downloads here (20.1 GB)

标签数据可以直接运行train.py,自动下载并解压,

python train.py --data coco.yaml --epochs 300 --weights '' --cfg yolov5n.yaml  --batch-size 32

cp ./Arial.ttf /root/.config/Ultralytics/

如果github连不上,则可以挂vpn去下载

https://github.com/ultralytics/yolov5/releases/download/v1.0/coco2017labels.zip

网络的搭建过程

1. model = Model(cfg, ch=3, nc=nc, anchors=hyp.get('anchors')).to(device)  # train.py--137
2. self.model, self.save = parse_model(deepcopy(self.yaml), ch=[ch])  # yolo.py--186
3. m_ = nn.Sequential(*(m(*args) for _ in range(n))) if n > 1 else m(*args)  # module yolo.py--347
4. layers.append(m_)
5. nn.Sequential(*layers)

网络的参数设定都在yaml中,d中的内容

这里涉及 eval() 函数的使用,参考这里?

for i, (f, n, m, args) in enumerate(d['backbone'] + d['head']):

# 其中的参数值举例
i :  1 
f : -1
n :  1
m :  'Conv'
args :  [64, 6, 2, 2]

它们都来自yaml文件中的定义。

# m.anchors
tensor([[[ 10.,  13.],
         [ 16.,  30.],
         [ 33.,  23.]],

        [[ 30.,  61.],
         [ 62.,  45.],
         [ 59., 119.]],

        [[116.,  90.],
         [156., 198.],
         [373., 326.]]])

优化器的搭建

optimizer = smart_optimizer(model, opt.optimizer, hyp['lr0'], hyp['momentum'], hyp['weight_decay'])  # train.py--162

EMA更新参数机制

ema = ModelEMA(model) if RANK in {-1, 0} else None   # train.py--172

cache中的内容

?数据的处理

1、 设定shape,保证最大的一边不超过640,  dataloader.py -- 560始
2、 保证图片的每一边都是步长的倍数

前面都是一些设置,主要的导入数据过程在 dataloaders.py 的 __getitem__中。

mosaic数据增强方法

随即采用的,并不是都采用

mosaic = self.mosaic and random.random() < hyp['mosaic']  # True, 随机采用

首先在范围内选取center,在随机选取额外的3张图片的索引并打乱顺序。

加载这些图片

fn中内容

采用cv2读入的数据

im = cv2.imread(f)  # BGR

?标签的对齐,主要如下

padw = x1a - x1b
padh = y1a - y1b

y[..., 0] = w * (x[..., 0] - x[..., 2] / 2) + padw

通过计算相对坐标,将得到的偏移量加到原有的,从而统一到增强后的坐标系中。相对坐标的应用系分析详见这里

# x 中的值,归一化了
[[    0.50074     0.60091     0.99852     0.77579], [    0.47636     0.63401     0.78222     0.61711]]
# y中的值, 反归一化了
[[     358.95      601.53         998      931.24], [     412.56      649.32      913.18      911.59]]

后续还在此基础上进行了一些数据增强操作,包括旋转,尺度变化等等

?因此,标签会根据数据增强后的再次进行对齐。最终的标签会再度除以宽和高进行归一化

labels[:, 1:5] = xyxy2xywhn(labels[:, 1:5], w=img.shape[1], h=img.shape[0], clip=True, eps=1E-3)  # dataloader.py--698

按每个类别的数量计算了权重?

\frac{?{\frac{?{\rm{1}}}{?{?{n_i}}}}}{?{\sum\limits_{i = 1}^{80} {\frac{1}{?{?{n_i}}}} }}

最终 , train_loader的返回值为

torch.from_numpy(img), labels_out, self.im_files[index], shapes

其中labels_out 是个6维的数据,

labels_out[2:6] 为归一化的 xywh bounding box 的标签
labels_out[1]  为 类别标签
labels_out[0]  为 0

模型的前向处理过程

前向处理过程中 Detect头直接输出,因为 self.training is False。整个模型端到端

pred中的内容举例

ai 内容?

targets内容

第一维变成batch size 的arrange了。

注意,在

t = targets * gain

时将标签的尺度转到了输出的特征图的尺度上。

yolov5锚框的设置,autoanchor 以及这里

这里结合代码进行了说明?

?yolov5锚框在每个尺度的特征图上的点设置了偏移量,并且每个点随机的采取周围的上下左右3个点作为anchor的中心点。

置信度的设定,采用的是预测的box与真实值box的CIoU,

tobj = torch.zeros(pi.shape[:4], dtype=pi.dtype, device=self.device)  # 初始值为0
iou = bbox_iou(pbox, tbox[i], CIoU=True).squeeze()  # iou(prediction, target)
tobj[b, a, gj, gi] = iou  # iou ratio  正样本标签采用CIoU

回归损失,采用的是CIoU损失,

置信度损失和分类损失,均采用Focal loss。

文章来源:https://blog.csdn.net/allrubots/article/details/135159122
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。