[docs]defget_flops(model):""" Calculate FLOPS for a tf.keras.Model or tf.keras.Sequential model in inference mode. It uses tf.compat.v1.profiler under the hood. Args: model (:obj:`keras.Model`): the model to evaluate Returns: :obj:`tf.compat.v1.profiler.GraphNodeProto`: object containing the FLOPS """# Prepare a constant input to pass to the profilerinput_shape=model.inputs[0].shape.as_list()input_shape[0]=1x=tf.constant(tf.fill(input_shape,1))ifnotisinstance(model,(tf.keras.models.Sequential,tf.keras.models.Model)):raiseValueError("Calculating FLOPS is only supported for `tf.keras.Model`""and `tf.keras.Sequential` instances.")# convert tf.keras model into frozen graph to count FLOPs about operations used at inferencereal_model=tf.function(model).get_concrete_function(x)frozen_func,_=convert_variables_to_constants_v2_as_graph(real_model)# Calculate FLOPs with tf.profilerrun_meta=tf.compat.v1.RunMetadata()opts=(tf.compat.v1.profiler.ProfileOptionBuilder(tf.compat.v1.profiler.ProfileOptionBuilder().float_operation()).with_empty_output().build())flops=tf.compat.v1.profiler.profile(graph=frozen_func.graph,run_meta=run_meta,cmd="scope",options=opts)tf.compat.v1.reset_default_graph()returnflops
[docs]defdisplay_macs(model_path,verbose=False):"""Displays the MACs for a keras model By default it displays only the total MACS. Args: model (:obj:`keras.Model`): the model to evaluate verbose (bool): display MACS for each operation """model=load_model(model_path)flops=get_flops(model)ifverbose:defdisplay_children_macs(nodes):fornodeinnodes:print(f"{node.name}: {node.total_float_ops/2:e} MACS")display_children_macs(node.children)# Recursively display MACS by node (i.e. operation)display_children_macs(flops.children)# We divide FLOPS by 2 to obtain an estimate of Multiply and Accumulate (MACS)print(f"Total: {flops.total_float_ops/2:e} MACS")