0


关于 FLOPS、FLOPs、参数量的相关计算

关于 FLOPS、FLOPs、参数量的相关计算

写在前面
  最近找到一些计算FLOPs的文章,奈何全是水文,讲都讲不清楚,完完全全的究极缝合怪。因此,这里准备彻底搞懂。

参考:CNN 模型所需的计算力(flops)和参数(parameters)数量是怎么计算的?

2023.3.12更新:

  • thop 库计算 MACs 和 FLOPs 示例代码
  • 最新一篇参数量计算博文,无需安装 pip 包:三行代码计算模型参数量

一、FLOPS

  FLOPS:全称:FLoating point Operations Per Second的缩写,即每秒浮点运算次数,或表示为计算速度。是一个衡量硬件性能的指标。通俗点讲 显卡算力,对应英伟达官网的那些:GPU算力排行榜。

二、FLOPs

  这才是本文的重点,FLOPs:FLoating point OPerationS 即 浮点计算次数,包含乘法和加法,只和模型有关,可以用来衡量其复杂度。多提一嘴,论文里面的FLOPs有的计算也并不明确,包括很多 Github 开源代码里面采用的 MACs,也就是考虑一次乘+加法运算为一次 MAC,粗略换算的话:

  1. FLOPs
  2. =
  3. 2
  4. ×
  5. MAC
  6. \text{FLOPs} = 2\times\text{MAC}
  7. FLOPs=2×MAC。建议发表的论文还是按照 FLOPs 来给出,因为我看的大部分文章都是用的这个,而不是 MACs

2.1 2D 卷积运算

FLOPs

就单纯的 2D 卷积而言,举例:

  1. Conv2d
  2. (
  3. C
  4. o
  5. u
  6. t
  7. ,
  8. C
  9. i
  10. n
  11. ,
  12. k
  13. e
  14. r
  15. n
  16. e
  17. l
  18. =
  19. K
  20. ,
  21. s
  22. t
  23. r
  24. i
  25. d
  26. e
  27. =
  28. S
  29. ,
  30. p
  31. a
  32. d
  33. d
  34. i
  35. n
  36. g
  37. =
  38. P
  39. ,
  40. b
  41. i
  42. a
  43. s
  44. =
  45. F
  46. a
  47. l
  48. s
  49. e
  50. )
  51. \text{Conv2d}(C_{out}, C_{in}, kernel= K, stride= S, padding= P, bias=False)
  52. Conv2d(Cout​,Cin​,kernel=K,stride=S,padding=P,bias=False)

