TensorFlow Profiler统计FLOPs为何不随输入形状变化?
问题原因及修复方案
你统计得到的23563360 FLOPs远小于ResNet50的正常推理运算量(224×224输入下约4GFLOPs),说明你没有采集到实际推理过程的浮点运算,数值不变的具体原因如下:
- 运行元数据未正确收集:你代码中声明的
run_meta是空对象,调用model.predict()时没有传入运行时元数据参数,导致profiler仅统计了静态图中与固定权重相关的运算量,这部分数值和输入尺寸无关。 - 全局计算图未重置:如果在同一Python进程内多次切换
INPUT_SHAPE运行逻辑,没有提前调用tf.compat.v1.reset_default_graph()清空全局默认图、重建会话,旧的模型节点会残留在图中,多次统计会复用缓存的错误结果。 - Profiler参数配置不当:你使用
cmd="scope"按命名空间统计,容易遗漏和输入张量动态尺寸关联的卷积算子,建议调整为按算子类型统计的配置。
修复后的代码示例
import tensorflow as tf import numpy as np from tensorflow.keras.layers import Input from tensorflow.keras.applications.resnet50 import ResNet50, preprocess_input def pre_process(img_size=(224, 224, 3)): x = np.random.rand(img_size[0], img_size[1], img_size[2]) x = np.expand_dims(x, axis=0) x = preprocess_input(x) return x def get_total_flops(graph, session, run_meta): opts = tf.compat.v1.profiler.ProfileOptionBuilder.float_operation() opts['output'] = 'none' flops = tf.compat.v1.profiler.profile( graph=graph, run_meta=run_meta, cmd="op", options=opts ) return flops.total_float_ops # 每次切换输入尺寸前先重置默认图 tf.compat.v1.reset_default_graph() session = tf.compat.v1.Session() graph = tf.compat.v1.get_default_graph() INPUT_SHAPE = (256, 256, 3) model = ResNet50(weights=None, input_tensor=Input(shape=INPUT_SHAPE), classes=1) x = pre_process(img_size=INPUT_SHAPE) with graph.as_default(), session.as_default(): session.run(tf.compat.v1.global_variables_initializer()) # 采集运行时元数据 run_meta = tf.compat.v1.RunMetadata() opts = tf.compat.v1.RunOptions(trace_level=tf.compat.v1.RunOptions.FULL_TRACE) # 直接用sess.run跑推理,传入run_meta和run_options _ = session.run(model.output, feed_dict={model.input: x}, options=opts, run_metadata=run_meta) total_flops = get_total_flops(graph, session, run_meta) print('total_flops: ', total_flops)
运行修改后的代码,切换不同输入尺寸即可看到FLOPs随输入分辨率平方级增长的正常结果。
内容的提问来源于stack exchange,提问作者Guinther Kovalski
相关产品推荐
相关产品推荐

