深度学习模型往往受到端计算力的限制,无法很好的部署在移动端或无法降低端的计算成本。例如自动驾驶的模型就过于巨大,而且往往是很多模型并行,所以一般会用一些加速的方法来降低推算的计算力要求。
加速方法有多种不同角度:网络结构,模型推理加速,模型剪枝,参数量化等。
Table of Contents
网络结构加速
模型推理加速
优化模型的推理顺序
降低参数精度加速
模型剪枝加速
参数量化
网络结构加速
所谓网络结构,就是使用结构更简单的网络,例如适用于移动端的网络mobilenet和mobilenet2等。
在普通卷积神经网络的基础上,mobilenet使用了拆分“滑窗遍历”和“纵向channel”的方法来减少模型参数量。
例:
普通卷积操作:5*5*3的卷积核去扫略9*9*3的特征向量时,一个卷积核的参数量应该是5*5*3(channel深度方向需要乘3),如果使用10个不同的卷积核,参数总量为:5*5*3*10 =750
mobilenet:对于9*9*3的特征向量,分别使用3个5*5的卷积核去卷积每一个channel,得到3个channel的特征向量,再用10个1*1*3的卷积核去卷积得到的特征向量来卷积获取深度方向的关联,同时同样得到10个channel的特征向量(和stride和padding无关),不过这样拆分的过程使用的参数总量为:5*5*3+1*1*3*10 =105,参数缩减了7倍多。
模型推理加速
NVIDIA推出的TensorRT工具可以进行模型推理层面的加速。
优化模型的推理顺序
上图是Google Inception模型的一个block,虽然是不同的卷积方式的组合,但是第一层3个都使用了1*1的卷积,实际上在推理过程中,这3个1*1的卷积可以同时调用相同的函数来计算,但是在没有优化之前,这三次1*1卷积需要调用三次相同的函数,这是可以优化的一个点,这种推理优化只是优化的推理的顺序,并不会影响模型推理的精度。
降低参数精度加速
通常,我们会使用Float32 单精度的浮点数来对参数初始化,在推理过程中,实际上可以将Float32转成Float16半精度或者INT8来对模型的推理进行加速。半精度或INT8的使用都需要有对应的硬件条件来使用。
TensorRT工具可以将Float32转成INT8格式并运行在相应的支持的GPU上。
这种降低参数精度加速的方法会影响一些推理的精度,需要权衡精度上的损失和速度上的加成。
模型剪枝加速
在模型推理时,实际上我们可以获取每一层,每一个单元的输出,观察这些输出往往会发现一些值为0或者近似0的数值,这些单元在模型的推理中并不起作用,可以将其“剪”掉。剪掉之后除了可以减少推理过程的计算之外,还可以对剪枝后的模型再训练几个epoch,得到新的模型的表现往往会比剪枝前更好。
参数量化
对4x4的卷积核里的参数进行k-means聚类,这里k=4,聚类完后得到两个矩阵,一个是聚类中心值,即每个种类参数的平均值;一个是卷积核参数的类别index,该index可以用2bit int格式存储。
所以存储空间从32bit*16—>32bit*4+2bit*16。
上图下方的梯度更新是在进行重新训练,目的是为了调整量化后的参数,提升一些精度(量化的过程会损失很多精度)。
Tip:有时不一定会对原来的参数一次性量化,会量化一部分,留下一部分(留下的部分可以是绝对值比较小的,需要设置一个阈值),然后对所有参数进行重新训练,得到新的参数后再量化一部分,循环迭代,直到所有参数被量化。
参考:/p/33408871
除了以上的方法外,还有知识蒸馏、低秩近似等。