一、算法概述
1.1 svd分解
1.1.1 问题引出:对仿射变换进行降维线性近似
对一个卷积层来说,卷积的输出响应可表示为,其中扩展成 ,扩展成,为输入通道个数,为卷积核大小,为输出通道个数。
在假设输出响应是一个低秩空间下,存在低秩的矩阵,使得,其中为的均值,因此,输出响应可重写为:
其中,。低秩的可分解成两个矩阵的乘积,即,其中,于是可得,
其中,。因此,可使用两个卷积层(卷积核分别为和 )来近似原来的卷积层,该近似的完成还存在两个问题:
- 矩阵如何求解?
- 如何分解?
- 使用优化问题来求解:
该优化问题可用svd求解:
令为减去均值后的N个响应,协方差矩阵(根据协方差矩阵定义推导)。
2.上述矩阵的分解可用svd:,因此
1.1.2 推广: 对加入非线性(relu)层的卷积层进行降维近似
上述输出响应近似推广到非线性输出响应的近似,则优化问题可变为:
解上述优化问题具有挑战性,因此可用通过求解近似优化问题来求解:
这里当时,等价于原优化问题。使用迭代的方法分别优化和
- 固定,求解;
当固定时,最小化目标函数可得,则优化问题变为:
该优化问题与线性时的优化问题相似,但是这里有两个响应集,重写优化问题可得:
此处的响应集均是减均值之后的结果,该问题可用GSVD求解。
- 固定,求解; 当固定后,可逐元素的优化:
1.1.3 减小逐层误差累积: 非对称分解思路
为了防止底层近似误差累积都深层,采用非对称方法来解决该问题,优化问题变成:
其中是该层的近似输入,因此是近似输出。解该优化问题如非线性情况。
1.1.4 选择最优的衰减通道数
上述优化问题中是决定近似层复杂度的唯一参数,每一层的冗余不同,因此不同层应合理的选择适当的参数值。
经验上PCA能量与分类准确率有关,定义目标函数:
其中,表示层第大的特征值,是近似之前的复杂度,是期望的近似之后的总复杂度。该优化可用贪心算法求解。
1.2 卷积核分解
1.2.1 scheme2
基于事实:不同的卷积核与通道之间存在冗余。
基于思想:每个卷积层可分解成一系列的两个子空间矩形卷积层,第一个卷积层有个卷积核,第二层有个卷积核。
因此原始的卷积核可近似为:
因此能得到优化问题:
使用共轭梯度法解该优化问题。
1.3 组合使用svd分解与卷积核分解
思路:先使用核分解将卷积层分解成和的卷积核,再使用通道近似的方法,将的卷积核近似成和的卷积核。
二、实现步骤
2.1 脚本说明
compute_d.py 通道数的选择
solve_linear_PWb_space.py 通道线性分解
solve_nonlinear_PWb.py 通道非线性分解
asymmetric.py 通道非对称分解
cgd_sch2.py 核分解
2.2 svd分解步骤
1、导出需要分解层的feature map和权重:
1.1 导出要分解层的feature map存成.h5文件(3000-6000幅图),每幅图feature map 为三维(feature_size, feature_size, output_channel)
feature map文件:feature_map/conv1_1/imgname.h5
注意:feature map为三维(feature high,feature width,outputchannel),一般每层feature map取3000-6000幅为宜
1.2 将权重文件转成.pkl文件,以convname_w.pkl和convname_b.pkle命名
权重文件:Wbs/conv1_1_w.pkl Wbs/conv1_1_b.pkl
2、通道分解:
2.1 选择每层减少通道数de_ch:
计算每层yyt的值,脚本solve_linear_PWb_space.py中已有相关计算,结果存于solution/solution_linear/conv1_1/accelerating_linear_Mb.pkl
修改相应的卷积层名称layers,和原始复杂度计算Complexity
修改输入文件名:init_dir 为accelerating_linear_Mb.pkl的地址
设置期望近似后的复杂度 Complexity_predict=Complexity_total*0.4
$ python compute_d.py 打印出每层减少通道后的通道数
2.2 分别修改solve_linear_PWb_space.py、solve_nonlinear_PWb.py、asymmetric.py中每个feature map随机采样点数randsize=4,和输入文件地址:
indir --- feature_map 地址
wdir --- conv1_1_w.pkl地址
bdir --- conv1_1_b.pkl 地址
2.3 线性、非线性和非对称分别执行:
$ python solve_linear_PWb_space.py --layer=conv1_1 --de_ch=16 --batch_size=6000
$ python solve_nonlinear_PWb.py --layer=conv1_1 --de_ch=16 --batch_size=6000
$ python asymmetric.py --layer=conv1_1 --de_ch=16 --batch_size=6000
其中,layer为要分解卷积层,de_ch为减少通道数,batch_size为feature map的个数。
注意:非对称分解需要输入上一层近似之后的feature map,因此分解一层都要导出前面都近似之后的feature map,且该feature map要和原始的feature map相对应。
2.4 分解好的权重文件存放在solution目录下:
线性:solution_linear/conv1_1/accelerating_linear_PWb.pkl
非线性:solution_nonlinear/conv1_1/accelerating_nonlinear_PWb.pkl
非对称:solution_asy/conv1_1/acceleratin_asy_PWb.pkl
2.5 修改网络,测试精度:
将分解层网络(3 * 3,outchannel)改成(3 * 3,de_ch)+ (1 * 1,outchannel),并导入相应层分解后的权重,测试精度
2.3 卷积核分解步骤
1 修改cgd_sch2.py中输入文件地址:
wdir = 'Wbs/' + FLAGS.layer + '_w.pkl' 权重文件
bdir = 'Wbs/' + FLAGS.layer + '_b.pkl' bias文件
2 $ Python cgd_sch2.py –layer=conv1_1 –de_ch=16
其中,layer为要分解卷积层,de_ch为减少通道数
3 分解好的权重文件solution/cgd/conv1_1/sch2_HV_cgd_step10.pkl
4 修改网络,测试精度:
将(3 * 3, outchannel)改成(3 * 1, de_ch) + (1 * 3, outchannel),并导入相应层分解后的权重文件,测试精度
三、注意
由于svd分解是基于对feature map冗余信息的降维近似,当生成feature map所用的数据集与原来训练网络模型时所用的数据集有差别时,分解的精度会受很大影响。但是卷积核分解不存在此问题。
利用svd的非线性方法进行分解时需要求解GSVD,当feature map的协方差矩阵低秩时可能有复数解,此时应该使用线性求解的方法
利用cgd求解双凸问题时,初始值的选择可能会影响目标函数的结果。
参考文献
[1] Zhang X, Zou J, He K, et al. Accelerating Very Deep Convolutional Networks for Classification and Detection[J]. IEEE Transactions on Pattern Analysis & Machine Intelligence, 2016, 38(10):1943.
[2] Jaderberg M, Vedaldi A, Zisserman A. Speeding up Convolutional Neural Networks with Low Rank Expansions[J]. Computer Science, 2014, 4(4):XIII.
[3] Takane Y, Hwang H. Regularized linear and kernel redundancy analysis[J]. Computational Statistics & Data Analysis, 2007, 52(1):394-405.