资源简介
剪枝压缩剪枝压缩剪枝压缩剪枝压缩剪枝压缩剪枝压缩剪枝压缩剪枝压缩剪枝压缩
代码片段和文件信息
# coding:utf-8
# by chen yh
import caffe
import numpy as np
import shutil
import matplotlib.pyplot as plt
‘‘‘
These parameters need modification:
root: root directory ;
model: your caffemodel ;
prototxt: your prototxt ;
prune layer: need prune layer name a list ;
input layer: input of these layers is output of prune layereach element is a list ;
th : thereshold of each prune layera list.
Please ensure lenth of prune layer input layer and th.
picture and get get_sum_l1 functions can help you find suitable threshold.
‘‘‘
def get_prune(netlayerthreshold): # 返回layer中低于阈值threshold的卷积核的序号
weight_ori=net.params[layer][0].data
#bias_ori=net.params[layer][1].data
sum_l1 = []
for i in range(weight_ori.shape[0]):
sum_l1.append((inp.sum(abs(weight_ori[i : : :]))))#sum_l1存放每个卷积核的所有权重绝对值之和
de_keral=[] #de_keral存放大于阈值的卷积核的序号
for i in sum_l1:
if i[1]>threshold:
de_keral.append(i[0])
print layer + “层需要prune的卷积核有“ + str(weight_ori.shape[0]-len(de_keral)) + “个保留的卷积核有“ + str(len(de_keral)) + “个“
return de_keral
def prune(netpklk): # 输出两个字典键都是修剪层的layer的名字值分别是修剪层的weight和bias
w_new={} #键是layer值是保存后的weight
b_new={} #键是layer值是保存后的bias
for l in pk.keys(): #待剪层权重处理 w_n = w[pk[l]:;;]
w_old = net.params[l][0].data
b_old = net.params[l][1].data
w_n = w_old[pk[l]:::]
b_n = b_old[pk[l]]
w_new[l] = w_n
b_new[l] = b_n
# net_n.params[l][0].data[...] = w_n
# net_n.params[l][1].data[...] = b_n
for l in lk.keys():#以待剪层为输入的层权重处理
if l not in pk.keys(): # bottom被修剪后本身没有被修剪所以其权重只需要在原来的net上面取切片w_n = w[:lk[l]::]
if l != “conv4_3_norm“: #对传统卷积层的处理
w_o = net.params[l][0].data
b_o = net.params[l][1].data
b_new[l] = b_o # bias保留因为这些层没有剪卷积核
w_n = w_o[: lk[l] : :]
w_new[l] = w_n
else: #对特殊层的处理参数个数不是2
w_o = net.params[l][0].data
w_n = w_o[lk[l]]
w_new[l] = w_n
else: #pk 和 lk共有的层也就是这层的bottom和层本身都被修剪过所以权重不能在原来的net上切片利用保存了的w_new取切片.
w_o = w_new[l]
w_n = w_o[:lk[l]::]
w_new[l] = w_n
return w_newb_new
def get_prototxt(pkpro_n): #复制原来的prototxt并修改修剪层的num_output这一段代码有点绕有空的话优化为几个单独的函数或者弄个类
with open(pro_n“r“) as p:
lines = p.readlines()
k=0
with open(pro_n“w“) as p:
while k < len(lines): #遍历所有的lines此处不宜用for.
if ‘name:‘ in lines[k]:
l_name = lines[k].split(‘“‘)[1] #获取layer name
if l_name in pk.keys(): #如果name在待修剪层中则需要修改下面进入一个找channel的循环块.
while True:
if “num_output:“ in lines[k]:
channel_n = “ num_output: “+str(len(pk[l_name]))+“\n“
p.write(channel_n)
k=k+1
评论
共有 条评论