您的位置:首页 > 其它

深度学习模型压缩加速专题-1.层融合

2019-04-16 16:26 1086 查看

主要记录一下最近几天参加中兴捧月算法比赛的历程,我是从别人的微信群里知道这个比赛的,由于当时没有啥深度学习相关(阿里的对抗样本大赛除外,我是检测分割方向)的比赛, 所以一开始就准备参加一下这个比赛,毕竟模型压缩加速也是跟我的方向有点关系,自己也了解一些相关的技术。
正式提交作品是4月11号的晚上,到现在不到5 天的时间,从榜单外刷到15名,虽然名次不高,但是有些经验还是值得分享的。总结起来,此次模型压缩比赛主要用到的技术就是层融合+剪枝+SVD技术,其他的分离卷积以及relu融合我因为技术有限,就没有实现。

1.层融合,在caffe模型里面就是将bn,scale层与卷积融合在一起,原理如下:

2.层融合代码:

import caffe
import numpy as np

class Merge_bn(object):
def __init__(self, net):
self._net = net
self.new_parames = {}

def conv_bn(self, conv_with_bn):
for conv_name in conv_with_bn:
weight, bias = self._net.params[conv_name]
weight = weight.data
bias = bias.data
channels = weight.shape[0]

# params of bn layer
mean, var, scalef = net.params[conv_name + "_bn"]
mean = mean.data
var = var.data
scalef = scalef.data

if scalef != 0:
scalef = 1. / scalef
mean *= scalef
var *= scalef
rstd = 1. / np.sqrt(var + 1e-5)

# params of scale layer
gamma, beta = net.params[conv_name + "_scale"]
gamma = gamma.data
beta = beta.data

new_weight = weight * rstd.reshape((channels, 1, 1, 1)) * gamma.reshape((channels, 1, 1, 1))
new_bias = (bias - mean) * rstd * gamma + beta
self.new_params[conv_name] = new_weight, new_bias.reshape(-1)
print(conv_name + "merge_bn is sucessed")

def save_model(self, merge_prototxt, merge_caffemodel):
net_bn = caffe.Net(merge_prototxt, caffe.TEST)
for key in net_bn.params.keys():
if key in new_params:
net_bn.params[key][0].data[...] = new_params[key][0]
net_bn.params[key][1].data[...] = new_params[key][1]
else:
net_bn.params[key][0].data[...] = net.params[key][0].data
net_bn.params[key][1].data[...] = net.params[key][1].data
net_bn.save(merge_caffemodel)

def main():
# path
root = './models/'
prototxt = root + 'orig/TestModel.prototxt'
model = root + 'orig/TestModel.caffemodel'

# initial caffe
caffe.set_mode_gpu()
net = caffe.Net(prototxt, model, caffe.TEST)
conv_with_bn = ['conv1_1_1', 'conv1_2_1', 'conv1_2_2', 'conv1_3_1']

merge = Merge_bn(net)
merge.conv_bn(conv_with_bn)

# you need modify .prototxt manually before you save model
merge_prototxt = root + 'merge/merge_bn.prototxt'
merge_caffemodel = root + 'merge/merge_bn.caffemodel'
merge.save_model(merge_prototxt, merge_caffemodel)

if __name__ == '__main__':
main()

后面将会陆续公布其他的一些辅助测试代码以及自己因此看的一些相关的论文。

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: