一个项目,因为需要解决旋转的问题,加入了stn(spatial transformer networks),识别确实正确了,但是网络参数文件一下子增加了200m+,又由于是跑在android设备上(内存只有2g),这时整个app启动过程中,内存峰值到3g,需求就来了:压缩模型。
讨论后方法2个:1. 对stn进行压缩,2. 更换网络
1. 对stn进行压缩:
小伙伴对stn压缩后,跟没有stn事model文件增加了1612179byte,1.6m。app也可以在2g内存环境下运行起来~ 今晚我自己也稍微折腾了一下下:情况如下:
conv1: 11*11 --> 3*3
444715279 --> 444672266
0.9223 --> 0.9426
conv2: 5*5 -->3*3444672266 --> 444541194
0.9192
stn_fc1: 1600 --> 100
241279186
0.9075
stn_fc1: 100 --> 32
232064642
0.9408
conv2: 输出层数64->16
228758967
0.9517
conv*是卷积层,第一行是卷积核大小,第二行是文件大小变化,第三行是识别率(考虑shuffle,以及init的随机性,会有丝丝变动),stn_fc1是全连接层,可以看到这个参数作用很大。可以这么理解:
1. 假设channel为n,改小卷积核带来的优化是,用float存,4bytes:(11*11-3*3)*n*4=448n,所以没多少,其他类似
2. 输入224*224的图像,conv,pool 2次之后,大小为25*25,channel为64,flattend后大小为25*25*64=40000,fc1我1600,参数大小为:(25*25*64)*1600*4(byte) / 1000.0 / 1000.0=256m,所以这。。。
3. 从1600->32识别率没怎么降低
4. conv2输出层数从64改到16,又减少了几m,还是因为全连接层的原因。。。还发现精度啷个上去了呢。。。。
5. 当然,还可以继续优化的,也可以提高运行效率的,后面继续
2. 更换网络:
直接从alexnet换到mobilenet,输出模型为13m,抛出实现错误的原因,还不需要stn。。。这意外。。。app运行峰值为300m
当然,还有一个比较大的优化点是:现在用的是tensorflow mobile sdk,让小伙伴测了下,不加载model,app起来也要80m。。。换到tensorflow lite才1m+
嗯,这次也是给以后优化model(大小+效率)探个路。
突然发现有了理论指导了。。。