簡體   English   中英

keras 子類 model 中的 Plot cnn 中間層

[英]Plot cnn intermediate layer in keras subclass model

我有以下子類 model:

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).

這個想法是plot什么是output來自各個cnn的層。 上面的代碼適用於Sequential()模型,但不適用於這個子類 model。 我只能plot第一個intermediate_layer(第一個cnn層)。

有誰知道我該如何解決這個錯誤?

示例工作代碼

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)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM