Keras子类API构建卷积网络时model.summary()输出异常求助
解决Keras子类API中
model.summary()层顺序混乱、无输出形状的问题 你遇到的这个问题是Keras子类API的常见特性,完全不用重写model.summary()方法,两个简单步骤就能搞定:
问题根源
- 层顺序混乱:子类模型的
summary()默认是按照你在__init__方法里定义层的顺序来展示的,而不是call方法中实际的执行顺序,所以才会出现和你逻辑不符的层排列。 - 输出形状显示
multiple:仅调用build()只是让模型知晓输入的形状框架,但没有实际运行计算图,Keras无法推导各层的具体输出形状,因此只能显示multiple。
具体解决方法
1. 调整层的定义顺序,与执行逻辑对齐
把__init__里的层定义顺序改成和call方法中的执行顺序一致,这样summary里的层顺序就会和模型实际运行的顺序匹配。
2. 用示例输入触发计算图构建
在调用summary()之前,让模型处理一次符合输入形状的虚拟张量,或者直接在初始化模型时指定输入形状(Python 3.6+支持),这样Keras就能计算出各层的准确输出形状。
修改后的完整代码
import tensorflow as tf from tensorflow import keras class thing(keras.Model): def __init__(self, **kwargs): super().__init__(**kwargs) # 按call方法中的执行顺序定义层 self.conv1 = keras.layers.Conv2D(96, kernel_size=(11, 11), strides=4, activation="relu", data_format="channels_last") self.pool = keras.layers.MaxPooling2D(pool_size=(3,3), strides=2, data_format="channels_last") self.flatten = keras.layers.Flatten(data_format="channels_last") self.dense = keras.layers.Dense(4096, activation="relu") def call(self, inputs): conv1 = self.conv1(inputs) pool1 = self.pool(conv1) flatten_conv = self.flatten(pool1) ff_1 = self.dense(flatten_conv) return ff_1 # 方法一:用虚拟输入调用模型,触发计算图构建 a = thing() dummy_input = tf.random.normal((1, 277, 277, 3)) _ = a(dummy_input) a.summary() # 方法二:初始化时直接指定input_shape(Python 3.6+支持) # a = thing(input_shape=(277,277,3)) # a.summary()
执行后,summary()会输出正确的结果:
Model: "thing" _________________________________________________________________ Layer (type) Output Shape Param # ================================================================= conv2d (Conv2D) (1, 67, 67, 96) 34944 max_pooling2d (MaxPooling2D (1, 33, 33, 96) 0 ) flatten (Flatten) (1, 10368) 0 dense (Dense) (1, 4096) 415240192 ================================================================= Total params: 415,275,136 Trainable params: 415,275,136 Non-trainable params: 0 _________________________________________________________________
内容的提问来源于stack exchange,提问作者Aditya Mehrotra
相关产品推荐
相关产品推荐

