如何计算Keras中的Mobilenet FLOP

时间:2018-03-28 03:48:19

标签: deep-learning keras flops

ITEM  BOX  PLASTIC  
ABC     2      0   
GHI     0      5  
JKL     0      5

当我运行上面的代码时,我得到了以下结果

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

这与本文中描述的触发器不同。

mobilenet:https://arxiv.org/pdf/1704.04861.pdf

ShuffleNet:https://arxiv.org/pdf/1707.01083.pdf

如何计算论文中描述的精确翻牌?

4 个答案:

答案 0 :(得分:7)

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

答案 1 :(得分:6)

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

但是,当我在计算机上查看自己的示例(不是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实现:

image

表中的第一个模型与您得到的结果(4,253,864)相匹配,并且Mult-Adds大约是您得到的flops结果的一半。因此,您有正确的答案,只是您误以为是Mult-Adds(又名乘累加或MAC)的翻牌。

如果要计算MAC的数量,只需要将以上代码的结果除以2。

答案 2 :(得分:5)

上述解决方案不能运行两次,否则翻牌将累积! (换句话说,第二次运行它,将得到输出= flops_of_1st_call + flops_of_2nd_call。)下面的代码调用Offer来避免这种情况。

reset_default_graph

由@driedler修改,谢谢!

答案 3 :(得分:0)

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