Y. *_*Han 1 flops deep-learning keras
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))
Run Code Online (Sandbox Code Playgroud)
当我运行上面的代码时,我得到了下面的结果
1,137,481,704 --- 4,253,864
Run Code Online (Sandbox Code Playgroud)
这与本文所述的触发器不同。
移动网络:https ://arxiv.org/pdf/1704.04861.pdf
ShuffleNet:https://arxiv.org/pdf/1707.01083.pdf
如何计算论文中所述的确切触发器?
Mal*_*olm 10
tl; dr您实际上得到了正确的答案!您只是在比较触发器与乘法累加(来自本文),因此需要除以2。
如果您使用的是Keras,那么您列出的代码会使事情有些复杂化...
让model是任何编译Keras模型。我们可以使用以下代码来获得模型的触发器。
import tensorflow as tf
import keras.backend as K
def get_flops(model):
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 ....
print(get_flops(model))
Run Code Online (Sandbox Code Playgroud)
但是,当我查看我在计算机上所做的示例(不是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%)
Run Code Online (Sandbox Code Playgroud)
很明显,该total_float_ops属性考虑了乘法,加法和减法。
然后,我回头看一下MobileNets示例,简要浏览一下该论文,我发现MobileNet的实现是基于参数数量的默认Keras实现:

表格中的第一个模型与您得到的结果(4,253,864)相匹配,而“多加” flops结果大约是您得到的结果的一半。因此,您有正确的答案,只是您误以为是Mult-Adds(又称乘法累加或MAC)。
如果要计算MAC的数量,只需要将上述代码的结果除以2。
这在 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
Run Code Online (Sandbox Code Playgroud)
以上解决方案不能运行两次,否则会累积失败!(换句话说,第二次运行它时,您将得到 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
Run Code Online (Sandbox Code Playgroud)
从@driedler 修改,谢谢!
| 归档时间: |
|
| 查看次数: |
3951 次 |
| 最近记录: |