如何手动计算像ResNet这样的CNN的反向通道中的FLOPS数量



我一直在想如何计算ResNet向后传递中的浮点数。对于前向传递,似乎很简单:将conv滤波器应用于每一层的输入。但是,在向后传递过程中,如何对梯度计算和所有权重的更新进行Flops计数?

具体而言,

  • 如何在每层的梯度计算中计算Flops?

  • 需要计算哪些所有梯度才能计算出每个梯度的Flops?

  • Pool、BatchNorm和Relu层的梯度计算中有多少Flops?

我理解梯度计算的链式规则,但很难制定它如何应用于ResNet的conv层中的权重过滤器,以及每层需要多少Flops。这将是非常有用的,得到任何意见的方法,以计算总的Flops向后传球。谢谢

您肯定可以手动计算向后传递的乘法和加法的数量,但我想这对复杂模型来说是一个详尽的过程。

通常,大多数模型的基准是前向传球的失败次数,而不是CNN和其他模型的后向失败次数。我想原因与推理在应用程序中的不同CNN变体和其他深度学习模型方面更重要有关。

后向传球只在训练时很重要,对于大多数简单的模型,后向和前向的失误应该与一些恒定的因素接近。

因此,我尝试了一种巧妙的方法来计算图中整个resnet模型的梯度,以获得前向通过和梯度计算的失败次数,然后减去前向失败次数。这不是一个精确的测量,可能会错过复杂图形/模型的许多操作。

但这可能会给大多数模型一个失败的估计。

[以下代码片段适用于tensorflow 2.0]

import tensorflow as tf
def get_flops():
for_flop = 0
total_flop = 0
session = tf.compat.v1.Session()
graph = tf.compat.v1.get_default_graph()
# forward
with graph.as_default():
with session.as_default():
model = tf.keras.applications.ResNet50() # change your model here
run_meta = tf.compat.v1.RunMetadata()
opts = tf.compat.v1.profiler.ProfileOptionBuilder.float_operation()
# 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)
for_flop = flops.total_float_ops
# print(for_flop)
# forward + backward
with graph.as_default():
with session.as_default():
model = tf.keras.applications.ResNet50() # change your model here

outputTensor = model.output 
listOfVariableTensors = model.trainable_weights
gradients = tf.gradients(outputTensor, listOfVariableTensors)
run_meta = tf.compat.v1.RunMetadata()
opts = tf.compat.v1.profiler.ProfileOptionBuilder.float_operation()
# 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)
total_flop = flops.total_float_ops
# print(total_flop)
return for_flop, total_flop

for_flops, total_flops = get_flops()
print(f'forward: {for_flops}')
print(f'backward: {total_flops - for_flops}')

输出:

51112224
102224449
forward: 51112224
backward: 51112225

最新更新