从CNN卷积参数计算到模型加速方法

ぃ、小莉子 提交于 2020-08-16 19:21:15

一:CNN卷积参数计算

要对CNN卷积过程进行参数计算,首先得知道卷积操作过程中的权值是共享的,即卷积核的权重参数以及偏置参数在一次卷积过程中不改变,CNN卷积操作的过程如下图所示。

CNN卷积操作示意图

上述卷积过程的输入特征图尺寸为: (7*7*3);卷积核大小为: (3*3*3);输出的特征图尺寸为: (3*3*2),可以看出,神经网络网络学习参数即卷积核的权重参数以及偏置参数在卷积过程中不改变,所以CNN卷积参数量与输入输出特征图的尺寸无关,只与卷积核的大小数量以及输入与输出通道数相关。

卷积过程实际上是卷积核与特征图尺寸进行线性计算的过程公式如下: y_{i}=w_{i}\cdot x+b_{i}
,其中 w_{i}代表权重, b_{i}代表偏置,因为计算过程都是线性的,所以需要引入激活函数,增加网络的表达能力,而不是一味的线性叠加。

参数量即为权值 w_{0}w_{1} 以及偏置 b_{0}b_{1} 中参数个数总和。计算过程如下:卷积核的参数为: C_{i}\times k\times k\times C_{0}=3\times3\times3\times2=54 ,其中 k 为卷积核尺寸, C_{i} 输入通道个数, C_{0} 为输出通道个数。加上两个偏置参数,总的参数量为 :(C_{i}\times k\times k+1)\times C_{0}=(3\times3\times3+1)\times2=56

当然每一次搭建模型后,不需要我们来手动计算参数量的大小,各种框架下已经备好了相应命令,比如:在keras框架下,模型参数量可以直接通过model.summary()来进行模型架构和参数量的输出;在pytorch框架下,需要先安装第三方包torchsummary,然后通过如下命令进行输出网络结构参数量。

import torch
from torchsummary import summary
# 需要使用device来指定网络在GPU还是CPU运行
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
model = model().to(device)
summary(model, input_size=(3, 224, 224))

pytorch框架下,输出的效果如图所示。

网络结构及参数

二:模型加速方法

在神经网络模型的实际应用中,我们一方面追求模型具有较高的性能,一方面还需要控制模型的大小以便于部署到终端。模型的大小一方面取决于模型参数的多少,一方面取决于参数的数据类型。为了实现对模型的进一步压缩,当前流行的方法可以大致分为以下几个方面:轻量化模型设计、权重量化、BN层合并、网络剪枝、张量分解、知识蒸馏等等,本文主要从权重量化、轻量化模型设计这两个角度进行介绍。

1:权重量化主要指将网络中高精度参数量化为低精度参数,使得压缩模型大小从而加速计算。以pytorch框架为例,官方给出了7中CPU Tensor类型与8种GPU Tensor类型,具体如下表所示。

pytorch框架下Tensor类型

由于高精度的模型参数拥有更大的动态变化范围,表达更丰富的空间,因此在训练过程中,默认使用32位浮点数据类型torch.FloatTensor或torch.cuda.FloatTensor,为了减小模型的大小,通常可以转换为16位半精度浮点torch.cuda.HalfTensor。

具体操作代码如下:

data.cuda().half()
model.cuda().half()

2:轻量化模型设计主要指在模型一开始设计时就考虑一些轻量化的思想,比如常用的分组卷积、深度可分离卷积、实现通道降维的1*1卷积等方式,比较有代表性的模型SqueezeNet、MobileNet、ShuffleNet等。

SqueezeNet:主要是通过1*1卷积实现降维的方式,达到压缩目的,模型性能与AlexNet相近,但模型参数仅有AlexNet的1/50;其中SqueezeNet的基础模块Fire Module如下图。

SqueezeNet的基础模块Fire Module

整体结构如下图。

SqueezeNet整体结构

MobileNet:提出了一种更为高效的深度可分离卷积方式。标准卷积在卷积过程中,同时考虑了图像的区域与通道信息,而深度可分离卷积将区域与通道分开考虑,实现逐通道卷积,由于逐通道卷积缺少通道间的特征融合,后续还要继续连接一个1*1的卷积,改变通道数的同时,融合不同通道的特征。虽然深度可分离卷积过程分为了两步,但凭借轻量化卷积方式,总体计算量约为标准卷积的1/9,逐通道卷积的计算过程如下图。

逐通道卷积示意图

ShuffleNet:在MobileNet和ResNeXt等高性能网络中,1*1卷积占用了大量计算资源,ShuffleNet从优化网络结构的角度出发,利用组卷积与通道混洗的操作,有效的降低了1*1逐点卷积的计算量,通道混洗的做过过程如下图。

通道混洗示意图

具体实现如下图,包括Reshape、Transpose、Flatten三个过程,首先将输入通道的一个维度Reshape成两个维度,一个是卷积组数,一个是每个卷积组包含的通道数;然后将扩展出的两维进行置换;将置换后的通道Flatten平展后即可完成最后的通道混洗。

通道混洗具体操作

上述内容存若在不足之处,欢迎补充和交流。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!