输入 Feature map:

  1. (
  2. B
  3. ,
  4. C
  5. i
  6. n
  7. ,
  8. W
  9. i
  10. n
  11. ,
  12. H
  13. i
  14. n
  15. )
  16. (B, C_{in}, W_{in}, H_{in})
  17. (B,Cin​,Win​,Hin​),输出 Feature map
  18. (
  19. B
  20. ,
  21. C
  22. o
  23. u
  24. t
  25. ,
  26. W
  27. o
  28. u
  29. t
  30. ,
  31. H
  32. o
  33. u
  34. t
  35. )
  36. (B, C_{out}, W_{out}, H_{out})
  37. (B,Cout​,Wout​,Hout​),计算如下:
  38. FLOPs
  39. =
  40. (
  41. 2
  42. ×
  43. C
  44. i
  45. n
  46. ×
  47. K
  48. 2
  49. 1
  50. )
  51. ×
  52. W
  53. o
  54. u
  55. t
  56. ×
  57. H
  58. o
  59. u
  60. t
  61. ×
  62. C
  63. o
  64. u
  65. t
  66. \text{FLOPs}=\left(2\times{C_{in}}\times{K}^2-1\right)\times{W_{out}}\times{H_{out}}\times{C_{out}}
  67. FLOPs=(2×Cin​×K21Wout​×Hout​×Cout

注意 (.) 里面的 -1 ,如果 bias = True,则不需要 -1。将 (.) 拆分为 乘法和加法:

  1. FLOPs
  2. =
  3. [
  4. (
  5. C
  6. i
  7. n
  8. ×
  9. K
  10. 2
  11. )
  12. +
  13. (
  14. C
  15. i
  16. n
  17. ×
  18. K
  19. 2
  20. 1
  21. )
  22. ]
  23. ×
  24. W
  25. o
  26. u
  27. t
  28. ×
  29. H
  30. o
  31. u
  32. t
  33. ×
  34. C
  35. o
  36. u
  37. t
  38. \text{FLOPs}=\left[\left({C_{in}}\times{K}^2\right)+\left({C_{in}}\times{K}^2-1\right)\right]\times{W_{out}}\times{H_{out}}\times{C_{out}}
  39. FLOPs=[(Cin​×K2)+(Cin​×K21)]×Wout​×Hout​×Cout

第一个 (.) 里面是乘法,第二个是加法,如果 n 个数相加,做 n - 1 次加法运算,因此当 bias = True 时,刚好和 -1 抵消掉。

Parameters

  参数量的计算要简单些:

  1. Paras
  2. =
  3. K
  4. ×
  5. K
  6. ×
  7. C
  8. i
  9. n
  10. ×
  11. C
  12. o
  13. u
  14. t
  15. +
  16. C
  17. o
  18. u
  19. t
  20. \text{Paras}=K\times{K}\times{C_{in}}\times{C_{out}}+C_{out}
  21. Paras=K×K×Cin​×Cout​+Cout

同样注意:如果 bias = True,

  1. +
  2. C
  3. o
  4. u
  5. t
  6. +C_{out}
  7. +Cout​,如果 bias = False,去掉
  8. +
  9. C
  10. o
  11. u
  12. t
  13. +C_{out}
  14. +Cout​。

2.2 全连接层

FLOPs

线性全连接层,举例:

  1. L
  2. i
  3. n
  4. e
  5. r
  6. (
  7. C
  8. i
  9. n
  10. ,
  11. C
  12. o
  13. u
  14. t
  15. ,
  16. b
  17. i
  18. a
  19. s
  20. =
  21. F
  22. a
  23. l
  24. s
  25. e
  26. )
  27. Liner(C_{in}, C_{out}, bias = False)
  28. Liner(Cin​,Cout​,bias=False),输入 sequence
  29. (
  30. B
  31. ,
  32. n
  33. u
  34. m
  35. ,
  36. C
  37. i
  38. n
  39. )
  40. (B, num, C_{in})
  41. (B,num,Cin​),输出 sequence
  42. (
  43. B
  44. ,
  45. n
  46. u
  47. m
  48. ,
  49. C
  50. o
  51. u
  52. t
  53. )
  54. (B, num, C_{out})
  55. (B,num,Cout​),计算如下:

$

  1. FLOPs
  2. =
  3. (
  4. 2
  5. ×
  6. C
  7. i
  8. n
  9. 1
  10. )
  11. ×
  12. C
  13. o
  14. u
  15. t
  16. \text{FLOPs}=\left(2\times{C_{in}}-1\right)\times{C_{out}}
  17. FLOPs=(2×Cin​−1Cout

其中

  1. 2
  2. 2
  3. 2 代表乘法和加法。同上,当 bias = False 时,-1bias = True时,无 -1

Parameters

全连接层参数:

  1. Paras
  2. =
  3. C
  4. i
  5. n
  6. ×
  7. C
  8. o
  9. u
  10. t
  11. +
  12. C
  13. o
  14. u
  15. t
  16. \text{Paras}={C_{in}}\times{C_{out}}+C_{out}
  17. Paras=Cin​×Cout​+Cout

同样注意:当 bias = True,

  1. +
  2. C
  3. o
  4. u
  5. t
  6. +C_{out}
  7. +Cout​,当 bias = False,去掉
  8. +
  9. C
  10. o
  11. u
  12. t
  13. +C_{out}
  14. +Cout​。

2.3 BatchNorm2D 层

FLOPs

由于 BatchNorm2D 层经常和卷积层连用,参考:论文阅读笔记:看完也许能进一步了解Batch Normalization,而在程序里面,这两个可以合并运算,因此不会增加 FLOPs。当然如果是 BatchNorm2D 在前,卷积在后,通用需要考虑 BatchNorm2D 层。

Parameters

对于每一个通道来说,可学习的参数有 2 个,动量

  1. γ
  2. \gamma
  3. γ、动量偏移
  4. β
  5. \beta
  6. β。

2.4 激活层

  对于 ReLU 来说,由于其本身性质,不涉及 MAC 运算,因此只考虑 FLOPs。而FLOPs 相对来说较小,所以一般不计算或者想其他办法计算。提一嘴,在推理时哪会用得到sigmoid呢。
激活层没有参数。

三、Github 自动计算 Parameters、MACs 的工具

3.1 thop

官网:Github
安装:

  1. pip install thop

使用举例:

  1. import torch
  2. from torchvision.models import resnet50
  3. from thop import profile
  4. model = resnet50()input= torch.randn(1,3,224,224)
  5. macs, params = profile(model, inputs=(input,))print("MACs=",str(macs /1e9)+'{}'.format("G"))print("MACs=",str(macs /1e6)+'{}'.format("M"))

自定义计算规则举例:

  1. import torch
  2. from thop import profile
  3. classYourModule(nn.Module):# 自定义模型defcount_your_model(model, x, y):# 自定义计算规则input= torch.randn(1,3,224,224)
  4. macs, params = profile(model, inputs=(input,),
  5. custom_ops={YourModule: count_your_model})print("MACs=",str(macs /1e9)+'{}'.format("G"))print("MACs=",str(macs /1e6)+'{}'.format("M"))

优点:对于某个层的调试来说,很方便,比如 nn.Conv2D。
缺点:自定义的层,如 nn.Sequential()、nn.ModuleList() 这些容器层计算不了,需要自定义规则。

3.2 ptflops

官网:Github
安装:

  1. pip install ptflops

使用举例:

  1. import torch
  2. from torchvision.models import resnet50
  3. from ptflops import get_model_complexity_info
  4. model = resnet50()
  5. macs, params = get_model_complexity_info(model,(3,200,280), as_strings=True,
  6. print_per_layer_stat=True, verbose=True)print("MACs=",str(macs /1e9)+'{}'.format("G"))print("MACs=",str(macs /1e6)+'{}'.format("M"))

优点:对于某个层的调试来说,很方便,比如 nn.Conv2D这些。另外 print_per_layer_stat = True 可以打印每一层的结构
缺点:自定义的层,如 nn.Sequential()、nn.ModuleList() 这些容器层计算不了。另外输入没有 batch维度,给出 shape 即可。

3.3 其他

  还有一些其他的库,基本上和上面两种差不多,但缺点也很明显,自己写的卷积层可能压根计算不了。
  举例:Github

四、尚未完结,需要时再补充~

写在后面
  CSDN 灌水的人太多了,关键很多是错的,无语~~


本文转载自: https://blog.csdn.net/qq_38929105/article/details/123847385
版权归原作者 乄洛尘 所有, 如有侵权,请联系我们删除。

“关于 FLOPS、FLOPs、参数量的相关计算”的评论:

还没有评论