Deep learning 如何计算Keras中的Mobilenet触发器

Deep learning 如何计算Keras中的Mobilenet触发器,deep-learning,keras,flops,Deep Learning,Keras,Flops,run\u meta=tf.RunMetadata() 输入codwith tf.Session(graph=tf.graph())作为sess: K.SETU会话(sess) 使用tf.device('/cpu:0'): 基本模型=MobileNet(alpha=1,权重=None,输入张量=tf.placeholder('float32',形状=(1224224,3))) opts=tf.profiler.ProfileOptionBuilder.float\u操作() flops=tf.p

run\u meta=tf.RunMetadata()
输入codwith tf.Session(graph=tf.graph())作为sess:
K.SETU会话(sess)
使用tf.device('/cpu:0'):
基本模型=MobileNet(alpha=1,权重=None,输入张量=tf.placeholder('float32',形状=(1224224,3)))
opts=tf.profiler.ProfileOptionBuilder.float\u操作()
flops=tf.profiler.profile(sess.graph,run\u meta=run\u meta,cmd='op',options=opts)
opts=tf.profiler.ProfileOptionBuilder.trainable_variables_parameter()
params=tf.profiler.profile(sess.graph,run\u meta=run\u meta,cmd='op',options=opts)
打印(“{:,}-{:,}”。格式(flops.total\u float\u ops,params.total\u parameters))
当我运行上面的代码时,得到了下面的结果

1137481704---4253864
这与本文中描述的触发器不同

美孚网络:

ShuffleNet:


如何计算论文中描述的精确触发器?

您可以在所有Keras模型上使用
model.summary()
来获得触发器的数量。

tl;dr你真的得到了正确的答案!您只是将触发器与乘法累加(从纸上)进行比较,因此需要除以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)时,打印出来的总浮点运算量为2115,当我简单地打印
浮点变量时,我得到了以下结果:

[...]
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\u float\u ops
属性考虑了乘法、加法和减法

然后,我回顾了MobileNet示例,简要地浏览了本文,我发现MobileNet的实现是基于参数数量的默认Keras实现:

表中的第一个模型与您得到的结果(4253864)匹配,Mult ADD大约是您得到的
flops
结果的一半。因此,你得到了正确的答案,只是你把触发器误认为是Mult-Adds(又称乘法累加或mac)

如果你想计算mac的数量,你只需要把上面代码的结果除以2


重要注意事项

如果要运行代码示例,请记住以下几点:

  • 代码示例编写于2018年,不适用于tensorflow版本2。有关tensorflow版本2兼容性的完整示例,请参见@driedler的答案
  • 代码示例最初打算在已编译的模型上运行一次。。。有关以没有副作用(因此可以在同一个模型上多次运行)的方式使用它的更好示例,请参阅@ch271828n的答案

  • 这在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
    
    上述解决方案不能运行两次,否则触发器将累积!(换句话说,第二次运行它时,您将得到输出=第一次调用的flops\u+第二次调用的flops\u。)以下代码调用
    reset\u default\u graph
    ,以避免这种情况

    def get_flops():
    session=tf.compat.v1.session()
    graph=tf.compat.v1.get\u default\u graph()
    使用graph.as_default():
    使用session.as_default():
    模型=keras.applications.mobilenet.mobilenet(
    alpha=1,weights=None,input_tensor=tf.compat.v1.placeholder('float32',shape=(1224224,3)))
    run_meta=tf.compat.v1.RunMetadata()
    opts=tf.compat.v1.profiler.ProfileOptionBuilder.float\u操作()
    #可选:将打印结果保存到文件
    #flops\u log\u path=os.path.join(tempfile.gettempdir(),'tf\u flops\u log.txt')
    #选择['output']='file:outfile={}'。格式(flops\u log\u路径)
    #我们在调用探查器时使用Keras会话图。
    flops=tf.compat.v1.profiler.profile(图形=图形,
    run\u meta=run\u meta,cmd='op',options=opts)
    tf.compat.v1.reset\u default\u graph()
    返回浮点运算。总浮点运算
    

    修改自@driedler,谢谢

    这只列出了参数的数量为什么需要
    model
    作为
    get\u flops
    的参数?在Tensorflow 2.1.0上,它给出了一个错误:
    AttributeError:模块“Tensorflow”没有属性“RunMetadata”
    MAC的数量不等于
    参数/2
    。在本文中,您可以看到
    参数
    为420万,而
    Mult Adds
    为5.69亿。因此,这种方法计算MAC的数量是错误的。我也不确定是哪一个。@gizmole…idk,lol。也许我最初的推理是,当你调用函数时,它必须是一个编译模型@秦鹤阳他们完全有可能不赞成或删除了该模块。事实上,只要浏览文档,它就在
    2.1.0
    中的
    tf.compat.v1.RunMetadata
    中。在v2文档中可能有更好的替代方案。。。如果你发现了什么,我可以编辑我的答案,或者你可以单独回答@AwaisHussain它不是
    参数/2
    ,如果你重新阅读我的回复,你会发现我没有声明。感谢你的修改,当我在一个大约有18个卷积层的模型上运行它时,我得到以下===================================================================配置文件:===TFProfRoot 0浮点运算(0.00%,0.00%)=========================================================================================================有些事情似乎不对劲。我的型号摘要打印总参数:176240可培训参数:176240不可培训参数:0我不确定。也许TF1.x分析器有问题?请注意,假设他们正在使用TF2.x分析器:我让它工作了,问题是我