简体   繁体   English

EfficientNetB3 架构制作 Class 激活 Map (CAM)

[英]Making Class Activation Map (CAM) for EfficientNetB3 architecture

I would like to draw a class activation map for a model built upon EfficeintNet B3.我想为基于 EfficeintNet B3 的 model 绘制一个 class 激活 map。 But when I follow different tutorials and codes from different sources, it simply fails....但是当我遵循不同来源的不同教程和代码时,它就失败了……

#load images
img = tf.keras.preprocessing.image.load_img(
        base, target_size=(img_height, img_width))
img_array = tf.keras.preprocessing.image.img_to_array(img)
img_array = tf.expand_dims(img_array, 0) # Create a batch
predictions = model.predict(img_array)
score = tf.nn.softmax(predictions[0])


last_conv = model.layers[2].layers[-3]

grad_model = tf.keras.models.Model(
    [model.inputs], [last_conv.output, model.output])

Can't build a grad_model无法构建 grad_model

ValueError: Graph disconnected: cannot obtain value for tensor KerasTensor(type_spec=TensorSpec(shape=(None, 300, 300, 3), dtype=tf.float32, name='input_1'), name='input_1', description="created by layer 'input_1'") at layer "stem_conv". ValueError:图形断开连接:无法获取张量 KerasTensor(type_spec=TensorSpec(shape=(None, 300, 300, 3), dtype=tf.float32, name='input_1'), name='input_1', description="由“input_1”层“stem_conv”层创建。 The following previous layers were accessed without issue: []可以毫无问题地访问以下先前的层:[]

This is the model:这是 model:

 Model: "sequential_1"
    _________________________________________________________________
    Layer (type)                 Output Shape              Param #   
    =================================================================
    sequential (Sequential)      (None, 300, 300, 3)       0         
    _________________________________________________________________
    rescaling (Rescaling)        (None, 300, 300, 3)       0         
    _________________________________________________________________
    efficientnet-b3 (Functional) (None, 10, 10, 1536)      10783528  
    _________________________________________________________________
    global_average_pooling2d (Gl (None, 1536)              0         
    _________________________________________________________________
    dropout (Dropout)            (None, 1536)              0         
    _________________________________________________________________
    dense (Dense)                (None, 128)               196736    
    _________________________________________________________________
    dense_1 (Dense)              (None, 5)                 645       
    =================================================================

To address the graph disconnected value error, you need to build the grad cam model properly.要解决图形断开值错误,您需要正确构建 grad cam model。 Here is one of the ways to build a model for grad-cam.这是为 grad-cam 构建 model 的方法之一。

import tensorflow as tf 
from tensorflow import keras
from tensorflow.keras import layers

inputs = tf.keras.Input(shape=(300, 300, 3))

x = keras.applications.EfficientNetB3(
    input_tensor=inputs, # pass input to input_tensor 
    include_top=False,
    weights=None
)

# flat the base model with x.output 
x = layers.GlobalAveragePooling2D()(x.output) 

# others 
x = layers.Dense(128)(x)
x = layers.Dropout(0.5)(x)
x = layers.Dense(5)(x)

model = keras.Model(inputs, x)

for i, layer in enumerate(model.layers[-10:]):
    print(i, layer.name, layer.output_shape, layer.trainable)
0 block7b_project_bn (None, 10, 10, 384) True
1 block7b_drop (None, 10, 10, 384) True
2 block7b_add (None, 10, 10, 384) True
3 top_conv (None, 10, 10, 1536) True
4 top_bn (None, 10, 10, 1536) True
5 top_activation (None, 10, 10, 1536) True  # < - We will pick this 2D maps
6 global_average_pooling2d_2 (None, 1536) True
7 dense_2 (None, 128) True
8 dropout (None, 128) True
9 dense_3 (None, 5) True

Build Grad-CAM Model构建 Grad-CAM Model

grad_model = keras.models.Model(
    [model.inputs], 
    [
        model.get_layer('top_activation').output, 
        model.output
     ]
)

Check查看

With your setup, you would get a disconnected error with the following code.使用您的设置,您会收到以下代码的断开连接错误。 But now, it wouldn't happen.但现在,这不会发生。

import numpy as np 

image = np.random.rand(1, 300, 300, 3).astype(np.float32) 

with tf.GradientTape() as tape:
    convOutputs, predictions = grad_model(tf.cast(image, tf.float32))
    loss = predictions[:, tf.argmax(predictions[0])]

grads = tape.gradient(loss, convOutputs)
print(grads.shape) 
(1, 10, 10, 1536) # NO DISCONNECTED ERROR

To get the heatmaps from your grad-cam model, check the following answers and sources as references.要从您的 grad-cam model 获取热图,请检查以下答案和来源作为参考。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM