Pytorch中计算自己模型的FLOPs | thop.profile() 方法 | yolov5s 网络模型参数量、计算量统计

本文介绍了如何使用PyTorch-OpCounter计算模型如YOLOv5s的FLOPs和参数量,涵盖了FLOPS基础概念,以及如何通过GitHub库统计模型复杂度。同时提供了实际代码示例和常见错误处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1-0

享受学术探讨的欢乐,传递温暖,希望能够帮助到刚刚入门的同学

  • 🍖 Pytorch中计算自己模型的FLOPs | yolov5s 网络模型参数量、计算量统计


📙 FLOPS 基础概念理解


参考链接: 这部分内容 精选于 Z 乎 问答,感谢各位大佬

  • FLOPS:注意全大写,是floating point operations per second的缩写,意指每秒浮点运算次数,理解为计算速度。是一个衡量硬件性能的指标。
  • FLOPs:注意s小写,是floating point operations的缩写(s表复数),意指浮点运算数,理解为计算量。可以用来衡量算法/模型的复杂度。

描述一个深度学习框架/模型,除了精确度,通常用正向推理 计算量和参数个数(#Parameters)来描述复杂度

1-0
1-1

深度学习框架 FLOPs 的组成

  1. Conv1d/2d/3d (including grouping)
  2. ConvTranspose1d/2d/3d (including grouping)
  3. BatchNorm1d/2d/3d, GroupNorm, InstanceNorm1d/2d/3d
  4. Activations (ReLU, PReLU, ELU, ReLU6, LeakyReLU)
  5. Linear
  6. Upsample
  7. Poolings (AvgPool1d/2d/3d, MaxPool1d/2d/3d and adaptive ones)

其中,Conv所占的比重通常最大
和预处理之后网络的输入图像大小有关系
而 #Parameters和图像大小无关

关于网络模型 参数 和 计算量 统计,当前有如下两个大佬的作品可供使用


本博文简单解析,和试用,第二个代码


📔 pytorch-OpCounter GitHub 主页:


https://github.com/Lyken17/pytorch-OpCounter


🟧 How to install
pip install thop
🟨 How to use
  • Basic usage
from torchvision.models import resnet50
from thop import profile
model = resnet50()
input = torch.randn(1, 3, 224, 224) 
macs, params = profile(model, inputs=(input, ))
  • Define the rule for 3rd party module.
class YourModule(nn.Module):
    # your definition
def count_your_model(model, x, y):
    # your rule here

input = torch.randn(1, 3, 224, 224)
macs, params = profile(model, inputs=(input, ), 
                        custom_ops={YourModule: count_your_model})
  • Improve the output readability

设置参数的输出格式

from thop import clever_format
macs, params = clever_format([macs, params], "%.3f")

📕 运行该项目评估代码


python benchmark/evaluate_famous_models.py 

运行输出如下

ModelParams(M)FLOPs(G)
alexnet61.100.71
densenet1217.982.87
densenet16128.687.79
densenet16914.153.40
densenet20120.014.34
googlenet6.621.50
inception_v323.835.73
mobilenet_v23.500.31
resnet10144.557.83
resnet15260.1911.56
resnet1811.691.82
resnet3421.803.67
resnet5025.564.11
resnext101_32x8d88.7916.48
resnext50_32x4d25.034.26
shufflenet_v2_x0_51.370.04
shufflenet_v2_x1_02.280.15
shufflenet_v2_x1_53.500.30
shufflenet_v2_x2_07.390.59
squeezenet1_01.250.82
squeezenet1_11.240.35
vgg11132.867.62
vgg11_bn132.877.63
vgg13133.0511.32
vgg13_bn133.0511.35
vgg16138.3615.48
vgg16_bn138.3715.51
vgg19143.6719.65
vgg19_bn143.6819.68

python benchmark/evaluate_rnn_models.py 

运行输出如下

ModelParams(M)FLOPs(G)
RNNCell0.350.01
GRUCell1.040.03
LSTMCell1.380.04
RNN0.351.11
GRU1.043.32
LSTM1.384.43
stacked-RNN1.926.15
stacked-GRU5.7618.49
stacked-LSTM7.6824.64
BiRNN0.692.21
BiGRU2.076.65
BiLSTM2.768.86
stacked-BiRNN5.4117.34
stacked-BiGRU16.2452.07
stacked-BiLSTM21.6669.42

📗 自己实测的一个代码(该代码无法直接运行)


使用 from thop import profile 方法进行统计

input = torch.randn([1, self.img_ch, self.img_size, self.img_size]).to(self.device)
print('input size:')
print(input.size())

print(input)

macs, params = profile(self.disA, inputs=(input,))
name = 'disA'
print("%s | %s | %s" % ("Model", "Params(M)", "FLOPs(G)"))
print("---|---|---")
print("%s | %.2f | %.2f" % (name, params / (1000 ** 2), macs / (1000 ** 3)))


real_A_ae = self.disA(input)
macs, params = profile(self.gen2B, inputs=(real_A_ae,))

print()
name = 'gen2B'
print("%s | %s | %s" % ("Model", "Params(M)", "FLOPs(G)"))
print("---|---|---")
print("%s | %.2f | %.2f" % (name, params / (1000 ** 2), macs / (1000 ** 3)))

ModelParams(M)FLOPs(G)
disA0.170.73
ModelParams(M)FLOPs(G)
gen2B8.1033.78

这里属个人笔记,和本部分内容无关

  • 这个示例只是说明,对于 精简网络层之后的 NiceGAN测试阶段 判别器的层(共用作为编码层) 参数量极少;
  • 主要还是生成器在运算;

📘 yolov5s 网络模型参数量、计算量统计


🟧 代码修改

对 YOLOv5 有兴趣,可简单查阅我的这篇博文


YOLOv5 环境搭建 | coco128 训练示例 |❤️ 详细记录❤️ |【YOLOv5】


本部分,基础步骤如下

5-0

推理输出如下,可以发现 yolov5 本身yolov5-5.0/utils/torch_utils.py 下 model_info 方法已对 参数和计算量进行统计,对比可以发现

  • parameters 数值一致
  • 计算量 GFLOPS 存在差异 【未深入探究,需要对比 model_info 方法实现】
  • GFLOPS 数值和 送入模型 input 的 shape 正相关
  • 这里的 yolov5s 模型支持动态尺寸【预处理之后,input 宽高为 N 的整数倍数】图像处理
  • 均使用 from thop import profile 下方法进行的统计
python detect.py --source data/images/bus.jpg 

Namespace(agnostic_nms=False, augment=False, classes=None, conf_thres=0.25, device='', exist_ok=False, img_size=640, iou_thres=0.45, name='exp', nosave=False, project='runs/detect', save_conf=False, save_txt=False, source='data/images/bus.jpg', update=False, view_img=False, weights='yolov5s.pt')
YOLOv5 🚀 2021-4-12 torch 1.8.1+cu111 CUDA:0 (Quadro RTX 5000, 16125.3125MB)


Fusing layers... 
# 代码本身统计 ,欢迎补充
Model Summary: 224 layers, 7266973 parameters, 0 gradients, 17.0 GFLOPS



# 自定义方法,参数量、计算量统计输出
 
Model | Params(M) | FLOPs(G)
---|---|---
yolov5s | 7.26697300 | 6.37915530
640x480 4 persons, 1 bus, 1 fire hydrant, Done. (0.040s)
Results saved to runs/detect/exp11
Done. (0.162s)

相关代码如下

import torch
from thop import profile

# ...

"""add moli yolov5s 参数量、计算量统计  start """
print("yolov5s 参数量、计算量统计 \n")
total_ops, total_params = profile(model, inputs=(img,))
name = "yolov5s"

print("%s | %s | %s" % ("Model", "Params(M)", "FLOPs(G)"))
print("---|---|---")
print("%s | %.8f | %.8f" % (name, total_params / (1000 ** 2), total_ops / (1000 ** 3)))
"""add moli yolov5s 参数量、计算量统计  End """

再或者,相关代码添加到 34行 # Load model 之后的位置,效果和上面方式一样

5-1

🟨 相关报错统计
  • 可能遇到的报错一
RuntimeError: Input type (torch.FloatTensor) and weight type (torch.cuda.FloatTensor) should be the same

解决方法是,input 类型需要指定 device , input = torch.randn(1, 3, 640, 480).to(device)

  • 可能遇到的报错二
RuntimeError: Sizes of tensors must match except in dimension 3. Got 15 and 16 (The offending index is 0)

原因是: input = torch.randn(1, 3, 640, 120).to(device) input 的 宽高无法被 N 【 盲猜 N = 32,欢迎修正 】 整除

9-8


📙 博主 AI 领域八大干货专栏、诚不我欺



📙 预祝各位 前途似锦、可摘星辰


  • 🎉 作为全网 AI 领域 干货最多的博主之一,❤️ 不负光阴不负卿 ❤️
  • ❤️ 过去的每一天、想必你也都有努力、祝你披荆斩棘、未来可期

9-9

### YOLOv8 模型参数量统计 为了统计 YOLOv8 的模型参数量以及推理速度,可以借助 PyTorch 提供的相关工具库来完成这一任务。以下是实现方法的具体说明: #### 使用 `thop` 库统计模型参数量计算复杂度 `thop` 是一个用于计算 PyTorch 模型浮点运算次数 (FLOPs) 和参数数量的第三方库。通过它能够轻松获取模型的各项指标。 安装依赖: ```bash pip install thop ``` 编写代码以统计模型参数量FLOPs: ```python from ultralytics import YOLO from thop import profile # 加载自定义或官方预训练模型 model = YOLO("yolov8n.pt").model # 替换为自己的模型路径或者名称 # 构造输入张量 input_tensor = model(torch.zeros(1, 3, 640, 640)) # 输入尺寸需与实际一致 # 计算 FLOPs参数量 flops, params = profile(model, inputs=(torch.randn(1, 3, 640, 640),)) print(f"FLOPs: {flops / 1e9:.2f} G") # 转化为 GFLOPs 显示 print(f"Parameters: {params / 1e6:.2f} M") # 转化为百万级显示 ``` 上述代码会输出模型的总参数量(单位:M 表示百万)和总的浮点数操作次数(单位:G 表示十亿)。这种方法适用于任何基于 PyTorch 实现的神经网络结构[^3]。 #### 测量模型的速度 对于测量模型推断时间,可以通过多次运行前向传播并取平均值得到较为精确的结果。下面是一个简单的例子展示如何测试单次预测所需的时间: ```python import time import torch device = 'cuda' if torch.cuda.is_available() else 'cpu' model.to(device) start_time = time.time() for _ in range(10): # 多次迭代减少偶然误差影响 input_data = torch.rand((1, 3, 640, 640)).to(device) output = model(input_data) end_time = time.time() average_inference_time = (end_time - start_time) * 1000 / 10 # 平均每帧耗时(ms) print(f"Inference Time per Frame: {average_inference_time:.2f} ms") ``` 这段脚本会在 GPU 或 CPU 上执行指定数量的正向传递循环,并打印每次处理一帧图像所需的毫秒级别时间[^2]。 综上所述,利用 `thop` 可方便快捷地得到修改版 YOLOv8 的理论性能数据;而通过手动记录前后时刻差则能直观反映其实战表现情况。
评论 26
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

墨理学AI

不必打赏,关注博主公众号即可

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

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

打赏作者

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

抵扣说明:

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

余额充值