加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
testers.py 58.17 KB
一键复制 编辑 原始数据 按行查看 历史
NightSnack 提交于 2020-06-06 21:34 . add prune
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290
import numpy as np
import torch
from numpy import linalg as LA
import argparse
import json
from torch.utils.data import DataLoader
from models import *
from utils.datasets import *
from utils.utils import *
def test_irregular_sparsity(model):
"""
:param model: saved re-trained model
:return:
"""
total_zeros = 0
total_nonzeros = 0
for name, weight in model.named_parameters():
if "bias" in name:
continue
zeros = np.sum(weight.cpu().detach().numpy() == 0)
total_zeros += zeros
non_zeros = np.sum(weight.cpu().detach().numpy() != 0)
total_nonzeros += non_zeros
zeros = np.sum(weight.cpu().detach().numpy() == 0)
non_zero = np.sum(weight.cpu().detach().numpy() != 0)
print("irregular zeros: {}, irregular sparsity is: {:.4f}".format(zeros, zeros / (zeros + non_zero)))
print("---------------------------------------------------------------------------")
print("total number of zeros: {}, non-zeros: {}, zero sparsity is: {:.4f}".format(
total_zeros, total_nonzeros, total_zeros / (total_zeros + total_nonzeros)))
print("only consider conv layers, compression rate is: {:.4f}".format(
(total_zeros+total_nonzeros) / total_nonzeros))
print("===========================================================================\n\n")
def test_column_sparsity(model):
"""
:param model: saved re-trained model
:return:
"""
total_zeros = 0
total_nonzeros = 0
total_column = 0
total_empty_column = 0
for name, weight in model.named_parameters():
if(len(weight.size()) == 4): # only consider conv layers
zeros = np.sum(weight.cpu().detach().numpy() == 0)
total_zeros += zeros
non_zeros = np.sum(weight.cpu().detach().numpy() != 0)
total_nonzeros += non_zeros
weight2d = weight.reshape(weight.shape[0], -1)
column_num = weight2d.shape[1]
empty_column = np.sum(np.sum(weight2d.cpu().detach().numpy(), axis=0) == 0)
print("(total/empty) column of {} is: ({}/{}). column sparsity is: {:.4f}".format(
name, weight.size()[1]*weight.size()[2]*weight.size()[3], empty_column, empty_column / column_num))
total_column += column_num
total_empty_column += empty_column
print("---------------------------------------------------------------------------")
print("total number of zeros: {}, non-zeros: {}, zero sparsity is: {:.4f}".format(
total_zeros, total_nonzeros, total_zeros / (total_zeros + total_nonzeros)))
print("total number of column: {}, empty-column: {}, column sparsity is: {:.4f}".format(
total_column, total_empty_column, total_empty_column / total_column))
print("only consider conv layers, compression rate is: {:.4f}".format(
(total_zeros + total_nonzeros)/total_nonzeros))
# unused = calculate_unused_weight(model)
# print("only consider conv layers, including unused weight, compression rate is: {:.4f}".format(
# (total_zeros + total_nonzeros) / (total_nonzeros - unused)))
# print("===========================================================================\n\n")
def test_channel_sparsity(model):
"""
:param model: saved re-trained model
:return:
"""
total_zeros = 0
total_nonzeros = 0
total_channel = 0
total_empty_channel = 0
for name, weight in model.named_parameters():
if(len(weight.size()) == 4):
weight = weight.cpu().detach().numpy()
""" check channel sparsity based on column sparsity"""
zeros = np.sum(weight == 0)
total_zeros += zeros
non_zeros = np.sum(weight != 0)
total_nonzeros += non_zeros
channel_num = weight.shape[1]
empty_channel = 0
for i in range(channel_num):
# print(np.sum(weight[:,i,:,:].cpu().detach().numpy()))
if np.sum(weight[:,i,:,:]) == 0:
empty_channel += 1
print("(total/empty) channel of {} is: ({}/{}). channel sparsity is: {:.4f}".format(
name, weight.shape[1], empty_channel, empty_channel / channel_num))
total_channel += channel_num
total_empty_channel += empty_channel
print("---------------------------------------------------------------------------")
print("total number of zeros: {}, non-zeros: {}, zero sparsity is: {:.4f}".format(
total_zeros, total_nonzeros, total_zeros / (total_zeros + total_nonzeros)))
print("total number of channel: {}, empty-channel: {}, channel sparsity is: {:.4f}".format(
total_channel, total_empty_channel, total_empty_channel / total_channel))
print("only consider conv layers, compression rate is: {:.4f}".format(
(total_zeros + total_nonzeros) / total_nonzeros))
# unused = calculate_unused_weight(model)
# print("only consider conv layers, including unused weight, compression rate is: {:.4f}".format(
# (total_zeros + total_nonzeros) / (total_nonzeros - unused)))
# print("===========================================================================\n\n")
# almost_empty_channel = 0
# for i in range(weight2d.size()[1]):
# channel_i = weight2d[0, i, :]
# # print(channel_i)
# zeros = np.sum(channel_i.cpu().detach().numpy() == 0)
# channel_empty_ratio = zeros / weight2d.size()[2]
# if channel_empty_ratio == 1:
# almost_empty_channel += 1
# # print(zeros, weight2d.size()[2])
# # print(channel_empty_ratio)
# print("({} {}) almost empty channel: {}, total channel: {}. ratio: {}%".format(name, weight.size(),
# almost_empty_channel, weight2d.size()[1], 100.0 * almost_empty_channel / weight2d.size()[1]))
def test_filter_sparsity(model):
"""
:param model: saved re-trained model
:return:
"""
total_zeros = 0
total_nonzeros = 0
total_filters = 0
total_empty_filters = 0
for name, weight in model.named_parameters():
if(len(weight.size()) == 4): # only consider conv layers
zeros = np.sum(weight.cpu().detach().numpy() == 0)
total_zeros += zeros
non_zeros = np.sum(weight.cpu().detach().numpy() != 0)
total_nonzeros += non_zeros
empty_filters = 0
filter_num = weight.size()[0]
for i in range(filter_num):
if np.sum(weight[i,:,:,:].cpu().detach().numpy()) == 0:
empty_filters += 1
print("(total/empty) filter of {} is: ({}/{}). filter sparsity is: {:.4f}".format(
name, weight.size()[0], empty_filters, empty_filters / filter_num))
total_filters += filter_num
total_empty_filters += empty_filters
print("---------------------------------------------------------------------------")
print("total number of zeros: {}, non-zeros: {}, zero sparsity is: {:.4f}".format(
total_zeros, total_nonzeros, total_zeros / (total_zeros + total_nonzeros)))
print("total number of filters: {}, empty-filters: {}, filter sparsity is: {:.4f}".format(
total_filters, total_empty_filters, total_empty_filters / total_filters))
print("only consider conv layers, compression rate is: {:.4f}".format(
(total_zeros + total_nonzeros) / total_nonzeros))
# unused = calculate_unused_weight(model)
# print("only consider conv layers, including unused weight, compression rate is: {:.4f}".format(
# (total_zeros + total_nonzeros) / (total_nonzeros - unused)))
# print("===========================================================================\n\n")
def test_filter_balance(model):
"""
:param model: saved re-trained model
:return:
"""
total_zeros = 0
total_nonzeros = 0
for name, weight in model.named_parameters():
if(len(weight.size()) == 4 and "shortcut" not in name): # only consider conv layers
zeros = np.sum(weight.cpu().detach().numpy() == 0)
total_zeros += zeros
non_zeros = np.sum(weight.cpu().detach().numpy() != 0)
total_nonzeros += non_zeros
weight3d = weight.reshape(weight.shape[0], weight.shape[1], -1)
kernel_num = weight3d.shape[1]
# print(kernel_num)
for i in range(weight3d.shape[0]):
empty_kernel_num = 0
for j in range(weight3d.shape[1]):
# print(weight3d[i,j,:])
if(np.sum(weight3d[i,j,:].cpu().detach().numpy()) == 0):
empty_kernel_num += 1
print(kernel_num, empty_kernel_num)
def test_pattern_distribution(model):
"""
:param model: saved re-trained model
:return:
"""
pattern1 = [0,2,4,6,8]
pattern2 = [0,2,3,5,6]
pattern3 = [0,1,2,7,8]
pattern4 = [2,3,5,6,8]
pattern5 = [0,1,6,7,8]
pattern6 = [0,2,3,5,8]
pattern7 = [1,2,6,7,8]
pattern8 = [0,3,5,6,8]
pattern9 = [0,1,2,6,7]
pattern10 = [1,2,5,6,8]
pattern11 = [0,5,6,7,8]
pattern12 = [0,2,3,6,7]
pattern13 = [0,1,2,3,8]
pattern14 = [0,1,3,6,8]
pattern15 = [0,1,2,5,6]
pattern16 = [0,2,5,7,8]
pattern17 = [2,3,6,7,8]
pattern18 = [0,2,6,7,8]
pattern19 = [0,2,3,6,8]
pattern20 = [0,1,2,6,8]
pattern21 = [0,2,5,6,8]
patterns_dict = {1: pattern1,
2: pattern2,
3: pattern3,
4: pattern4,
5: pattern5,
6: pattern6,
7: pattern7,
8: pattern8,
9: pattern9,
10: pattern10,
11: pattern11,
12: pattern12,
13: pattern13,
14: pattern14,
15: pattern15,
16: pattern16,
17: pattern17,
18: pattern18,
19: pattern19,
20: pattern20,
21: pattern21
}
"""initialize distribution"""
model_pattern_distribution = {}
for name, weight in model.named_parameters():
if(len(weight.size()) == 4):
model_pattern_distribution[name] = {}
for name, weight in model.named_parameters(): # loop layer
if(len(weight.size()) == 4):
weight3d = (weight.reshape(weight.shape[0], weight.shape[1], -1)).cpu().detach().numpy()
layer_pattern_distribute = {1:0,2:0,3:0,4:0,5:0,6:0,7:0,8:0,9:0,10:0,11:0,12:0,13:0,14:0,15:0,16:0,17:0,18:0,19:0,20:0,21:0}
print("layer {}: each filter has pattern distributed in: ".format(name))
for i in range(weight3d.shape[0]): # loop filter
filter_pattern_distribute = {1:0,2:0,3:0,4:0,5:0,6:0,7:0,8:0,9:0,10:0,11:0,12:0,13:0,14:0,15:0,16:0,17:0,18:0,19:0,20:0,21:0}
for j in range(weight3d.shape[1]): # loop kernel
pattern = np.where(weight3d[i,j,:] == 0)[0]
for k, v in patterns_dict.items():
pattern2compare = np.array(v)
if np.array_equal(pattern, pattern2compare):
layer_pattern_distribute[k] += 1
filter_pattern_distribute[k] += 1
print("layer {}, filter {} --> {}".format(name, i, filter_pattern_distribute))
print("-------------------\nthe total pattern distribution in this layer -> {} is: ".format(name))
print(layer_pattern_distribute, "\n\n")
model_pattern_distribution[name] = layer_pattern_distribute
np.save("pattern_dict.npy", model_pattern_distribution)
def calculate_unused_weight(model):
"""
helper funtion to calculate the corresponding filter add-on sparsity to next layer empty channel
:param model: saved re-trained model
:return:
"""
weight_dict = {} # indexed weight copy
m = 1 # which layer
n = 1 # which layer
counter = 1 # layer counter
total_unused_number = 0 # result
flag1 = False # detect sparsity type
flag2 = False # detect sparsity type
for name, weight in model.named_parameters(): # calculate total layer
if (len(weight.size()) == 4 and "downsample" not in name):
weight_dict[counter] = weight
counter += 1
counter = counter - 1
for name, weight in model.named_parameters():
if (len(weight.size()) == 4 and "downsample" not in name):
weight3d = weight.reshape(weight.shape[0], weight.shape[1], -1)
""" calculate unused filter, previous layer filter <= empty channel by column pruning """
if m != 1:
empty_channel_index = []
for i in range(weight3d.size()[1]):
non_zero_filter = np.where(weight3d[:, i, :].cpu().detach().numpy().any(axis=1))[0]
if non_zero_filter.size == 0:
channel_i = weight3d[0, i, :]
else:
channel_i = weight3d[non_zero_filter[0], i, :]
zeros = np.sum(channel_i.cpu().detach().numpy() == 0)
channel_empty_ratio = zeros / weight3d.size()[2]
if channel_empty_ratio == 1:
empty_channel_index.append(i)
flag1 = True
# print(name, empty_channel_index)
previous_layer = weight_dict[m - 1]
filter_unused_num = 0
for filter_index in empty_channel_index:
target_filter = previous_layer[filter_index, :, :, :]
filter_unused_num += np.sum(target_filter.cpu().detach().numpy() != 0) # != 0 to calculate sparsity
total_unused_number += filter_unused_num
m += 1
#=====================================================================================#
""" calculate unused channel, empty filter by filter pruning => next layer channel """
if n != counter:
empty_filter_index = []
for j in range (weight.size()[0]):
if np.sum(weight[j, :, :, :].cpu().detach().numpy()) == 0:
empty_filter_index.append(j)
flag2 = True
# print(empty_filter_index)
next_layer = weight_dict[n + 1]
channel_unused_num = 0
for channel_index in empty_filter_index:
target_channel = next_layer[:, channel_index, :, :]
channel_unused_num += np.sum(target_channel.cpu().detach().numpy() != 0) # != 0 to calculate sparsity
total_unused_number += channel_unused_num
n += 1
if flag1 and not flag2:
print("your model has column sparsity")
elif flag2 and not flag1:
print("your model has filter sparsity")
elif flag1 and flag2:
print("your model has column AND filter sparsity")
elif not flag1 and not flag2:
print("your model doesn't have redundent weights")
print("total unused weight number (column => prev filter / filter => next column): ", total_unused_number)
return total_unused_number
def remove_unused_weights(model):
weight_dict = {} # indexed weight copy
# ------ column & filter prune -----------------
channel_to_remove = {}
filter_to_remove = {} # index of the filters need to be removed in previous layer
# ------ check L2-norm -------------------------
L2_norms_8col = []
L2_norms_all = []
L2_8_dict = {}
L2_all_dict = {}
m = 1 # which layer
n = 1 # which layer
layer_cont = 1
total_unused_number = 0 # result
for name, weight in model.named_parameters(): # calculate total layer
if (len(weight.size()) == 4 and "downsample" not in name):
weight_dict[layer_cont] = weight
layer_cont += 1
total_layer = layer_cont - 1
layer_cont = 1
for name, weight in model.named_parameters():
if (len(weight.size()) == 4 and "downsample" not in name):
weight3d = weight.reshape(weight.shape[0], weight.shape[1], -1)
""" calculate unused filter, previous layer filter <= empty channel by column pruning """
if m != 1: # start from second layer, 1st layer has no previous layer
# ---------------- Test -----------------
empty_9col_channel_index = [] # index of channels have 9 empty columns
empty_8col_channel_index = [] # index of channels have 8 empty columns
empty_7col_channel_index = [] # index of channels have 7 empty columns
# ---------------------------------------
empty_channel_index = [] # index of considered empty channels (9? 8? 7?...)
for i in range(weight3d.size()[1]): # loop all channels
non_zero_filter = np.where(weight3d[:, i, :].cpu().detach().numpy().any(axis=1))[0]
if non_zero_filter.size == 0:
channel_i = weight3d[0, i, :]
else:
channel_i = weight3d[non_zero_filter[0], i, :]
zeros = np.sum(channel_i.cpu().detach().numpy() == 0)
# ------------ check channel L2-norm ------------
# channel2d = weight3d[:, i, :].cpu().detach().numpy()
#
# column_l2_norm = LA.norm(channel2d, 2, axis=0)
# channel_l2_norm = np.sum(column_l2_norm)
#
# if channel_l2_norm <= 1.5: # th
# empty_channel_index.append(i) # find columns under th to prune
# L2_norms_8col.append(channel_l2_norm) #test
# -----------------------------------------------
# ---------------- Test -----------------
if (True):
if (zeros == 7):
empty_7col_channel_index.append(i)
# print("layer: {} channel {} has {} zeros over {}".format(name, i, zeros, weight3d.size()[2]))
if (zeros == 8):
empty_8col_channel_index.append(i)
# print("layer: {} channel {} has {} zeros over {}".format(name, i, zeros, weight3d.size()[2]))
if (zeros == 9):
empty_9col_channel_index.append(i)
# print("layer: {} channel {} has {} zeros over {}".format(name, i, zeros, weight3d.size()[2]))
# ---------------------------------------
channel2d = weight3d[:, i, :].cpu().detach().numpy()
column_l2_norm = LA.norm(channel2d, 2, axis=0)
# channel_l2_norm = np.sum(column_l2_norm)
# print(channel_l2_norm)
for column_norm in column_l2_norm:
if column_norm != 0:
L2_norms_all.append(column_norm)
if (zeros == 9):
empty_channel_index.append(i)
print("layer: {} 7-zeros channel is: {}/{} ({}%)".format(layer_cont, len(empty_7col_channel_index),
weight3d.size()[1], 100.*float(len(empty_7col_channel_index))/float(weight3d.size()[1])))
print("layer: {} 8-zeros channel is: {}/{} ({}%)".format(layer_cont, len(empty_8col_channel_index),
weight3d.size()[1], 100.*float(len(empty_8col_channel_index))/float(weight3d.size()[1])))
print("layer: {} 9-zeros channel is: {}/{} ({}%)".format(layer_cont, len(empty_9col_channel_index),
weight3d.size()[1], 100.*float(len(empty_9col_channel_index))/float(weight3d.size()[1])))
print("--------------------------------------------")
L2_8_dict[name] = list(L2_norms_8col)
#print(L2_norms_8col)
L2_norms_8col.clear()
#print("L2_norm_8col")
#print(L2_norms_8col)
#print(L2_8_dict[name])
if layer_cont in channel_to_remove:
# print("col before extend in layer {}".format(layer_cont))
# print(column_to_remove[layer_cont])
channel_to_remove[layer_cont].extend(empty_channel_index)
# print("col after extend in layer {}".format(layer_cont))
# print(column_to_remove[layer_cont])
else:
channel_to_remove[layer_cont] = empty_channel_index
if layer_cont - 1 in filter_to_remove:
# print("fil before extend in layer {}".format(layer_cont-1))
# print(filter_to_remove[layer_cont-1])
filter_to_remove[layer_cont - 1].extend(empty_channel_index)
# print("fil after extend in layer {}".format(layer_cont-1))
# print(filter_to_remove[layer_cont-1])
else:
filter_to_remove[layer_cont - 1] = empty_channel_index
m += 1
# =====================================================================================#
""" calculate unused channel, empty filter by filter pruning => next layer channel """
if n != total_layer:
empty_filter_index = []
distri_dict = {}
for j in range(weight.size()[0]):
if np.sum(weight[j, :, :, :].cpu().detach().numpy()) == 0:
empty_filter_index.append(j)
# print(empty_filter_index)
total_num = weight[0, :, :, :].cpu().detach().numpy().size # total weights per filter
for index in range(weight.size()[0]):
zeros = np.count_nonzero(weight[index, :, :, :].cpu().detach().numpy() == 0) # count zeros in a filter
percentage = int(100*zeros/total_num)
if percentage in distri_dict: # get distribution of different percentage
distri_dict[percentage] += 1
else:
distri_dict[percentage] = 1
print("filter zero percentage in layer: {} (total {} weights)".format(layer_cont, total_num))
print(sorted(distri_dict.items())) # print sorted distri_dict
print("--------------------------------------------")
# ------ add filters that needs to be removed into dict ---------
if layer_cont in filter_to_remove:
#print("fil before extend in layer {}".format(layer_cont))
#print(filter_to_remove[layer_cont])
filter_to_remove[layer_cont].extend(empty_filter_index) # may has duplicated element now
#print("fil after extend in layer {}".format(layer_cont))
#print(filter_to_remove[layer_cont])
else:
#print("fil before new in layer {}".format(layer_cont))
filter_to_remove[layer_cont] = empty_filter_index
# print("fil after new in layer {}".format(layer_cont))
#print(filter_to_remove[layer_cont])
# ------ add column that needs to be removed into dict ---------
if layer_cont + 1 in channel_to_remove:
#print("col before extend in layer {}".format(layer_cont + 1))
# print(column_to_remove[layer_cont + 1])
channel_to_remove[layer_cont + 1].extend(empty_filter_index) # may has duplicated element now
#print("col after extend in layer {}".format(layer_cont + 1))
# print(column_to_remove[layer_cont + 1])
else:
#print("col before new in layer {}".format(layer_cont + 1))
channel_to_remove[layer_cont + 1] = empty_filter_index
# print("col after new in layer {}".format(layer_cont + 1))
#print(column_to_remove[layer_cont + 1])
n += 1
layer_cont += 1
# ------------- remove weights ----------------
layer_cont = 1
for name, weight in model.named_parameters():
if (len(weight.size()) == 4 and "downsample" not in name):
# ----------- remove filters ----------------
if layer_cont in filter_to_remove: #last layer not included
#print("remove filters in Conv layer: {}".format(layer_cont))
newWeight = weight.cpu().detach().numpy()
for index in filter_to_remove[layer_cont]:
newWeight[index, :, :, :] = 0 # set unused filter to 0
weight.data = torch.from_numpy(newWeight).cuda()
# ----------- remove channels ---------------
if layer_cont in channel_to_remove: #first layer not included
#print("remove channels in Conv layer: {}".format(layer_cont))
newWeight = weight.cpu().detach().numpy()
for index in channel_to_remove[layer_cont]:
newWeight[:, index, :, :] = 0 # set unused filter to 0
weight.data = torch.from_numpy(newWeight).cuda()
layer_cont += 1
# plt.figure(1)
# plt.hist(L2_norms_8col, bins=50, align="mid", rwidth=0.3)
# plt.title("8 columns L2-norms")
#
# plt.figure(2)
# plt.hist(L2_norms_all, bins=50, align="mid", rwidth=0.3)
# plt.title("all columns L2-norms")
# #plt.yscale('log')
# plt.show()
# for layer in L2_8_dict:
# print(L2_8_dict[layer])
return channel_to_remove, filter_to_remove
# prune channels that L2 norm smaller than threshold
def post_channel_prune(model, th=0):
# threshold for channel prune
# channels that L2 norm under th will be pruned
# best th: resnet: 0.3 vgg16: 0.23
# ------ channels to prune -----------------
channel_to_remove = {}
# ------ check L2-norm -------------------------
L2_norms_channel = []
L2_dict = {}
layer_cont = 1
for name, weight in model.named_parameters():
if (len(weight.size()) == 4 and "downsample" not in name):
weight3d = weight.reshape(weight.shape[0], weight.shape[1], -1)
""" calculate unused filter, previous layer filter <= empty channel by column pruning """
empty_channel_index = []
for i in range(weight3d.size()[1]): # loop all channels
channel2d = weight3d[:, i, :].cpu().detach().numpy()
columns_l2_norm = LA.norm(channel2d, 2, axis=0) # [0.1,0.5, ...] 9 columns' L2 norm
channel_l2_norm = np.sum(columns_l2_norm) # channel L2 norm sum
if channel_l2_norm < th: # th
empty_channel_index.append(i) # find channel under th to prune
L2_norms_channel.append(channel_l2_norm) # test
# --------------- store satisfied channels in each layer ------------------------
L2_dict[name] = list(L2_norms_channel)
L2_norms_channel.clear()
channel_to_remove[layer_cont] = empty_channel_index
layer_cont += 1
for layer in L2_dict:
print(L2_dict[layer])
# ------------- remove channels ----------------
layer_cont = 1
for name, weight in model.named_parameters():
if (len(weight.size()) == 4 and "downsample" not in name):
if layer_cont in channel_to_remove:
newWeight = weight.cpu().detach().numpy()
for index in channel_to_remove[layer_cont]:
newWeight[:, index, :, :] = 0 # set channel to 0
weight.data = torch.from_numpy(newWeight).cuda()
layer_cont += 1
return th
def post_column_prune(model, th=0):
# threshold for channel prune
# channels that L2 norm under th will be pruned
# best th: resnet: 0.04 vgg16: 0.057 vgg_shortcut:0.0645
# ------ channels to prune -----------------
column_to_remove = {}
# ------ check L2-norm -------------------------
L2_norms_column = []
L2_dict = {}
layer_cont = 1
for name, weight in model.named_parameters():
if (len(weight.size()) == 4): # and "shortcut" not in name and "downsample" not in name):
weight2d = weight.reshape(weight.shape[0], -1)
""" calculate unused filter, previous layer filter <= empty channel by column pruning """
empty_column_index = []
for i in range(weight2d.size()[1]): # loop all columns
column1d = weight2d[:, i].cpu().detach().numpy()
column_l2_norm = LA.norm(column1d, 2) # [0.1,0.5, ...] 9 columns' L2 norm
if column_l2_norm < th: # th
empty_column_index.append(i) # find channel under th to prune
L2_norms_column.append(column_l2_norm) # test
# --------------- store satisfied channels in each layer ------------------------
L2_dict[name] = list(L2_norms_column)
L2_norms_column.clear()
column_to_remove[layer_cont] = empty_column_index
layer_cont += 1
print("----------- empty columns ------------")
for layer in L2_dict:
print(L2_dict[layer])
# ------------- remove channels ----------------
layer_cont = 1
for name, weight in model.named_parameters():
if (len(weight.size()) == 4): # and "shortcut" not in name and "downsample" not in name):
if layer_cont in column_to_remove:
shape = weight.shape
weight = weight.reshape(shape[0], -1)
for index in column_to_remove[layer_cont]:
weight[:, index] = 0 # set channel to 0
layer_cont += 1
return th
def post_filter_prune(model, th=0):
# threshold for channel prune
# channels that L2 norm under th will be pruned
# best th: resnet18: 0.23 vgg16: 0.15
# ------ channels to prune -----------------
filter_to_remove = {}
# ------ check L2-norm -------------------------
L2_norms_filter = []
L2_dict = {}
layer_cont = 1
for name, weight in model.named_parameters():
if (len(weight.size()) == 4 and "downsample" not in name):
weight2d = weight.reshape(weight.shape[0], -1)
""" calculate unused filter, previous layer filter <= empty channel by column pruning """
empty_filter_index = []
for i in range(weight2d.size()[0]): # loop all filters
filter1d = weight2d[i, :].cpu().detach().numpy()
filter_l2_norm = LA.norm(filter1d, 2) # L2 norm of a filter
if filter_l2_norm < th: # th
empty_filter_index.append(i) # find channel under th to prune
L2_norms_filter.append(filter_l2_norm) # test
# --------------- store satisfied filters in each layer ------------------------
L2_dict[name] = list(L2_norms_filter)
L2_norms_filter.clear()
filter_to_remove[layer_cont] = empty_filter_index
layer_cont += 1
for layer in L2_dict:
print(L2_dict[layer])
# ------------- remove filters ----------------
layer_cont = 1
for name, weight in model.named_parameters():
if (len(weight.size()) == 4 and "downsample" not in name):
if layer_cont in filter_to_remove: # first layer not included
newWeight = weight.cpu().detach().numpy()
for index in filter_to_remove[layer_cont]:
newWeight[index, :, :, :] = 0 # set channel to 0
weight.data = torch.from_numpy(newWeight).cuda()
layer_cont += 1
return th
def post_kernel_prune(model, th=0):
for name, weight in model.named_parameters():
weightn = weight.cpu().detach().numpy()
shape = weightn.shape
if (len(shape) == 4): # and "shortcut" not in name):
weight3d = weightn.reshape(shape[0], shape[1], -1)
for i in range(shape[0]): # loop all filters
filter_i = weight3d[i, :, :]
kernel_l2_norms = LA.norm(filter_i, 2, axis=1)
under_threshold = kernel_l2_norms < th
filter_i[under_threshold, :] = 0
weight.data = torch.from_numpy(weightn).cuda()
return th
def test_sparsity(model, column=True, channel=True, filter=True):
# --------------------- total sparsity --------------------
total_zeros = 0
total_nonzeros = 0
for name, weight in model.named_parameters():
if (len(weight.size()) == 4):# and "shortcut" not in name): # only consider conv layers
zeros = np.sum(weight.cpu().detach().numpy() == 0)
total_zeros += zeros
non_zeros = np.sum(weight.cpu().detach().numpy() != 0)
total_nonzeros += non_zeros
comp_ratio = float((total_zeros + total_nonzeros)) / float(total_nonzeros)
if(not column and not channel and not filter):
print("---------------------------------------------------------------------------")
print("total number of zeros: {}, non-zeros: {}, zero sparsity is: {:.4f}".format(
total_zeros, total_nonzeros, total_zeros / (total_zeros + total_nonzeros)))
print("only consider conv layers, compression rate is: {:.4f}".format(
(total_zeros + total_nonzeros) / total_nonzeros))
print("===========================================================================\n\n")
# --------------------- column sparsity --------------------
if(column):
total_column = 0
total_empty_column = 0
layer_cont = 1
for name, weight in model.named_parameters():
if (len(weight.size()) == 4):# and "shortcut" not in name): # only consider conv layers
weight2d = weight.reshape(weight.shape[0], -1)
column_num = weight2d.shape[1]
empty_column = np.sum(np.sum(np.absolute(weight2d.cpu().detach().numpy()), axis=0) == 0)
print("(empty/total) column of {}({}) is: ({}/{}). column sparsity is: {:.4f}".format(
name, layer_cont, empty_column, weight.size()[1] * weight.size()[2] * weight.size()[3],
empty_column / column_num))
total_column += column_num
total_empty_column += empty_column
layer_cont += 1
print("---------------------------------------------------------------------------")
print("total number of zeros: {}, non-zeros: {}, zero sparsity is: {:.4f}".format(
total_zeros, total_nonzeros, total_zeros / (total_zeros + total_nonzeros)))
print("total number of column: {}, empty-column: {}, column sparsity is: {:.4f}".format(
total_column, total_empty_column, total_empty_column / total_column))
print("only consider conv layers, compression rate is: {:.4f}".format(
(total_zeros + total_nonzeros) / total_nonzeros))
print("===========================================================================\n\n")
# --------------------- channel sparsity --------------------
if (channel):
total_channels = 0
total_empty_channels = 0
layer_cont = 1
for name, weight in model.named_parameters():
if (len(weight.size()) == 4):# and "shortcut" not in name): # only consider conv layers
empty_channels = 0
channel_num = weight.size()[1]
for i in range(channel_num):
if np.sum(np.absolute(weight[:, i, :, :].cpu().detach().numpy())) == 0:
empty_channels += 1
print("(empty/total) channel of {}({}) is: ({}/{}). channel sparsity is: {:.4f}".format(
name, layer_cont, empty_channels, weight.size()[1], empty_channels / channel_num))
total_channels += channel_num
total_empty_channels += empty_channels
layer_cont += 1
print("---------------------------------------------------------------------------")
print("total number of zeros: {}, non-zeros: {}, zero sparsity is: {:.4f}".format(
total_zeros, total_nonzeros, total_zeros / (total_zeros + total_nonzeros)))
print("total number of channels: {}, empty-channels: {}, channel sparsity is: {:.4f}".format(
total_channels, total_empty_channels, total_empty_channels / total_channels))
print("only consider conv layers, compression rate is: {:.4f}".format(
(total_zeros + total_nonzeros) / total_nonzeros))
print("===========================================================================\n\n")
# --------------------- filter sparsity --------------------
if(filter):
total_filters = 0
total_empty_filters = 0
layer_cont = 1
for name, weight in model.named_parameters():
if (len(weight.size()) == 4):# and "shortcut" not in name): # only consider conv layers
empty_filters = 0
filter_num = weight.size()[0]
for i in range(filter_num):
if np.sum(np.absolute(weight[i, :, :, :].cpu().detach().numpy())) == 0:
empty_filters += 1
print("(empty/total) filter of {}({}) is: ({}/{}). filter sparsity is: {:.4f}".format(
name, layer_cont, empty_filters, weight.size()[0], empty_filters / filter_num))
total_filters += filter_num
total_empty_filters += empty_filters
layer_cont += 1
print("---------------------------------------------------------------------------")
print("total number of zeros: {}, non-zeros: {}, zero sparsity is: {:.4f}".format(
total_zeros, total_nonzeros, total_zeros / (total_zeros + total_nonzeros)))
print("total number of filters: {}, empty-filters: {}, filter sparsity is: {:.4f}".format(
total_filters, total_empty_filters, total_empty_filters / total_filters))
print("only consider conv layers, compression rate is: {:.4f}".format(
(total_zeros + total_nonzeros) / total_nonzeros))
print("===========================================================================\n\n")
return comp_ratio
def find_empty_channel_and_filters_resnet18(model):
conv_weight_dict = {} # indexed weight copy
shortcut_weight_dict = {}
conv_layer_number = []
shortcut_layer_number = []
# ------ column & filter prune -----------------
channel_to_remove = {}
filter_to_remove = {} # index of the filters need to be removed in previous layer
conv_empty_channels = {}
conv_empty_filters = {}
sc_empty_channels = {}
sc_empty_filters = {} # index of the filters need to be removed in previous layer
layer_cont = 1
total_conv_layer = 0
total_shortcut_layer = 0
for name, weight in model.named_parameters(): # calculate total layer
if (len(weight.size()) == 4 and "shortcut" not in name and "downsample" not in name):
conv_weight_dict[layer_cont] = weight
conv_layer_number.append(layer_cont)
total_conv_layer += 1
if (len(weight.size()) == 4 and ("shortcut" in name or "downsample" in name)):
shortcut_weight_dict[layer_cont] = weight
shortcut_layer_number.append(layer_cont)
total_shortcut_layer += 1
layer_cont += 1
total_layer = layer_cont - 1
layer_cont = 1
conv_layer_number_index = 0
for name, weight in model.named_parameters():
# -------------- Conv layer empty channels ------------------------
if (len(weight.size()) == 4 and "shortcut" not in name and "downsample" not in name):
""" calculate unused filter, previous layer filter <= empty channel by column pruning """
if conv_layer_number_index != 0: # start from second layer, 1st layer has no previous layer
# ---------------------------------------
empty_channel_index = [] # index of considered empty channels (9? 8? 7?...)
for i in range(weight.size()[1]):
if np.sum(np.absolute(weight[:, i, :, :].cpu().detach().numpy())) == 0:
empty_channel_index.append(i)
conv_empty_channels[layer_cont] = empty_channel_index
filter_to_remove[conv_layer_number[conv_layer_number_index - 1]] = empty_channel_index
# =====================================================================================#
""" calculate unused channel, empty filter by filter pruning => next layer channel """
if conv_layer_number_index != total_conv_layer - 1: #not the last layer
empty_filter_index = []
for j in range(weight.size()[0]):
if np.sum(np.absolute(weight[j, :, :, :].cpu().detach().numpy())) == 0:
empty_filter_index.append(j)
conv_empty_filters[layer_cont] = empty_filter_index
channel_to_remove[conv_layer_number[conv_layer_number_index + 1]] = empty_filter_index
conv_layer_number_index += 1
# -------------- shortcut layer empty channels ------------------------
if (len(weight.size()) == 4 and (("shortcut" in name) or ("downsample" in name))):
""" calculate unused filter, previous layer filter <= empty channel by column pruning """
# ---------------------------------------
empty_channel_index = [] # index of considered empty channels (9? 8? 7?...)
for i in range(weight.size()[1]):
if np.sum(np.absolute(weight[:, i, :, :].cpu().detach().numpy())) == 0:
empty_channel_index.append(i)
sc_empty_channels[layer_cont] = empty_channel_index
# =====================================================================================#
""" calculate unused channel, empty filter by filter pruning => next layer channel """
empty_filter_index = []
for j in range(weight.size()[0]):
if np.sum(np.absolute(weight[j, :, :, :].cpu().detach().numpy())) == 0:
empty_filter_index.append(j)
sc_empty_filters[layer_cont] = empty_filter_index
layer_cont += 1 # count for each layer
return conv_empty_channels, conv_empty_filters, sc_empty_channels, sc_empty_filters
def remove_unused_path_resnet18(model, conv_empty_channels, conv_empty_filters, sc_empty_channels, sc_empty_filters):
# channel_to_remove, filter_to_remove,
# sc_empty_channels, sc_empty_filters,
# conv_layer_number, shortcut_layer_number
layer_cont = 1
for name, weight in model.named_parameters():
if (len(weight.size()) == 4):
# ================= layer 1 ==============================
if layer_cont == 1:
newWeight = weight.cpu().detach().numpy()
# ------------ remove channel ----------------
# no channel remove in first layer
# ------------ remove filter ----------------
for index in conv_empty_channels[4]:
if index in conv_empty_channels[10] and index in conv_empty_channels[16] and index in sc_empty_channels[22]:
newWeight[index, :, :, :] = 0 # set channel to 0
weight.data = torch.from_numpy(newWeight).cuda()
# ================= layer 4 ==============================
if layer_cont == 4:
newWeight = weight.cpu().detach().numpy()
# ------------ remove channel ----------------
for index in conv_empty_filters[1]:
newWeight[:, index, :, :] = 0 # set channel to 0
# ------------ remove filter ----------------
for index in conv_empty_channels[7]:
newWeight[index, :, :, :] = 0 # set channel to 0
weight.data = torch.from_numpy(newWeight).cuda()
# ================= layer 7 ==============================
if layer_cont == 7:
newWeight = weight.cpu().detach().numpy()
# ------------ remove channel ----------------
for index in conv_empty_filters[4]:
newWeight[:, index, :, :] = 0 # set channel to 0
# ------------ remove filter ----------------
for index in conv_empty_channels[10]:
if index in conv_empty_channels[16] and index in sc_empty_channels[22]:
newWeight[index, :, :, :] = 0 # set channel to 0
weight.data = torch.from_numpy(newWeight).cuda()
# ================= layer 10 ==============================
if layer_cont == 10:
newWeight = weight.cpu().detach().numpy()
# ------------ remove channel ----------------
for index in conv_empty_filters[7]:
if index in conv_empty_filters[1]:
#print("index {} is in sc".format(index))
newWeight[:, index, :, :] = 0 # set channel to 0
# ------------ remove filter ----------------
for index in conv_empty_channels[13]:
newWeight[index, :, :, :] = 0 # set channel to 0
weight.data = torch.from_numpy(newWeight).cuda()
# ================= layer 13 ==============================
if layer_cont == 13:
newWeight = weight.cpu().detach().numpy()
# ------------ remove channel ----------------
for index in conv_empty_filters[10]:
newWeight[:, index, :, :] = 0 # set channel to 0
# ------------ remove filter ----------------
for index in conv_empty_channels[16]:
if index in sc_empty_channels[22]:
newWeight[index, :, :, :] = 0 # set channel to 0
weight.data = torch.from_numpy(newWeight).cuda()
# ================= layer 16 ==============================
if layer_cont == 16:
newWeight = weight.cpu().detach().numpy()
# ------------ remove channel ----------------
for index in conv_empty_filters[13]:
if index in conv_empty_filters[7]:
newWeight[:, index, :, :] = 0 # set channel to 0
# ------------ remove filter ----------------
for index in conv_empty_channels[19]:
newWeight[index, :, :, :] = 0 # set channel to 0
weight.data = torch.from_numpy(newWeight).cuda()
# ================= layer 19 ==============================
if layer_cont == 19:
newWeight = weight.cpu().detach().numpy()
# ------------ remove channel ----------------
for index in conv_empty_filters[16]:
newWeight[:, index, :, :] = 0 # set channel to 0
# ------------ remove filter ----------------
for index in conv_empty_channels[25]:
if index in sc_empty_filters[22] and index in sc_empty_channels[37] and index in conv_empty_channels[31]:
newWeight[index, :, :, :] = 0 # set channel to 0
weight.data = torch.from_numpy(newWeight).cuda()
# ================= shortcut layer 22 ==============================
if layer_cont == 22:
newWeight = weight.cpu().detach().numpy()
# ------------ remove channel ----------------
for index in conv_empty_filters[13]:
if index in conv_empty_filters[7] and index in conv_empty_filters[1]:
newWeight[:, index, :, :] = 0 # set channel to 0
# ------------ remove filter ----------------
for index in conv_empty_channels[25]:
if index in conv_empty_channels[31] and index in sc_empty_channels[37]:
newWeight[index, :, :, :] = 0 # set channel to 0
weight.data = torch.from_numpy(newWeight).cuda()
# ================= layer 25 ==============================
if layer_cont == 25:
newWeight = weight.cpu().detach().numpy()
# ------------ remove channel ----------------
for index in conv_empty_filters[19]:
if index in sc_empty_filters[22]:
newWeight[:, index, :, :] = 0 # set channel to 0
# ------------ remove filter ----------------
for index in conv_empty_channels[28]:
newWeight[index, :, :, :] = 0 # set channel to 0
weight.data = torch.from_numpy(newWeight).cuda()
# ================= layer 28 ==============================
if layer_cont == 28:
newWeight = weight.cpu().detach().numpy()
# ------------ remove channel ----------------
for index in conv_empty_filters[25]:
newWeight[:, index, :, :] = 0 # set channel to 0
# ------------ remove filter ----------------
for index in conv_empty_channels[31]:
if index in sc_empty_channels[37]:
newWeight[index, :, :, :] = 0 # set channel to 0
weight.data = torch.from_numpy(newWeight).cuda()
# ================= layer 31 ==============================
if layer_cont == 31:
newWeight = weight.cpu().detach().numpy()
# ------------ remove channel ----------------
for index in conv_empty_filters[28]:
if index in conv_empty_filters[19] and index in sc_empty_filters[22]:
newWeight[:, index, :, :] = 0 # set channel to 0
# ------------ remove filter ----------------
for index in conv_empty_channels[34]:
newWeight[index, :, :, :] = 0 # set channel to 0
weight.data = torch.from_numpy(newWeight).cuda()
# ================= layer 34 ==============================
if layer_cont == 34:
newWeight = weight.cpu().detach().numpy()
# ------------ remove channel ----------------
for index in conv_empty_filters[31]:
newWeight[:, index, :, :] = 0 # set channel to 0
# ------------ remove filter ----------------
for index in conv_empty_channels[40]:
if index in conv_empty_channels[46] and index in sc_empty_channels[52]:
newWeight[index, :, :, :] = 0 # set channel to 0
weight.data = torch.from_numpy(newWeight).cuda()
# ================= shortcut layer 37 ==============================
if layer_cont == 37:
newWeight = weight.cpu().detach().numpy()
# ------------ remove channel ----------------
for index in conv_empty_filters[28]:
if index in conv_empty_filters[19] and index in sc_empty_filters[22]:
newWeight[:, index, :, :] = 0 # set channel to 0
# ------------ remove filter ----------------
for index in conv_empty_channels[40]:
if index in conv_empty_channels[46] and index in sc_empty_channels[52]:
newWeight[index, :, :, :] = 0 # set channel to 0
weight.data = torch.from_numpy(newWeight).cuda()
# ================= layer 40 ==============================
if layer_cont == 40:
newWeight = weight.cpu().detach().numpy()
# ------------ remove channel ----------------
for index in conv_empty_filters[34]:
if index in sc_empty_filters[37]:
newWeight[:, index, :, :] = 0 # set channel to 0
# ------------ remove filter ----------------
for index in conv_empty_channels[43]:
newWeight[index, :, :, :] = 0 # set channel to 0
weight.data = torch.from_numpy(newWeight).cuda()
# ================= layer 43 ==============================
if layer_cont == 43:
newWeight = weight.cpu().detach().numpy()
# ------------ remove channel ----------------
for index in conv_empty_filters[40]:
newWeight[:, index, :, :] = 0 # set channel to 0
# ------------ remove filter ----------------
for index in conv_empty_channels[46]:
if index in sc_empty_channels[52]:
newWeight[index, :, :, :] = 0 # set channel to 0
weight.data = torch.from_numpy(newWeight).cuda()
# ================= layer 46 ==============================
if layer_cont == 46:
newWeight = weight.cpu().detach().numpy()
# ------------ remove channel ----------------
for index in conv_empty_filters[43]:
if index in conv_empty_filters[34] and index in sc_empty_filters[37]:
newWeight[:, index, :, :] = 0 # set channel to 0
# ------------ remove filter ----------------
for index in conv_empty_channels[49]:
newWeight[index, :, :, :] = 0 # set channel to 0
weight.data = torch.from_numpy(newWeight).cuda()
# ================= layer 49 ==============================
if layer_cont == 49:
newWeight = weight.cpu().detach().numpy()
# ------------ remove channel ----------------
for index in conv_empty_filters[46]:
newWeight[:, index, :, :] = 0 # set channel to 0
# ------------ remove filter ----------------
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! "
" may not work."
" did't take shortcut into account (because fc layer) !!!!!!!!!! "
# for index in conv_empty_channels[55]:
# newWeight[index, :, :, :] = 0 # set channel to 0
weight.data = torch.from_numpy(newWeight).cuda()
# ================= shortcut layer 52 ==============================
if layer_cont == 52:
newWeight = weight.cpu().detach().numpy()
# ------------ remove channel ----------------
for index in conv_empty_filters[43]:
if index in conv_empty_filters[34] and index in sc_empty_filters[37]:
newWeight[:, index, :, :] = 0 # set channel to 0
# ------------ remove filter ----------------
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! "
" may not work."
" did't take shortcut into account (because fc layer) !!!!!!!!!! "
# for index in conv_empty_channels[55]:
# newWeight[index, :, :, :] = 0 # set channel to 0
weight.data = torch.from_numpy(newWeight).cuda()
# ================= layer 55 ==============================
if layer_cont == 55:
newWeight = weight.cpu().detach().numpy()
# ------------ remove channel ----------------
for index in conv_empty_filters[49]:
if index in sc_empty_filters[52]:
newWeight[:, index, :, :] = 0 # set channel to 0
# ------------ remove filter ----------------
for index in conv_empty_channels[58]:
newWeight[index, :, :, :] = 0 # set channel to 0
weight.data = torch.from_numpy(newWeight).cuda()
# ================= layer 58 ==============================
" from test results, this layer may affect the accuracy, may because BN layer"
if layer_cont == 58:
newWeight = weight.cpu().detach().numpy()
# ------------ remove channel ----------------
# for index in conv_empty_filters[55]:
# newWeight[:, index, :, :] = 0 # set channel to 0
# ------------ remove filter ----------------
" no filter to remove in last layer"
weight.data = torch.from_numpy(newWeight).cuda()
layer_cont += 1
def main():
####################################
## yolo training setting
####################################
# Configure run
data_cfg = 'cfg/coco.data'
# train_path = parse_data_cfg(data_cfg)['train']
# test_path = parse_data_cfg(data_cfg)['valid']
multi_scale = False
img_size = 416
cfg = 'cfg/yolov3.cfg'
lr0 = 0.001
cutoff = -1 # backbone reaches to cutoff layer
start_epoch = 0
best_loss = float('inf')
# Initialize model
model = Darknet(cfg, img_size)
# model.load_state_dict(torch.load("./weights/yolov3_retrained_acc_0.489_3rhos_config_yolov3_filter.pt"))
model.load_state_dict(torch.load("/home/hongjia/yolov3_retrained_acc_0.346_4rhos_config_yolov3_v1_filter.pt"))
#
# for name, weight in model.named_parameters():
# if (len(weight.size()) == 1):
# print(name)
# print(weight)
# #
# conv_empty_channels, conv_empty_filters = find_empty_channel_and_filters_yolo(model)
# print(conv_empty_filters[0])
# print(conv_empty_filters[1])
# print(conv_empty_filters[2])
# print(conv_empty_filters[3])
# test(model, conv_empty_channels, conv_empty_filters)
# remove_filter, remove_channel = remove_unused_path_yolo(model, conv_empty_channels, conv_empty_filters)
# print(remove_filter)
# print(remove_channel)
#
# model.load_state_dict(torch.load("./weights/yolov3_remove.pt"))
test_filter_sparsity(model)
test_column_sparsity(model)
if __name__ == '__main__':
main()
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化