YOLOv8/v10/v11剪枝,接定制改模型后的剪枝

1 约束训练

1.1 修改YOLOv8代码:

ultralytics/yolo/engine/trainer.py

添加内容:

# Backward
self.scaler.scale(self.loss).backward()

# ========== 新增 ==========
l1_lambda = 1e-2 * (1 - 0.9 * epoch / self.epochs)
for k, m in self.model.named_modules():
    if isinstance(m, nn.BatchNorm2d):
        m.weight.grad.data.add_(l1_lambda * torch.sign(m.weight.data))
        m.bias.grad.data.add_(1e-2 * torch.sign(m.bias.data))
# ========== 新增 ==========

# Optimize - https://pytorch.org/docs/master/notes/amp_examples.html
if ni - last_opt_step >= self.accumulate:
    self.optimizer_step()
    last_opt_step = ni

1.2  训练

需要注意的就是amp=False

命令行输入:
yolo train model=yolov8s.yaml epochs=100 amp=False

训练完会得到一个best.pt和last.pt,推荐用last.pt

1.3 约束训练可视化

已实现在tensorboard可视化约束训练过程BN参数的分布变化

随着训练进行(纵轴是epoch),BN层参数会逐渐从最上面的正太分布趋向于0附近。

以下是正常训练和稀疏训练的BN层参数值分布图:

9603549cfb75653cf49537d236c273e1.png

右图的稀疏训练明显太早就全到0了,这样会影响精度,可以把系数1e-2改小一点1e-3,这样会稀疏的慢一点,l1_lambda = 1e-2 * (1 - 0.9 * epoch / self.epochs)
如下图:左为1e-2, 右为0.3*1e-2

89055bea79698be517554e4d0eb6925a.png

2 剪枝

上一步得到的last.pt作为剪枝对象,自己创建一个prun.py文件:

这里的剪枝代码仅适用yolov8原模型,如有模块/模型的更改,则需要修改剪枝代码

需要定制改模型后的剪枝的可以私信

from ultralytics import YOLO
import torch
from ultralytics.nn.modules import Bottleneck, Conv, C2f, SPPF, Detect

yolo = YOLO("last.pt")  # 第一步约束训练得到的pt文件


model = yolo.model
ws = []
bs = []

for _, m in model.named_modules():
    if isinstance(m, torch.nn.BatchNorm2d):
        w = m.weight.abs().detach()
        b = m.bias.abs().detach()
        ws.append(w)
        bs.append(b)


factor = 0.8  # 通道保留比率


ws = torch.cat(ws)
threshold = torch.sort(ws, descending=True)[0][int(len(ws) * factor)]
print(threshold)


def _prune(c1, c2):
    wet = c1.bn.weight.data.detach()
    bis = c1.bn.bias.data.detach()
    list = []
    _threshold = threshold
    while len(list) < 8:
        list = torch.where(wet.abs() >= _threshold)[0]
        _threshold = _threshold * 0.5
    i = len(list)
    c1.bn.weight.data = wet[list]
    c1.bn.bias.data = bis[list]
    c1.bn.running_var.data = c1.bn.running_var.data[list]
    c1.bn.running_mean.data = c1.bn.running_mean.data[list]
    c1.bn.num_features = i
    c1.conv.weight.data = c1.conv.weight.data[list]
    c1.conv.out_channels = i
    if c1.conv.bias is not None:
        c1.conv.bias.data = c1.conv.bias.data[list]
    if not isinstance(c2, list):
        c2 = [c2]
    for item in c2:
        if item is not None:
            if isinstance(item, Conv):
                conv = item.conv
            else:
                conv = item
            conv.in_channels = i
            conv.weight.data = conv.weight.data[:, list]

def prune(m1, m2):
    if isinstance(m1, C2f):
        m1 = m1.cv2
    if not isinstance(m2, list):
        m2 = [m2]
    for i, item in enumerate(m2):
        if isinstance(item, C2f) or isinstance(item, SPPF):
            m2[i] = item.cv1
    _prune(m1, m2)

