计算FLOPs和param

概念

网络中的参数量(param)对应与空间Space概念,及空间复杂度。
浮点计算量(FLOPs)对应与时间Time概念,对应于时间复杂度。

如何计算网络中的参数量(param)

网络中的参数量(param)的计算需要分为:卷积层,池化层,全连接层

卷积层

需要关注的参数为:卷积核大小(kernel_size=k*k)输入通道大小(in_channel)输出通道大小(out_channel)
计算公式:
完全版:conv_param=(k*k*in_channel+bias)*out_channel,默认bias=1,out_channel是filter(代表卷积核个数),且每个卷积核都有对应的bias。

举个例子:
image_size = 5x5x3
kernel_size = 3x3
in_channel = 3 (图像channel)
out_channel = 2 (卷积核数目\filter数目)
则该卷积层的参数个数为:
conv_param = ( kernel_size * in _channel + bias ) * out_channel = (5*3+1)*2 =152

池化层

池化层不需要参数。例如 max_pooling:直接最大化池化就可以,无需参数。

全连接层

全连接层有两种情况,一种是卷积层到全连接层,一种是全连接层到全连接层,因此需要分情况来讨论:

卷积层–全连接层

Conv_FC_param = feturemap_size * in_channel * out_neural

feturemap_size : 前一层特征图尺寸
in_channel : 前一层卷积核个数
out_neural : 全连接层神经元个数

全连接层–全连接层

FC_FC_param = in_neura * out_neural − bias
bias = out_neural,每个神经元都有一个bias。一般可忽略bias。

如何计算网络中的计算量

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

我们知道,通常我们去评价一个模型时,首先看的应该是它的精确度,当你精确度不行的时候,你和别人说我的模型预测的多么多么的快,部署的时候占的内存多么多么的小,都是白搭。但当你模型达到一定的精确度之后,就需要更进一步的评价指标来评价你模型:1)前向传播时所需的计算力,它反应了对硬件如GPU性能要求的高低;2)参数个数,它反应所占内存大小。为什么要加上这两个指标呢?因为这事关你模型算法的落地。比如你要在手机和汽车上部署深度学习模型,对模型大小和计算力就有严格要求。模型参数想必大家都知道是什么怎么算了,而前向传播时所需的计算力可能还会带有一点点疑问。所以这里总计一下前向传播时所需的计算力。它正是由FLOPs体现,那么FLOPs该怎么计算呢?

假设卷积核的大小为 k*k, 输入channel为M,输出channel为N,输出feature的宽为W,高为H。

bias为True时:
则计算量为:Flops = [2×(k×k×M) ] ×N×H×W
其中 k×k×M 为卷积中的乘法操作,k×k×M-1为卷积中的加法操作, + 1 为有bias。

bias为False时:
则参数数量为:Flops = (2×k×k×M-1) ×N×H×W

当使用BN时,还有两个可学习的参数α和β,参数量均为N
则参数数量为:Para = Flops = [(2×k×k×M-1) + 3 ] ×N×H×W

全连接层的计算量计算
假设 输入神经元数为M,输出神经元数为N,则

bias为True时:
则计算量为:FLOPs = [M+(M-1)+1]×N = 2 × M × N

bias为False时:
则参数数量为:Para = [M+(M-1)]×N = (2M-1)×N

实例计算_以lenet为例

简化计算,次Lenet中不适用激活函数ReLU函数
在这里插入图片描述

手动计算

在这里插入图片描述

代码

import torch
from torch import nn


class CNN(nn.Module):
    def __init__(self):
        super(CNN, self).__init__()
        self.conv1 = nn.Sequential(  # input shape (1, 28, 28)
            nn.Conv2d(
                in_channels=1,  # input height  gray just have one level
                out_channels=20,  # n_filters
                kernel_size=5,  # filter size
                stride=1,  # filter movement/step
                padding=0
            ),  # output shape (20, 24, 24)
            #nn.ReLU(),  # activation
            nn.MaxPool2d(kernel_size=1,stride=2,padding=0),  # choose max value in 2x2 area, output shape (16, 14, 14)
        )
        self.conv2 = nn.Sequential(  # input shape (16, 14, 14)
            nn.Conv2d(20, 50, 5, 1, 0),  # output shape (32, 14, 14)
            #nn.ReLU(),  # activation
            nn.MaxPool2d(1,stride=2),  # output shape (32, 7, 7)
        )
        # flatten
        # fc unit
        self.fc1 = nn.Sequential(
            nn.Linear(50*4*4,500),
            #nn.ReLU()
        )
        self.fc2 = nn.Sequential(
            nn.Linear(500,10),
            #nn.ReLU()
        )

    def forward(self, x):
        batchsz = x.size(0)
        x = self.conv1(x)
        x = self.conv2(x)

        x = x.view(batchsz, 50*4*4)

        x= self.fc1(x)
        logits = self.fc2(x)

        # # [b, 10]
        # pred = F.softmax(logits, dim=1)
        # loss = self.criteon(logits, y)

        return logits

构建一个CNN网络,如下图所示
在这里插入图片描述

使用开源工具 torchstat

from torchstat import stat
from main import CNN

# 导入模型,输入一张输入图片的尺寸
cnn=CNN()
print(cnn)
stat(cnn,(1, 28,28))

输出结果在这里插入图片描述

可直接使用 torchinfo 模块统计参数量

from torchinfo import summary
from main import CNN

# 导入模型,输入一张输入图片的尺寸
cnn=CNN()
batch_size = 1
summary(cnn, input_size=(batch_size, 1, 28, 28))

输出结果,如下图所示
在这里插入图片描述

使用开源工具 pytorch-OpCounter (推荐)

from main import CNN
import torch
# 导入模型,输入一张输入图片的尺寸
cnn=CNN()
from thop import profile
input = torch.randn(1, 1, 28, 28)
macs, params = profile(cnn, inputs=(input, ))
print('Total macc:{}, Total params: {}'.format(macs, params))
"""
Total macc:2307720.0, Total params: 431080.0
"""

在这里插入图片描述

  • 2
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值