如何在 Keras 的循环中加速 Grad-CAM 计算?

How to speed up the Grad-CAM calculation within a loop in Keras?

我正在编写一个手工制作的解决方案来计算给定数据集中包含的每个图像的 Grad-CAM。 这是代码:

def grad_cam(model, image, _class, layer_name, channel_index):

    class_output  = model.output[:, _class]
    conv_output_layer = model.get_layer(layer_name).output

    gradients = K.gradients(class_output, conv_output_layer)[0] 
    grad_function = K.function([model.input], [conv_output_layer, gradients])
    output, grad_val = grad_function([image]) # <== Execution time bottleneck

    #code...
    return grad_cam

给定图像、卷积层和通道索引,目的是了解 CNN 分类器正在查看的位置,以及必须为所有数据集的图像计算 Grad-CAM 表示的原因。由于数据集提供了数万张图片,因此在循环中调用grad_cam()函数:

def visual_attention(df):
    #code...
    for i in range(0, len(df)):
        #code...
        heatmap = grad_cam(model, df[i], _class, layer_name, channel_index)
        #code...
    #code...

其中 df 代表整个数据集。即使前面提到的代码工作得很好,我注意到涉及 grad_cam() 函数的速度变慢,因为 K.gradients() 每次调用时都会构建一个新的反向传播图。我做了很多尝试来尝试管理这种情况,但 TensorFlow 在每次迭代后继续向其图形添加新节点。在几百次迭代之后,代码变得慢得令人尴尬。如何处理这种情况?非常感谢您!

你应该拆分grad_function函数的创建,独立使用,例如:

def grad_cam(model, _class, layer_name, channel_index):

    class_output  = model.output[:, _class]
    conv_output_layer = model.get_layer(layer_name).output

    gradients = K.gradients(class_output, conv_output_layer)[0] 
    grad_function = K.function([model.input], [conv_output_layer, gradients])

    return return grad_function

然后你只创建一次 grad 函数的实例:

grad_fn = grad_cam(model, _class, layer_name, channel_index)

然后循环调用这个函数:

def visual_attention(df):
    #code...
    for i in range(0, len(df)):
        #code...
        heatmap = grad_fn(df[i])
        #code...
    #code...