如何解决Keras中model has not yet been built报错问题
报错信息
运行CNN模型调用model.summary()时触发如下报错:
This model has not yet been built. Build the model first by calling `build()` or by calling the model on a batch of data.
排查思路
- 先核对卷积层
data_format参数和input_shape的维度顺序是否匹配:channels_last对应维度顺序为(样本数, 高度, 宽度, 通道数),指定input_shape时不需要写样本数维度,只需要按顺序写高、宽、通道数即可。如果顺序写反,模型无法推导各层张量形状,就会触发未构建的报错。 - 再核对层堆叠的维度逻辑:Conv2D、MaxPooling2D这类卷积层要求输入是三维的特征图(高、宽、通道),如果在卷积层之前插入Flatten把特征拉成一维向量,下一层卷积会收到维度不合法的输入,直接导致模型构建失败。
- 最后检查冗余参数:Sequential模型仅第一层需要指定input_shape,后续层会自动适配前一层的输出形状,重复给非首层指定input_shape容易引发维度冲突。
修复后可运行代码
from tensorflow.keras.models import Sequential from tensorflow.keras.layers import Dense,Dropout from tensorflow.keras.layers import Conv2D from tensorflow.keras.layers import Flatten from tensorflow.keras.layers import MaxPooling2D from tensorflow.keras.callbacks import TensorBoard model = Sequential() # 修正input_shape维度顺序,匹配channels_last要求 model.add(Conv2D(32, 5, input_shape=(28,28,1), activation='relu', data_format='channels_last')) model.add(MaxPooling2D(pool_size=(2,2), strides=2)) # 删除插在卷积层之间的Flatten,保留二维特征图供下一层卷积使用 model.add(Conv2D(64, 5, activation='relu', data_format='channels_last')) model.add(MaxPooling2D(pool_size=2, strides=2)) # 所有卷积、池化操作完成后,再拉平特征接入全连接层 model.add(Flatten()) model.add(Dense(units=32, activation='relu')) model.add(Dropout(0.4)) # 按任务类型调整输出层:10分类任务(如MNIST手写数字)设units=10配softmax;二分类任务设units=1配sigmoid model.add(Dense(units=10, activation='softmax')) model.summary()
关键修改说明
- 把首层Conv2D的input_shape从
(1,28,28)改为(28,28,1),对齐channels_last的维度顺序要求。 - 移除了第一个MaxPooling2D之后错误放置的Flatten层,把Flatten挪到第二个MaxPooling2D之后,保证卷积层能收到合法的二维特征输入。
- 删除了第二个Conv2D层冗余的
input_shape参数,避免手动指定的形状和前层输出冲突。 - 修正了输出层的逻辑错误:原代码输出单元数为1却用softmax激活不符合逻辑,示例中按常见的MNIST 10分类场景改为
units=10,如果做二分类改成units=1, activation='sigmoid'即可。
内容的提问来源于stack exchange,提问作者Ajith
相关产品推荐
相关产品推荐

