mxnet统计运算量
【摘要】 参考:
https://github.com/Ldpe2G/DeepLearningForFun/blob/master/MXNet-Python/CalculateFlopsTool/calculateFlops.py
python calculateFlops.py -s symbols/caffenet-symbol.json -ds data,1,...
参考:
python calculateFlops.py -s symbols/caffenet-symbol.json -ds data,1,3,224,224 -ls prob_label,1,1000
('flops: ', '723.007176', ' MFLOPS')
('model size: ', '232.563873291', ' MB')
python calculateFlops.py -s E:\2/model-symbol.json -ds data,1,3,112,112 -ls prob_label,1,256
如果key_error prob_label,可以改下代码,不加载这个label_shapes参数
-
# -*- coding: utf-8 -*-
-
"""
-
File Name: calculate_flops.py
-
Author: liangdepeng
-
mail: liangdepeng@gmail.com
-
"""
-
-
import mxnet as mx
-
import argparse
-
import numpy as np
-
import json
-
import re
-
-
def parse_args():
-
parser = argparse.ArgumentParser(description='')
-
parser.add_argument('-ds', '--data_shapes',default=["data,1,3,112,112"], type=str, nargs='+',
-
help='data_shapes, format: arg_name,s1,s2,...,sn, example: data,1,3,224,224')
-
parser.add_argument('-ls', '--label_shapes',default=["label,1,512"], type=str, nargs='+',
-
help='label_shapes, format: arg_name,s1,s2,...,sn, example: label,1,1,224,224')
-
# parser.add_argument('-s', '--symbol_path', type=str, default=r'model-symbol.json', help='')
-
-
return parser.parse_args()
-
-
-
def product(tu):
-
"""Calculates the product of a tuple"""
-
prod = 1
-
for x in tu:
-
prod = prod * x
-
return prod
-
-
def get_internal_label_info(internal_sym, label_shapes):
-
if label_shapes:
-
internal_label_shapes = filter(lambda shape: shape[0] in internal_sym.list_arguments(), label_shapes)
-
if internal_label_shapes:
-
internal_label_names = [shape[0] for shape in internal_label_shapes]
-
return internal_label_names, internal_label_shapes
-
return None, None
-
-
if __name__ == '__main__':
-
args = parse_args()
-
sym = mx.sym.load(args.symbol_path)
-
-
data_shapes = list()
-
data_names = list()
-
if args.data_shapes is not None and len(args.data_shapes) > 0:
-
for shape in args.data_shapes:
-
items = shape.replace('\'', '').replace('"', '').split(',')
-
data_shapes.append((items[0], tuple([int(s) for s in items[1:]])))
-
data_names.append(items[0])
-
-
label_shapes = None
-
label_names = list()
-
if args.label_shapes is not None and len(args.label_shapes) > 0:
-
label_shapes = list()
-
for shape in args.label_shapes:
-
items = shape.replace('\'', '').replace('"', '').split(',')
-
label_shapes.append((items[0], tuple([int(s) for s in items[1:]])))
-
label_names.append(items[0])
-
-
devs = [mx.cpu()]
-
-
if len(label_names) == 0:
-
label_names = None
-
model = mx.mod.Module(context=devs, symbol=sym, data_names=data_names,label_names=None)
-
model.bind(data_shapes=data_shapes, label_shapes=label_shapes, for_training=False)
-
-
arg_params = model._exec_group.execs[0].arg_dict
-
-
conf = json.loads(sym.tojson())
-
nodes = conf["nodes"]
-
-
total_flops=0.
-
-
for node in nodes:
-
op = node["op"]
-
layer_name = node["name"]
-
attrs = None
-
if "param" in node:
-
attrs = node["param"]
-
elif "attrs" in node:
-
attrs = node["attrs"]
-
else:
-
attrs = {}
-
-
if op == 'Convolution':
-
internal_sym = sym.get_internals()[layer_name + '_output']
-
internal_label_names, internal_label_shapes = get_internal_label_info(internal_sym, label_shapes)
-
-
shape_dict = {}
-
for k,v in data_shapes:
-
shape_dict[k] = v
-
if internal_label_shapes != None:
-
for k,v in internal_label_shapes:
-
shape_dict[k] = v
-
-
_, out_shapes, _ = internal_sym.infer_shape(**shape_dict)
-
out_shape = out_shapes[0]
-
-
# num_group = 1
-
# if "num_group" in attrs:
-
# num_group = int(attrs['num_group'])
-
-
# support conv1d NCW and conv2d NCHW layout
-
out_shape_produt = out_shape[2] if len(out_shape) == 3 else out_shape[2] * out_shape[3]
-
# the weight shape already consider the 'group', so no need to divide 'group'
-
total_flops += out_shape_produt * product(arg_params[layer_name + '_weight'].shape) * data_shapes[0][1][0]
-
-
if layer_name + "_bias" in arg_params:
-
total_flops += product(out_shape)
-
-
del shape_dict
-
-
-
if op == 'Deconvolution':
-
input_layer_name = nodes[node["inputs"][0][0]]["name"]
-
-
internal_sym = sym.get_internals()[input_layer_name + '_output']
-
internal_label_names, internal_label_shapes = get_internal_label_info(internal_sym, label_shapes)
-
-
shape_dict = {}
-
for k,v in data_shapes:
-
shape_dict[k] = v
-
if internal_label_shapes != None:
-
for k,v in internal_label_shapes:
-
shape_dict[k] = v
-
-
_, out_shapes, _ = internal_sym.infer_shape(**shape_dict)
-
input_shape = out_shapes[0]
-
-
# num_group = 1
-
# if "num_group" in attrs:
-
# num_group = int(attrs['num_group'])
-
-
# the weight shape already consider the 'group', so no need to divide 'group'
-
total_flops += input_shape[2] * input_shape[3] * product(arg_params[layer_name + '_weight'].shape) * data_shapes[0][1][0]
-
-
del shape_dict
-
-
if layer_name + "_bias" in arg_params:
-
internal_sym = sym.get_internals()[layer_name + '_output']
-
internal_label_names, internal_label_shapes = get_internal_label_info(internal_sym, internal_label_shapes)
-
-
shape_dict = {}
-
for k,v in data_shapes:
-
shape_dict[k] = v
-
if internal_label_shapes != None:
-
for k,v in internal_label_shapes:
-
shape_dict[k] = v
-
-
_, out_shapes, _ = internal_sym.infer_shape(**shape_dict)
-
out_shapes = out_shapes[0]
-
-
total_flops += product(out_shape)
-
-
del shape_dict
-
-
if op == 'FullyConnected':
-
total_flops += product(arg_params[layer_name + '_weight'].shape) * data_shapes[0][1][0]
-
-
if layer_name + '_bias' in arg_params:
-
num_hidden = int(attrs['num_hidden'])
-
total_flops += num_hidden * data_shapes[0][1][0]
-
-
if op == 'Pooling':
-
if "global_pool" in attrs and attrs['global_pool'] == 'True':
-
input_layer_name = nodes[node["inputs"][0][0]]["name"]
-
-
internal_sym = sym.get_internals()[input_layer_name + '_output']
-
internal_label_names, internal_label_shapes = get_internal_label_info(internal_sym, label_shapes)
-
-
shape_dict = {}
-
for k,v in data_shapes:
-
shape_dict[k] = v
-
if internal_label_shapes != None:
-
for k,v in internal_label_shapes:
-
shape_dict[k] = v
-
-
_, out_shapes, _ = internal_sym.infer_shape(**shape_dict)
-
input_shape = out_shapes[0]
-
-
total_flops += product(input_shape)
-
else:
-
internal_sym = sym.get_internals()[layer_name + '_output']
-
internal_label_names, internal_label_shapes = get_internal_label_info(internal_sym, label_shapes)
-
-
shape_dict = {}
-
for k,v in data_shapes:
-
shape_dict[k] = v
-
if internal_label_shapes != None:
-
for k,v in internal_label_shapes:
-
shape_dict[k] = v
-
-
_, out_shapes, _ = internal_sym.infer_shape(**shape_dict)
-
out_shape = out_shapes[0]
-
-
n = '\d+'
-
kernel = [int(i) for i in re.findall(n, attrs['kernel'])]
-
-
total_flops += product(out_shape) * product(kernel)
-
-
del shape_dict
-
-
if op == 'Activation':
-
if attrs['act_type'] == 'relu':
-
internal_sym = sym.get_internals()[layer_name + '_output']
-
internal_label_names, internal_label_shapes = get_internal_label_info(internal_sym, label_shapes)
-
-
shape_dict = {}
-
for k,v in data_shapes:
-
shape_dict[k] = v
-
if internal_label_shapes != None:
-
for k,v in internal_label_shapes:
-
shape_dict[k] = v
-
-
_, out_shapes, _ = internal_sym.infer_shape(**shape_dict)
-
out_shape = out_shapes[0]
-
-
total_flops += product(out_shape)
-
-
del shape_dict
-
-
-
model_size = 0.0
-
if label_names == None:
-
label_names = list()
-
for k,v in arg_params.items():
-
if k not in data_names and k not in label_names:
-
model_size += product(v.shape) * np.dtype(v.dtype()).itemsize
-
-
print('flops: ', str(total_flops / 1000000), ' MFLOPS')
-
print('model size: ', str(model_size / 1024 / 1024), ' MB')
文章来源: blog.csdn.net,作者:网奇,版权归原作者所有,如需转载,请联系作者。
原文链接:blog.csdn.net/jacke121/article/details/115634504
【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)