如何在Keras中计算Mobilenet FLOP

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。

  • 为什么需要使用“模型”作为“ get_flops”的参数? (4认同)

use*_*323 8

这在 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)

  • 嗨,看来**这不能运行两次,否则失败次数会累积**...我提供了一点改进,请参阅我的答案:) (2认同)

fzy*_*cjy 5

以上解决方案不能运行两次,否则会累积失败!(换句话说,第二次运行它时,您将得到 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 修改,谢谢!


Ped*_*ram -14

您可以model.summary()在所有 Keras 模型上使用来获取 FLOPS 数。

  • 这只列出了参数的数量 (7认同)