[英]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.