(轉載)CNN 模型所需的計算力(FLOPs)和參數(parameters)數量計算

FLOPS:注意全大寫,是floating point operations per second的縮寫,意指每秒浮點運算次數,理解爲計算速度。是一個衡量硬件性能的指標。git

FLOPs:注意s小寫,是floating point operations的縮寫(s表複數),意指浮點運算數,理解爲計算量。能夠用來衡量算法/模型的複雜度。github

網上打字很容易全小寫,形成混淆,本問題針對模型,應指的是FLOPs。算法

如下答案不考慮activation function的運算。網絡

卷積層:(2\times C_{i} \times K^{2}-1)\times H\times W\times C_{o}session

Ci=input channel, k=kernel size, HW=output feature map size, Co=output channel.性能

2是由於一個MAC算2個operations。spa

不考慮bias時有-1,有bias時沒有-1。code

上面針對一個input feature map,沒考慮batch size。blog

理解上面這個公式分兩步,括號內是第一步,計算出output feature map的一個pixel,而後再乘以HWCo拓展到整個output feature map。括號內的部分又能夠分爲兩步, (2 \cdot C_{i}\cdot K^{2}-1)=(C_{i}\cdot K^{2})+(C_{i}\cdot K^{2}-1) ,第一項是乘法運算數,第二項是加法運算數,由於n個數相加,要加n-1次,因此不考慮bias,會有一個-1,若是考慮bias,恰好中和掉,括號內變爲 2 \cdot C_{i}\cdot K^{2}ci

 

全聯接層: (2\times I-1)\times O

I=input neuron numbers, O=output neuron numbers.

2是由於一個MAC算2個operations。

不考慮bias時有-1,有bias時沒有-1。

分析同理,括號內是一個輸出神經元的計算量,拓展到O了輸出神經元。

參考:chen liu

 

 

對於一個卷積層,假設其大小爲 h \times w \times c \times n (其中c爲#input channel, n爲#output channel),輸出的feature map尺寸爲 H' \times W' ,則該卷積層的

  • #paras = n \times (h \times w \times c + 1)
  • #FLOPS= H' \times W' \times n \times(h \times w \times c + 1)

即#FLOPS= H' \times W' \times #paras

參考:李珂

 

Model_size = 4*params  模型大小爲參數量的4倍

 

附:Pytorch計算FLOPs的代碼:

http://link.zhihu.com/?target=https%3A//github.com/Lyken17/pytorch-OpCounter

https://github.com/sovrasov/flops-counter.pytorch

神器(pytorch):

pytorch-OpCounter 用法:(pytorch版本>=1.0)

from torchvision.models import resnet50 from thop import profile model = resnet50() flops, params = profile(model, input_size=(1, 3, 224,224))

 

 

torchstat 用法:

from torchstat import stat import torchvision.models as models model = model.alexnet() stat(model, (3, 224, 224))

 

flopth 用法:

from flopth import flopth print(flopth(net, in_size=[3,112,112]))

 

ptflops用法:

from ptflops import get_model_complexity_info flops, params = get_model_complexity_info(net, (3, 224, 224), as_strings=True, print_per_layer_stat=True) print('Flops: ' + flops) print('Params: ' + params)

 

本身計算參數量:

print('Total params: %.2fM' % (sum(p.numel() for p in net.parameters())/1000000.0))

 

 須要注意的是:params只與你定義的網絡結構有關,和forward的任何操做無關。即定義好了網絡結構,參數就已經決定了。FLOPs和不一樣的層運算結構有關。若是forward時在同一層(同一名字命名的層)屢次運算,FLOPs不會增長。

 

 

參考:

輕量級神經網絡「巡禮」(一)—— ShuffleNetV2

相關文章
相關標籤/搜索