1.模型复杂度衡量
- model size
- Runtime Memory
- Number of computing operations
-
model size
就是模型的大小,我们一般使用参数量parameter来衡量,注意,它的单位是个。但是由于很多模型参数量太大,所以一般取一个更方便的单位:兆(M) 来衡量(M即为million,为10的6次方)。比如ResNet-152的参数量可以达到60 million = 0.00006M。
有些时候,model size在实际计算时除了包含参数量以外,还包括网络架构信息和优化器信息等。比如存储一个一般的CNN模型(ImageNet训练)需要大于300MB。
这里你可能会有疑问:刚才的单位是M,怎么这里出来了个MB?是不是写错了?
肯定没有,我们需要注意这里的M和MB的换算关系:
比如说我有一个模型参数量是1M,在一般的深度学习框架中(比如说PyTorch),一般是32位存储。32位存储的意思就是1个参数用32个bit来存储。那么这个拥有1M参数量的模型所需要的存储空间的大小即为:1M * 32 bit = 32Mb = 4MB。因为1 Byte = 8 bit。
所以读到这里你应该明白说一个模型的model size,用M和MB其实是一样的意思。
那你可能还会有疑问:是不是一定要用32位存储?
这个问题很好,现在的quantization技术就是减少参数量所占的位数:比如我用8位存储,那么:
所需要的存储空间的大小即为:1M * 8 bit = 8Mb = 1MB。
更有甚者使用二值神经网络进一步减小参数量所占的位数(权值被限制为{-1, 1}或{-1, 0, 1}),后文有论文的链接,有空再专门介绍这个方法吧。下面简单介绍下参数量的计算方法:
卷积层参数量的计算方法:
- Run time Memory
就是模型实际运行时所占的内存。注意这个指标与只存储模型参数所占的存储空间的大小是不一样的,这个指标更大。这对于GPU来讲不算是问题,但是对于硬件能力极为有限的端侧设备来说就显得无法承受了。它的单位是兆字节 (MB)。
- Number of computing operations FLOPS MACs
就是模型的计算量,有FLOPs和MACs两种衡量的方式、简而言之,前者指的是乘加的数量,而后者指运算量。比如ResNet-152在前向传播一张256 * 256的图片的运算量可以达到20 GFLOPs。下面简单介绍下模型计算量的计算方法:
第1种:FLOPs:
卷积层FLOPs的计算方法:
只需在parameters的基础上再乘以feature map的大小即可,即对于某个卷积层,它的FLOPs数量为:
全连接层FLOPs的计算方法:
对于全连接层,由于不存在权值共享,它的FLOPs数目即是该层参数数目:
第2种:MACs:
MACs与FLOPs的关系:
设有全连接层为:
y = w[0]*x[0] + w[1]*x[1] + w[2]*x[2] + ... + w[n8]*x[8]
对于上式而言共有9次乘加,即9MACs(实际上,9次相乘、9-1次相加,但为了方便统计,将计算量近似记为9MACs。所以近似来看 。(需要指出的是,现有很多硬件都将乘加运算作为一个单独的指令)。
全连接层MACs的计算:
激活层MACs的计算:
激活层不计算MAC,计算FLOPs。假设激活函数为:
则计算量为 FLOPs(乘法,指数,加法,除法)。
在计算FLOPS时,我们通常将加,减,乘,除,求幂,平方根等计为单个FLOP。
但是,实际上,我们通常不计这些操作,因为它们只占总时间的一小部分。通常只计算矩阵乘法和点积(dot product),忽略激活函数的计算量。
卷积层MACC的计算:
关于这些指标,更详细的解读以及对应的代码实现可以参考:
科技猛兽:PyTorch 63.Coding for FLOPs, Params and Latency
coding实现 PyTorch 63.Coding for FLOPs, Params and Latency - 知乎
2.常见模型压缩方法
剪枝,量化,蒸馏,轻量化模块设计,低秩分解,加法网络等
- 剪枝就是通过去除网络中冗余的channels,filters, neurons, or layers以得到一个更轻量级的网络,同时不影响性能。 代表性的工作有:
奇异值分解SVD(NIPS 2014): Exploiting linear structure within convolutional networks for efficient evaluation
韩松(ICLR 2016): Deep compression: Compressing deep neural networks with pruning, trained quantization and huffman coding
(NIPS 2015): Learning both weights and connections for efficient neural network
频域压缩(NIPS 2016): Packing convolutional neural networks in the frequency domain
剪Filter Reconstruction Error(ICCV 2017): Thinet: A filter level pruning method for deep neural network compression
LASSO regression(ICCV 2017): Channel pruning for accelerating very deep neural networks
Discriminative channels(NIPS 2018): Discrimination-aware channel pruning for deep neural networks
剪枝(ICCV 2017): Channel pruning for accelerating very deep neural networks
neuron level sparsity(ECCV 2017): Less is more: Towards compact cnns
Structured Sparsity Learning(NIPS 2016): Learning structured sparsity in deep neural networks(ICCV 2017):清华张长水,黄高团队: Learning Efficient Convolutional Networks through Network Slimming
(ECCV 2020):得克萨斯大学奥斯汀分校团队: GAN Slimming: All-in-One GAN Compression by A Unified Optimization Framework
- 轻量化模块设计就是设计一些计算效率高,适合在端侧设备上部署的模块。 代表性的工作有:
Bottleneck(ICLR 2017): Squeezenet: Alexnet-level accuracy with 50x fewer parameters and 0.5 mb model size
MobileNet(CVPR 2017): Mobilenets: Efficient convolutional neural networks for mobile vision applications
ShuffleNet(CVPR 2018): Shufflenet: An extremely efficient convolutional neural network for mobile devices
SE模块(CVPR 2018): Squeeze-and-excitation networks
无参数的Shift操作(CVPR 2018): Shift: A zero flop, zero parameter alternative to spatial convolutions
Shift操作填坑(Arxiv): Shift-based primitives for efficientconvolutional neural networks
多用卷积核(NIPS 2018): Learning versatile filters for efficient convolutional neural networks
GhostNet(CVPR 2020): GhostNet: More features from cheap operations
- 蒸馏就是过模仿教师网络生成的软标签将知识从大的,预训练过的教师模型转移到轻量级的学生模型。 代表性的工作有:
Hinton(NIPS 2015): Distilling the knowledge in a neural network
中间层的特征作为提示(ICLR 2015): Fitnets: Hints for thin deep nets
多个Teacher(SIGKDD 2017): Learning from multiple teacher networks
两个特征得新知识再transfer(CVPR 2017): A gift from knowledge distillation: Fast optimization, network minimization and transfer learning
- 量化就是减少权重等的表示的位数,比如原来网络权值用32 bit存储,现在我只用8 bit来存储,以减少模型的Memory为原来的 ;更有甚者使用二值神经网络。 代表性的工作有:
量化:
(ICML 2015): Compressing neural networks with the hashing trick
(NIPS 2015): Learning both weights and connections for efficient neural network
(CVPR 2018): Quantization and training of neural networks for efficient integer-arithmetic-only inference
(CVPR 2016): Quantized convolutional neural networks for mobile devices
(ICML 2018): Deep k-means: Re-training and parameter sharing with harder cluster assignments for compressing deep convolutions
(CVPR 2019): Learning to quantize deep networks by optimizing quantization intervals with task loss
(CVPR 2019): HAQ: Hardware-Aware automated quantization with mixed precision.二值神经网络:
Binarized weights(NIPS 2015): BinaryConnect: Training deep neural networks with binary weights during propagations
Binarized activations(NIPS 2016): Binarized neural networks
XNOR(ECCV 2016): Xnor-net: Imagenet classification using binary convolutional neural networks
more weight and activation(NIPS 2017): Towards accurate binary convolutional neural network
(ECCV 2020): Learning Architectures for Binary Networks
(ECCV 2020): BATS: Binary ArchitecTure Search
- 低秩分解就是将原来大的权重矩阵分解成多个小的矩阵,而小矩阵的计算量都比原来大矩阵的计算量要小。 代表性的工作有:
低秩分解(ICCV 2017): On compressing deep models by low rank and sparse decomposition
乐高网络(ICML 2019): Legonet: Efficient convolutional neural networks with lego filters
奇异值分解(NIPS 2014): Exploiting Linear Structure Within Convolutional Networks for Efficient Evaluation
- 加法网络就是:利用卷积所计算的互相关性其实就是一种“相似性的度量方法”,所以在神经网络中用加法代替乘法,在减少运算量的同时获得相同的性能。 代表性的工作有:
(CVPR 20): AdderNet: Do We Really Need Multiplications in Deep Learning?
(NIPS 20): Kernel Based Progressive Distillation for Adder Neural Networks
(Arxiv): AdderSR: Towards Energy Efficient Image Super-Resolution
参考链接:
深入浅出的模型压缩:你一定从未见过如此通俗易懂的Slimming操作