for _, m in model.named_modules():
    if isinstance(m, Bottleneck):
        _prune(m.cv1, m.cv2)


for _, p in yolo.model.named_parameters():
    p.requires_grad = True

# yolo.export(format="onnx")  # 导出为onnx文件
# yolo.train(data="VOC.yaml", epochs=100) # 剪枝后直接训练微调

torch.save(yolo.ckpt, "prune.pt")
print("done")

上述代码只需修改:

1. 最顶上的yolo = YOLO("last.pt")改为第一步约束训练得到的文件路径,一般为runs/detect/train/weights/last.pt

2. 最下面的torch.save(yolo.ckpt, "prune.pt")改为想要保存的路径

运行完会得到prune.pt和prune.onnx可以在netron.app网站拖入onnx文件查看是否剪枝成功了,成功的话可以看到某些通道数字为单数或者一些不规律的数字,如下图:

81627869f430d9cf9245ea8ccfc8b1b6.png

 

3 回调训练(finetune)

3.1 先要把第一步约束训练的代码注释掉

3.2  修改相关代码

修改位置:yolo/engine/trainer.py的443行左右

self.model = self.get_model(cfg=cfg, weights=weights, verbose=RANK == -1)  # calls Model(cfg, weights)

# ========== 新增该行代码 ==========
self.model = weights
# ========== 新增该行代码 ==========

return ckpt

3.3 修改完代码就可以进行finetun训练了

命令行输入:
yolo train model=prune.pt epochs=100

结果展示:

约束训练last.pt:

e7183f559b7e4636188d1620392ddf3e.png

剪枝后的prune.pt:

c2f735e613dfd9056d2a080fdd21d7be.png

回调后的finetune.pt:

14f71991d3f2ee1a17df4d2be08e0cbc.png

可以看到精度损失很小,但是参数量和浮点运算量下去了很多,推理速度在cpu上测试是变快了的,gpu上好像没啥变化

剪枝前后各层通道数对比:

eecb33a2f537ffcae42ef3406431ec23.jpeg

 

 

 

