我正在尝试使用我自己的模型来遵循这个GradCam教程。以下是模型的架构:
import tensorflow as tffrom tensorflow import keras as Kimport numpy as npclass CNNModel(K.Model): def __init__(self): super(CNNModel, self).__init__() self.base = K.applications.EfficientNetB1(input_shape=(224, 224, 12), include_top=False, weights=None) self.pool = K.layers.GlobalAveragePooling2D() self.drop1 = K.layers.Dropout(0.25) self.dense1 = K.layers.Dense(16, activation='relu') self.drop2 = K.layers.Dropout(0.25) self.out = K.layers.Dense(1, activation='sigmoid') def call(self, x, training=None, **kwargs): x = self.base(x) x = self.pool(x) x = self.drop1(x) x = self.dense1(x) x = self.drop2(x) x = self.out(x) return xmodel = CNNModel()model.build(input_shape=(None, 224, 224, 12))
我需要获取最后一个卷积层,因此我从基础(EfficientNet)模型中获取该层:
last_conv_layer_name = list(filter(lambda x: isinstance(x, tf.keras.layers.Conv2D), model.base.layers))[-1].name
然后我尝试基于此创建一个具有两个输出的模型,就像教程中那样。
grad_model = tf.keras.models.Model( [model.base.inputs], [model.base.get_layer(last_conv_layer_name).output, model.output] )
我得到了以下错误:
AttributeError: Layer cnn_model has no inbound nodes
回答:
我遇到过类似的问题,关于子类API模型,并进一步尝试将其用于grad-cam,通过将其纳入功能API中。当时对我有效的方法是为grad-cam单独构建一个子类模型,并在__init__
中构建所需的输出模型。
class CNNModel(K.Model): def __init__(self): super(CNNModel, self).__init__() self.base = K.applications.EfficientNetB1(input_shape=(224, 224, 12), include_top=False, weights=None) # 所需的模型 self.base = K.Model( [self.base.inputs], [self.base.get_layer('top_conv').output, self.base.output] ) self.pool = K.layers.GlobalAveragePooling2D() self.drop1 = K.layers.Dropout(0.25) self.dense1 = K.layers.Dense(16, activation='relu') self.drop2 = K.layers.Dropout(0.25) self.out = K.layers.Dense(1, activation='sigmoid') def call(self, x, training=None, **kwargs): x = self.base(x) top_conv = x[0] x = x[1] x = self.pool(x) x = self.drop1(x) x = self.dense1(x) x = self.drop2(x) x = self.out(x) return top_conv, xmodel = CNNModel()model.build(input_shape=(None, 224, 224, 12))
传递一些数据来检查。
img_array = np.random.rand(1, 224, 224, 12).astype(np.float32)(convOutputs, predictions) = model(img_array)print(convOutputs.shape, predictions.shape)(1, 7, 7, 1280) (1, 1)