欢迎关注我的公众号 [极智视界],获取我的更多经验分享
大家好,我是极智视界,本文来介绍一下 输入图片BatchSize和分辨率对模型计算量和参数量的影响。
邀您加入我的知识星球「极智视界」,星球内有超多好玩的项目实战源码下载,链接:t.zsxq.com/0aiNxERDq
在深度学习中,模型参数量和计算量是两个重要的考量因素。模型参数量指的是模型中的参数数量,对应于数据结构中空间复杂度的概念。而计算量则对应于时间复杂度的概念,与网络执行时间的长短有关。计算量的衡量指标主要是 FLOPs,也即浮点运算次数。这里有个坑,一定要区分开 FLOPs 和 FLOPS 的概念,FLOPs 是指 Floating-point Operations,即浮点运算次数,可以用来描述模型的计算量或者模型的时间复杂度;而 FLOPS 是指 Floating-point Operations Per Second,即每秒执行的浮点运算次数,一般是用来衡量芯片算力的。一个是量、一个是速度,需要分辨清楚。
拿芯片的算力 FLOPS 来说,按照数量级的不同,又有 MFLOPS、GFLOPS、TFLOPS 等之分 (同理会有 MFLOPs、GFLOPs…),然后如果是 int8/int4 量化的算力又有 TOPS 之类,如下,
- 1 MFLOPS(megaFLOPS)==> 每秒一百万(=10^6)次的浮点运算;
- 1 GFLOPS(gigaFLOPS)==> 每秒十亿(=10^9)次的浮点运算;
- 1 TFLOPS(teraFLOPS)==> 每秒一万亿(=10^12)次的浮点运算,也就是 1太拉;
- 1TOPS (teraOPS) ==> 每秒一万亿 (=10^12) 次运算 ==> 对于 int8/int4 量化的算力统计单位;
- 1 PFLOPS(petaFLOPS)==> 每秒一千万亿(=10^15)次的浮点运算;
- 1 EFLOPS(exaFLOPS)==> 每秒一百京(=10^18)次的浮点运算;
- 1 ZFLOPS(zettaFLOPS)==> 每秒十万京(=10^21)次的浮点运算;
另外还有个概念是 MACCs,全称是 Multiply-accumulate Operations,即乘-加操作次数,一般来说,MACCs 大约为 FLOPs 的一半。
有了上面的概念后,咱们继续。
在深度学习中,模型参数量和计算量有各自的优势和挑战。例如,增加参数量一般可以增加模型的表达能力,但同时也会增加模型的复杂度和计算量,这可能会影响模型的训练/部署速度和可解释性。因此,在模型优化过程中,需要综合考虑模型参数量和计算量以及权衡他们的关系。既然模型参数量和计算量这么重要,那么就需要有工具给他们先统计出来,这样算法优化的时候心里有个数。
下面介绍几种 pytorch 模型统计模型计算量和参数量的方法。咱们以 pytorch modelzoo 中的 MobileNetV2 来测试。
1> 使用 thop 库
首先安装 thop 库,如下,
pip install thop
然后执行计算统计:
import torch
import torchvision
from thop import profile
# load model
print('==> Loading model..')
model = torchvision.models.MobileNetV2()
dummy_input = torch.randn(1, 3, 320, 320)
flops, params = profile(model, (dummy_input,))
print('flops: ', flops, 'params: ', params)
print('flops: %.2f M, params: %.2f M' % (flops / 1000000.0, params / 1000000.0))
执行结果,如下,
==> Loading model..
[INFO] Register count_convNd() for <class 'torch.nn.modules.conv.Conv2d'>.
[INFO] Register count_normalization() for <class 'torch.nn.modules.batchnorm.BatchNorm2d'>.
[INFO] Register zero_ops() for <class 'torch.nn.modules.activation.ReLU6'>.
[INFO] Register zero_ops() for <class 'torch.nn.modules.container.Sequential'>.
[INFO] Register zero_ops() for <class 'torch.nn.modules.dropout.Dropout'>.
[INFO] Register count_linear() for <class 'torch.nn.modules.linear.Linear'>.
flops: 667008000.0 params: 3504872.0
flops: 667.01 M, params: 3.50 M
可以看到 in_shape 为 (1, 3, 320, 320) 的 MobileNetV2 的计算量是 667.01 MFLOPs,参数量是 3.50 M。这里先不比较输入图片的 BatchSize 和 图片分辨率对模型计算量和参数量的影响,先介绍统计方法。
2> 使用 ptflops 库
安装 ptflops 库,如下,
pip install ptflops
然后执行计算统计,
import torchvision
from ptflops import get_model_complexity_info
# load model
print('==> Loading model..')
model = torchvision.models.MobileNetV2()
flops, params = get_model_complexity_info(model, (3, 224, 224), as_strings=True, print_per_layer_stat=True)
print('flops: ', flops, 'params: ', params)
执行结果,如下,
...
(18): ConvBNActivation(
412.16 k, 11.760% Params, 20.26 MMac, 6.325% MACs,
(0): Conv2d(409.6 k, 11.687% Params, 20.07 MMac, 6.266% MACs, 320, 1280, kernel_size=(1, 1), stride=(1, 1), bias=False)
(1): BatchNorm2d(2.56 k, 0.073% Params, 125.44 KMac, 0.039% MACs, 1280, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(2): ReLU6(0, 0.000% Params, 62.72 KMac, 0.020% MACs, inplace=True)
)
)
(classifier): Sequential(
1.28 M, 36.549% Params, 1.28 MMac, 0.400% MACs,
(0): Dropout(0, 0.000% Params, 0.0 Mac, 0.000% MACs, p=0.2, inplace=False)
(1): Linear(1.28 M, 36.549% Params, 1.28 MMac, 0.400% MACs, in_features=1280, out_features=1000, bias=True)
)
)
flops: 320.3 MMac params: 3.5 M
这个方式会更加详细,模型中间每层的参数量都会打印出来,然后最后给出模型整体的计算量和参数量。这种方法对于想要看到中间层参数量的情况比较合适,Log 信息比较丰富。
3> 使用 pytorch_model_summary 库
安装 pytorch_model_summary 库, 如下,
pip instlal pytorch_model_summary
然后执行计算统计,
import torch
import torchvision
from pytorch_model_summary import summary
# load model
print('==> Loading model..')
model = torchvision.models.MobileNetV2()
dummy_input = torch.randn(1, 3, 224, 224)
print(summary(model, dummy_input, show_input=False, show_hierarchical=False))
执行结果,如下,
==> Loading model..
-----------------------------------------------------------------------------
Layer (type) Output Shape Param # Tr. Param #
=============================================================================
Conv2d-1 [1, 32, 112, 112] 864 864
BatchNorm2d-2 [1, 32, 112, 112] 64 64
ReLU6-3 [1, 32, 112, 112] 0 0
InvertedResidual-4 [1, 16, 112, 112] 896 896
InvertedResidual-5 [1, 24, 56, 56] 5,136 5,136
InvertedResidual-6 [1, 24, 56, 56] 8,832 8,832
InvertedResidual-7 [1, 32, 28, 28] 10,000 10,000
InvertedResidual-8 [1, 32, 28, 28] 14,848 14,848
InvertedResidual-9 [1, 32, 28, 28] 14,848 14,848
InvertedResidual-10 [1, 64, 14, 14] 21,056 21,056
InvertedResidual-11 [1, 64, 14, 14] 54,272 54,272
InvertedResidual-12 [1, 64, 14, 14] 54,272 54,272
InvertedResidual-13 [1, 64, 14, 14] 54,272 54,272
InvertedResidual-14 [1, 96, 14, 14] 66,624 66,624
InvertedResidual-15 [1, 96, 14, 14] 118,272 118,272
InvertedResidual-16 [1, 96, 14, 14] 118,272 118,272
InvertedResidual-17 [1, 160, 7, 7] 155,264 155,264
InvertedResidual-18 [1, 160, 7, 7] 320,000 320,000
InvertedResidual-19 [1, 160, 7, 7] 320,000 320,000
InvertedResidual-20 [1, 320, 7, 7] 473,920 473,920
Conv2d-21 [1, 1280, 7, 7] 409,600 409,600
BatchNorm2d-22 [1, 1280, 7, 7] 2,560 2,560
ReLU6-23 [1, 1280, 7, 7] 0 0
Dropout-24 [1, 1280] 0 0
Linear-25 [1, 1000] 1,281,000 1,281,000
=============================================================================
Total params: 3,504,872
Trainable params: 3,504,872
Non-trainable params: 0
-----------------------------------------------------------------------------
这个方法只能得到参数量,但是其中的参数量信息会更加详细,还区分训练参数和非训练参数。
上面介绍了三种统计模型计算量和参数量的方法,使用起来非常之简便。现在对于 pytorch 模型,应该可以轻松统计出它的计算量和参数量了吧。接着来分析试验一下输入图片的 BatchSize 和图片分辨率对模型计算量和参数量的影响,这里有很容易想当然的坑。我们来看,对于同样的 MobileNetV2 模型,控制输入图片的 BatchSize 在 1 和 32,控制图片分辨率在 (224, 224) 和 (320, 320)。然后采用上面介绍的方法统计模型对应的计算量和参数量,整理汇总如下,
来分析一下,可以看到模型的 “参数量” 真的是 “我自巍然不动”,不论是 BatchSize 还是分辨率怎么变,参数量就是不变,这个是很容易想当然搞错的。其实我们再仔细想想,比如拿卷积层来说,它的参数量计算方式是 k*k*c_in*c_out
,可以看到只是跟卷积核有关,跟输入数据是没有关系的,理解这个可能就理解 “为什么参数量巍然不动” 了。然后看计算量,还是拿卷积层举例,卷积层的计算量的计算方式是 k*k*c_in*c_out*h*w
,可以看到计算量的计算是要考虑输入图宽高的。这个道理放大到整个模型计算量的计算,当然也是会和输入图片的大小 (分辨率)、多少 (BatchSize) 有关系了。这样思考后,再看上面表格中计算量的数据,随着输入图片分辨率的增大而增加 (符合预期)、随着输入图片 BatchSize 的增大而增加,且是倍数增加关系 (也符合预期)。
完美。
好了,以上分享了 输入图片BatchSize和分辨率对模型计算量和参数量的影响,希望我的分享能对你的学习有一点帮助。
【公众号传送】
畅享人工智能的科技魅力,让好玩的AI项目不难玩。邀请您加入我的知识星球, 星球内我精心整备了大量好玩的AI项目,皆以工程源码形式开放使用,涵盖人脸、检测、分割、多模态、AIGC、自动驾驶、工业等。不敢说会对你学习有所帮助,但一定非常好玩,并持续更新更加有趣的项目。 t.zsxq.com/0aiNxERDq