<think>好的,我现在需要回答用户关于YOLOv5、YOLOv8YOLOv11哪个FPS更快的问题。首先,我需要确认这几个版本的基本信息,特别是它们的架构差异和性能表现。 YOLOv5是Ultralytics公司推出的,基于PyTorch实现,以其易用性和速度著称。它有不同的模型尺寸,比如n、s、m、l、x,对应不同的速度和准确率。一般来说,较小的模型YOLOv5n的FPS应该比较高,但可能准确率稍低。 YOLOv8同样来自Ultralytics,是YOLOv5的后续版本。它在架构上做了一些进,比如使用了更高效的backbone和neck结构,可能引入了新的模块或优化技术,比如CSP结构或不同的激活函数,这些都可能影响速度。但具体是提升还是降低FPS,需要看实际测试结果。 至于YOLOv11,这里可能存在混淆,因为目前官方YOLO版本到v8,而v9、v10也有社区版本,但v11可能不是官方的,或者用户可能指的是其他变种,比如YOLOX或其他进版本。需要核实YOLOv11是否存在,或者是否是笔误。假设用户确实是指某个YOLOv11,可能是某个研究团队或公司自研的版本,这时候需要查找相关资料,确认其架构特点,比如是否采用了更轻量化的设计,或者模型压缩技术,如剪枝、量化等,这些都可能提升FPS。 下来,我需要考虑影响FPS的因素:模型的计算复杂度(FLOPs)、参数量(Parameters)、硬件优化(如GPU加速)、输入分辨率、以及实际部署时的框架优化(如TensorRT)。通常,FLOPs和参数量较低的模型会更快,但实际FPS还取决于实现效率和硬件兼容性。 然后,查找这三个版本的公开基准测试数据。例如,YOLOv5和YOLOv8的官方GitHub或论文中可能有在COCO数据集上的速度和准确率对比。YOLOv11如果存在的话,需要找到其发布资料。假设在相同硬件条件下(如Tesla T4 GPU),输入分辨率相同(如640x640),比较它们的FPS。 根据已有信息,YOLOv8可能在保持或提升准确率的同时优化了速度,尤其是其nano版本(YOLOv8n)可能比YOLOv5n更快。而YOLOv11如果存在,可能进一步优化结构,比如使用更少的层或更高效的模块,从而提升FPS。但需要确认是否存在这样的进。 另外,需要注意不同版本的训练策略和模型缩放方法,比如YOLOv8可能采用了动态标签分配或其他训练优化,虽然不影响推理速度,但可能间影响模型效率。 如果缺乏YOLOv11的资料,可能需要指出这一点,并推测基于版本命名的可能优化方向。但需要明确说明不确定性,避免误导用户。 最后,总结对比结果,给出FPS的大致排序,并建议用户在实际环境中测试,因为硬件和实现细节会影响实际性能。</think>在比较YOLOv5、YOLOv8YOLOv11的FPS(每秒帧率)时,需综合考虑模型结构、硬件优化和部署环境。以下是逐步分析: --- ### 1. **YOLOv5** - **特点**: - 基于PyTorch实现,提供不同尺寸的预训练模型(n/s/m/l/x),例如: - **YOLOv5n**(超轻量级)FPS最高,但精度较低 - **YOLOv5x**(最大模型)FPS最低,但精度最高 - 使用CSPNet作为骨干网络,平衡速度和精度。 - **FPS表现**: 在Tesla T4 GPU上,输入分辨率$640 \times 640$时: - YOLOv5n:约**450-500 FPS** - YOLOv5s:约**120-150 FPS** --- ### 2. **YOLOv8** - **特点**: - YOLOv5的升级版,进一步优化了网络结构: - 引入更高效的**C2f模块**(跨阶段部分融合) - 使用**动态标签分配**提升训练效率 - 支持**Anchor-Free检测头**,减少计算量 - 同样提供多种尺寸(n/s/m/l/x)。 - **FPS表现**: 相同硬件和输入分辨率下: - YOLOv8n:约**500-550 FPS**(比YOLOv5n略快) - YOLOv8s:约**130-160 FPS** --- ### 3. **YOLOv11** - **注意**:截至2024年,**官方未发布YOLOv11**,可能为社区进版本或误写(如YOLOv10已由Ultralytics推出)。 - **推测进**(假设存在): - 可能采用更极致的轻量化设计(如深度可分离卷积、模型量化) - 可能引入Transformer等模块优化速度-精度平衡。 --- ### 4. **FPS对比结论** | 模型 | 典型FPS(Tesla T4, 640×640) | 备注 | |-----------|-------------------------------|----------------------------------| | YOLOv5n | 450-500 | 轻量级首选,速度快但精度较低 | | YOLOv8n | 500-550 | 结构优化,速度略优于YOLOv5n | | YOLOv11* | 未知(若存在可能更高) | 需具体验证实现细节 | --- ### 5. **关键影响因素** - **输入分辨率**:分辨率越低,FPS越高(但精度下降)。 - **硬件加速**:使用TensorRT或ONNX Runtime可进一步提升FPS。 - **部署框架**:PyTorch原生推理较慢,建议转换为TensorRT或OpenVINO。 --- ### 建议 1. **优先选择YOLOv8n**:在速度和精度间取得较好平衡。 2. **实测验证**:使用自己的硬件和数据测试,不同环境结果可能差异较大。 3. **关注官方更新**:YOLOv10已发布,建议对比最新版本性能。
评论 108
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Dneccc

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

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

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

打赏作者

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

抵扣说明:

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

余额充值