how to calculate a Mobilenet FLOPs in Keras

后端 未结 4 1325
借酒劲吻你
借酒劲吻你 2020-12-16 18:14

run_meta = tf.RunMetadata()
enter codwith tf.Session(graph=tf.Graph()) as sess:
K.set_session(sess)


with tf.dev         


        
相关标签:
4条回答
  • 2020-12-16 18:22

    The above solutions cannot be run twice, otherwise the flops will accumulate! (In other words, the second time you run it, you will get output = flops_of_1st_call + flops_of_2nd_call.) The following code calls reset_default_graph to avoid this.

    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
    
    

    Modified from @driedler, thanks!

    0 讨论(0)
  • 2020-12-16 18:31

    tl;dr You've actually got the right answer! You are simply comparing flops with multiply accumulates (from the paper) and therefore need to divide by two.

    If you're using Keras, then the code you listed is slightly over-complicating things...

    Let model be any compiled Keras model. We can arrive at the flops of the model with the following code.

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

    However, when I look at my own example (not Mobilenet) that I did on my computer, the printed out total_float_ops was 2115 and I had the following results when I simply printed the flops variable:

    [...]
    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%)
    

    It's pretty clear that the total_float_ops property takes into consideration multiplication, addition and subtraction.

    I then looked back at the MobileNets example, looking through the paper briefly, I found the implementation of MobileNet that is the default Keras implementation based on the number of parameters:

    image

    The first model in the table matches the result you have (4,253,864) and the Mult-Adds are approximately half of the flops result that you have. Therefore you have the correct answer, it's just you were mistaking flops for Mult-Adds (aka multiply accumulates or MACs).

    If you want to compute the number of MACs you simply have to divide the result from the above code by two.

    0 讨论(0)
  • 2020-12-16 18:33

    This is working for me in 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
    
    0 讨论(0)
  • 2020-12-16 18:45

    You can use model.summary() on all Keras models to get number of FLOPS.

    0 讨论(0)
提交回复
热议问题