0
点赞
收藏
分享

微信扫一扫

机器视觉 - YoloV8 的一些理解

理解batch

  • batch size: yolo 每次会从整个数据集中随机选出一个batch的数据进行前向传播训练.
  • 计算此btch上所有样本的损失函数值.
  • 通过损失对各层参数计梯度求导, 计算出权重参数新值
  • 将计算出的更新值应用到模型上, 完成参数的批量更新
  • 重复采样下一个batch, 反复完成前向和后向传播, 直至完成一个全量的epoch
  • 即yolov8采用的训练策略是batch 更新方式.

理解epoch

  • epoch 是训练一个完整数据集的过程, 训练一个epoch后, 会自动完成一次 val, 我们可以观察收敛情况.

训练过程中如何进行val和如何结束训练

  • YoloV8 在每个epoch完成后, 会使用val数据集进行验证, 来计算loss和mAP等指标
  • 如果当前epoch的loss比之前最佳的loss还大, 就会增加一个early_stops计数, 如果比最佳loss小, 则early_stops清零. 如果early_stops计数大于阈值, 则进行早停(early_stopping)操作, 即整个训练不需要一定要完整预设的epoch次数.
  • 早停机制是防止过拟合的重要手段.
  • 我们可以通过 yolov8 的 patience 设置early_stops阈值

YoloV8的Fine-tuning和预训练和from scratch训练

yolo命令行model的参数的说明既可以选择 yolov8n.pt, 也可以选择 yolov8n.yaml, 区别是:

  • model=yolov8n.pt, 即为Fine-tuning训练, yolov8n.pt 模型文件已经包含了 yolo v8网络结构、超参数、训练参数、 权重参数信息, 它是官方的pre-trained 模型文件, 官方基于大规模数据集(coco 数据集)的80个类别训练而成.
  • model=yolov8n.yaml pretrained=yolov8n.pt, 这是一个全新模型配置文件 + 预训练模型文件的组合, 训练过程将使用yaml模型配置文件, 包含模型的网络结构, 超参数和训练参数等信息, 但初始权重使用预训练的yolov8n.pt, 这样收敛速度较快, 训练过程比完整的from scratch要会短一些.
  • model=yolov8n.yaml pretrained=False ,这是from scratch 训练, yolov8n.yaml文件包含模型的网络结构, 超参数和训练参数等信息, 我们可以基于这样的模型定义+自定义数据集训练出自己的模型权重文件, 用于后续的预测. 训练耗时最长.

yolov8预训练模型是基于coco和imagenet大型数据集做的训练, 所以这样的预训练权重已经非常具备通用性了, 对于99%的情况都适用, 如果完成从0开始做预训练,初始权重太过随机,很难收敛,最终网路训练结果也不会太好.

如果我们修改了网络, 预训练权重基本上不能使用了, 需要从头开始训练网络, 从头训练网络需要有好的算力和大的数据集, 否则做不成.

深度学习通过冻结部分参数提升效率效率

  • 深度学习模型通常包括通用特征提取(卷积+池化)和高层分类(卷积+池化)和结果输出(全连接层)三个阶段.
  • 特征提取是通用特征, 这部分参数通常无需调整
  • 所以, 可通过冻结特征提取参数来减少计算量, 提升fine-tuning的效率, 步骤一般为:
  • (1)先冻结前面几层卷积和池化层, 仅仅更新后面负责高级特征处理的卷积和池化层(统称为later classifier)
  • (2) 最后解冻全连接层, 完成分类任务的微调

cd myEnv\Scripts

# 基于预训练 yolov8n.pt 进行自有数据的training, 换句话说, 是针对自有数据进行模型的 fine-tuning, 训练耗时较短. 
.\yolo task=detect mode=train data=coco8.yaml model=yolov8n.pt  

# 使用 yolov8n.yaml 模型定义文件重新训练, 并使用预训练的 yolov8n.pt 作为初始权重值, 训练耗时较长. 
#   pretrained参数可以设置成bool值, 也可以设置为一个pt文件
.\yolo task=detect mode=train data=coco8.yaml model=yolov8n.yaml pretrained=yolov8n.pt 

# 使用 yolov8n.yaml 模型定义文件进行完全重新训练, 训练耗时最长. 
.\yolo task=detect mode=train data=coco8.yaml model=yolov8n.yaml pretrained=False

顶层逻辑伪代码结构

下面是伪代码, 仅用于理解yolo 训练过程的顶层逻辑

import torch
from torch.utils.tensorboard import SummaryWriter
from yolov8 import Darknet

# 初始化模型、优化器等
model = Darknet()
optimizer = SGD(model.params) 

writer = SummaryWriter('logs/yolov8')

for epoch in range(epochs):
    
    ## 每个epoch 的 train 过程
    model.train() #模型切换到训练状态
    for batch_idx, (images, targets) in enumerate(train_loader):
    
       # 前向后向传播
       pred = model(images)
       loss = calc_loss(pred, targets)
       
       optimizer.zero_grad()  
       loss.backward()
       optimizer.step()
       
       # 记录指标
       writer.add_scalar('Loss/train', loss, global_step)
       global_step += 1
    
    
    ## 每个epoch 的 validate 
    model.eval()  #模型切换到val状态
    val_loss = 0
    for images, targets in val_loader:
    
        pred = model(images)
        loss = calc_loss(pred, targets) 
        val_loss += loss
    
    val_loss /= len(val_loader)
    writer.add_scalar('Loss/val', val_loss, global_step)
    
    ## 保存最优模型
    if val_loss < best_loss:
        torch.save(model)

writer.close()



举报

相关推荐

0 条评论