Deep learning 如何为类似CNN的ResNet手动计算反向过程中的失败次数?

Deep learning 如何为类似CNN的ResNet手动计算反向过程中的失败次数?,deep-learning,neural-network,conv-neural-network,backpropagation,deep-residual-networks,Deep Learning,Neural Network,Conv Neural Network,Backpropagation,Deep Residual Networks,我一直在试图找出如何计算ResNet向后传递的失败次数。对于前向传递,它似乎很简单:将conv过滤器应用于每个层的输入。但是,在向后传球过程中,如何计算梯度和更新所有权重的触发器计数 具体来说, 如何计算每层梯度计算中的触发器 所有梯度都需要计算什么,才能计算每个梯度的失败次数 池、BatchNorm和Relu层的梯度计算中有多少次失败 我理解梯度计算的链式规则,但很难确定它如何应用于ResNet的conv层中的权重过滤器,以及每个层需要多少次失败。这将是非常有用的获得任何意见的方法来计算总

我一直在试图找出如何计算ResNet向后传递的失败次数。对于前向传递,它似乎很简单:将conv过滤器应用于每个层的输入。但是,在向后传球过程中,如何计算梯度和更新所有权重的触发器计数

具体来说,

  • 如何计算每层梯度计算中的触发器

  • 所有梯度都需要计算什么,才能计算每个梯度的失败次数

  • 池、BatchNorm和Relu层的梯度计算中有多少次失败


我理解梯度计算的链式规则,但很难确定它如何应用于ResNet的conv层中的权重过滤器,以及每个层需要多少次失败。这将是非常有用的获得任何意见的方法来计算总倒转通过。谢谢

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

通常,对于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}')
输出:


我的问题更多的是关于如何手动操作,也就是说,查看图层,查看它的过滤器大小,并获得它需要的ops计数backprop,而无需编码。例如,对于Resnet-50的第一个瓶颈块(仅3层),你会怎么做?不要认为这适合这个频道。我投票结束这个问题,因为OP提出的是一个关于数学计算的问题,而不是特定于代码的解决方案。在统计上交叉发布了三次。所以
51112224
102224449
forward: 51112224
backward: 51112225