【问题标题】:Plot cnn intermediate layer in keras subclass model在 keras 子类模型中绘制 cnn 中间层
【发布时间】:2021-03-11 07:35:36
【问题描述】:

我有以下子类模型:

class MyModel(tf.keras.Model):

    def __init__(self, dropout_ratio=0.25, activation='relu', *args, **kwargs):
        super(MyModel, self).__init__(*args, **kwargs)

        self.layer_list = []
        # Input = 256
        self.layer_list.append(
            Conv2D(32, (3, 3), padding='valid', name='cnn_256pix_1', activation=activation, strides=1, dtype='float32'))
        self.layer_list.append(
            Conv2D(32, (3, 3), padding='valid', name='cnn_256pix_2', activation=activation, strides=1))

        self.layer_list.append(MaxPooling2D(pool_size=(2, 2)))
        self.layer_list.append(Dropout(dropout_ratio))
        # 128
        self.layer_list.append(
            Conv2D(64, (3, 3), padding='valid', name='cnn_128pix_1', activation=activation, strides=1))
        self.layer_list.append(
            Conv2D(64, (3, 3), padding='valid', name='cnn_128pix_2', activation=activation, strides=1))

        self.layer_list.append(MaxPooling2D(pool_size=(2, 2)))
        self.layer_list.append(Dropout(dropout_ratio))
        # 64
        self.layer_list.append(Conv2D(128, (3, 3), padding='valid', name='cnn_64pix_1', activation=activation))
        self.layer_list.append(Conv2D(128, (3, 3), padding='valid', name='cnn_64pix_2', activation=activation))
        self.layer_list.append(MaxPooling2D(pool_size=(2, 2)))
        self.layer_list.append(Dropout(dropout_ratio))

        self.layer_list.append(Flatten())
        self.layer_list.append(Dense(1024, activation=activation))
        self.layer_list.append(Dropout(0.3))
        self.layer_list.append(Dense(1024, activation=activation))
        self.layer_list.append(Dropout(0.3))
        self.layer_list.append(Dense(19, activation="softmax"))

    def call(self, inputs, **kwargs):
        print("shape: ", tf.shape(inputs))
        inp = inputs
        for layer in self.layer_list:
            inp = layer(inp)  # inp = tensor (1, 256, 256, 3) dtype=float32

        out = {self.layer_list[-1].name: self.layer_list[-1]}
        return out

    def compile(self, loss='mse', optimizer=RMSprop(lr=0.0001, clipvalue=1.0), **kwargs):
        self.output_names = self.layer_list[-1].name
        return super().compile(loss=loss, optimizer=optimizer, **kwargs)

绘制cnn中间层的代码是这样的:

model = MyModel()
print(evaluation_img.shape)  # (1, 256, 256, 3)
model.build(evaluation_img.shape)  # or equally (I think) model(evaluation_img)

layer_to_print = []
    for layer in model.layer_list:
        if "cnn" in layer.name:
            layer_to_print.append(layer)

input = tf.keras.Input(shape=evaluation_img.shape)  # shape=(None, 1, 256, 256, 3), dtype=float32)
for el in layer_to_print:
    intermediate_layer_model = Model(inputs=input, outputs=el(input))
    intermediate_output = intermediate_layer_model.predict(evaluation_img)
    plt.matshow(intermediate_output[0, :, :, intermediate_output.shape[3]-1], cmap='viridis')
    plt.show()

我收到此错误:

ValueError: Input 0 of layer cnn_256pix_2 is incompatible with the layer: expected axis -1 of input shape to have value 32 but received input with shape [None, 1, 256, 256, 3]

还有这个警告:

WARNING:tensorflow:Model was constructed with shape (None, 1, 256, 256, 3) for input Tensor("input_1:0", shape=(None, 1, 256, 256, 3), dtype=float32), but it was called on an input with incompatible shape (None, 256, 256, 3).

这个想法是绘制从各种 cnn 的层输出的内容。上面的代码适用于Sequential() 模型,但不适用于这个子类模型。我只能绘制第一个 middle_layer(第一个 cnn 层)。

有人知道我该如何解决这个错误吗?

【问题讨论】:

    标签: python python-3.x tensorflow keras deep-learning


    【解决方案1】:

    示例工作代码

    import tensorflow as tf
    import numpy as np
    input_shape = (1, 256, 256, 3)
    x = tf.random.normal(input_shape)
    
    model = tf.keras.models.Sequential()
    model.add(tf.keras.layers.Conv2D(32, (3, 3), activation='relu', input_shape=input_shape[1:]))
    model.add(tf.keras.layers.Conv2D(32, (3, 3), activation='relu', input_shape=input_shape[1:]))
    
    output = model(x)
    

    【讨论】:

      猜你喜欢
      • 2021-04-03
      • 1970-01-01
      • 1970-01-01
      • 2020-08-09
      • 1970-01-01
      • 2019-07-24
      • 1970-01-01
      • 2018-08-01
      • 1970-01-01
      相关资源
      最近更新 更多