run_meta = tf.RunMetadata()
enter codwith tf.Session(graph=tf.Graph()) as sess:
K.set_session(sess)
with tf.device('/cpu:0'):
base_model = MobileNet(alpha=1, weights=None, input_tensor=tf.placeholder('float32', shape=(1,224,224,3)))
opts = tf.profiler.ProfileOptionBuilder.float_operation()
flops = tf.profiler.profile(sess.graph, run_meta=run_meta, cmd='op', options=opts)
opts = tf.profiler.ProfileOptionBuilder.trainable_variables_parameter()
params = tf.profiler.profile(sess.graph, run_meta=run_meta, cmd='op', options=opts)
print("{:,} --- {:,}".format(flops.total_float_ops, params.total_parameters))当我运行上面的代码时,我得到了下面的结果
1,137,481,704 --- 4,253,864这与论文中描述的flops有所不同。
移动网:https://arxiv.org/pdf/1704.04861.pdf
ShuffleNet:https://arxiv.org/pdf/1707.01083.pdf
如何计算论文中描述的精确flops?
发布于 2018-08-16 04:58:52
tl;Dr.你实际上得到了正确的答案!你只是简单地比较flops和乘法累加(从论文中),因此需要除以2。
如果你使用的是Keras,那么你列出的代码有点过于复杂了……
让model成为任何编译过的Keras模型。我们可以通过以下代码得出模型的失败之处。
import tensorflow as tf
import keras.backend as K
def get_flops():
run_meta = tf.RunMetadata()
opts = tf.profiler.ProfileOptionBuilder.float_operation()
# We use the Keras session graph in the call to the profiler.
flops = tf.profiler.profile(graph=K.get_session().graph,
run_meta=run_meta, cmd='op', options=opts)
return flops.total_float_ops # Prints the "flops" of the model.
# .... Define your model here ....
# You need to have compiled your model before calling this.
print(get_flops())但是,当我在我的计算机上查看我自己的示例(不是Mobilenet)时,打印出的total_float_ops是2115,当我简单地打印flops变量时,我得到了以下结果:
[...]
Mul 1.06k float_ops (100.00%, 49.98%)
Add 1.06k float_ops (50.02%, 49.93%)
Sub 2 float_ops (0.09%, 0.09%)很明显,total_float_ops属性考虑了乘法、加法和减法。
然后,我回顾了MobileNets示例,简单地浏览了一下这篇文章,我发现了MobileNet的实现,这是基于参数数量的默认Keras实现:

表中的第一个模型与您已有的结果(4,253,864)相匹配,并且多个相加大约是您已有的flops结果的一半。因此,你得到了正确的答案,只是你把flops误认为是乘法(又称乘法累加或MACs)。
如果要计算MACs的数量,只需将上述代码的结果除以2即可。
重要说明
如果您正在尝试运行代码示例,请记住以下几点:
发布于 2020-01-22 23:17:50
这对我在TF-2.1中是有效的:
def get_flops(model_h5_path):
session = tf.compat.v1.Session()
graph = tf.compat.v1.get_default_graph()
with graph.as_default():
with session.as_default():
model = tf.keras.models.load_model(model_h5_path)
run_meta = tf.compat.v1.RunMetadata()
opts = tf.compat.v1.profiler.ProfileOptionBuilder.float_operation()
# Optional: save printed results to file
# flops_log_path = os.path.join(tempfile.gettempdir(), 'tf_flops_log.txt')
# opts['output'] = 'file:outfile={}'.format(flops_log_path)
# We use the Keras session graph in the call to the profiler.
flops = tf.compat.v1.profiler.profile(graph=graph,
run_meta=run_meta, cmd='op', options=opts)
return flops.total_float_ops发布于 2020-04-06 21:02:22
以上解决方案不能重复运行,否则flops将累加!(换句话说,第二次运行它时,您将得到output = flops_of_1st_call +flops_of_2nd_call。)下面的代码调用reset_default_graph来避免这种情况。
def get_flops():
session = tf.compat.v1.Session()
graph = tf.compat.v1.get_default_graph()
with graph.as_default():
with session.as_default():
model = keras.applications.mobilenet.MobileNet(
alpha=1, weights=None, input_tensor=tf.compat.v1.placeholder('float32', shape=(1, 224, 224, 3)))
run_meta = tf.compat.v1.RunMetadata()
opts = tf.compat.v1.profiler.ProfileOptionBuilder.float_operation()
# Optional: save printed results to file
# flops_log_path = os.path.join(tempfile.gettempdir(), 'tf_flops_log.txt')
# opts['output'] = 'file:outfile={}'.format(flops_log_path)
# We use the Keras session graph in the call to the profiler.
flops = tf.compat.v1.profiler.profile(graph=graph,
run_meta=run_meta, cmd='op', options=opts)
tf.compat.v1.reset_default_graph()
return flops.total_float_ops修改自@driedler,谢谢!
https://stackoverflow.com/questions/49525776
复制相似问题