You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

构建124x124人像生成CNN模型时遇ValueError问题求助

解决Keras Sequential模型未调用导致的input未定义错误

我正在构建一个用于生成124×124像素人像的CNN模型,代码如下:

model = Sequential()
model.add(Embedding(num_samples, PARAM_SIZE, input_shape = (1,)))
print (model.output_shape)
model.add(Flatten(name='pre_encoder'))
print (model.output_shape)
model.add(Reshape((PARAM_SIZE, 1, 1), name='encoder'))
print (model.output_shape)
model.add(Conv2DTranspose(256, 4))           #(4, 4)
model.add(Activation("relu"))
print (model.output_shape)
model.add(Conv2DTranspose(256, 4, strides = 2))                #(10,10)
model.add(Activation("relu"))
print (model.output_shape)
model.add(Conv2DTranspose(128, 4))                #(13, 13)
model.add(Activation("relu"))
print (model.output_shape)
model.add(Conv2DTranspose(64, 4, strides = 2))                #(28,28)
model.add(Activation("relu"))
print (model.output_shape)
model.add(Conv2DTranspose(32, 6, strides = 2))                #(60,60)
model.add(Activation("relu"))
print (model.output_shape)
model.add(Conv2DTranspose(3, 6, strides = 2))                #(124,124)
model.add(Activation("sigmoid"))
print (model.output_shape)
    
model.compile(optimizer='adam', loss='mse')

func = Model(inputs = model.get_layer('encoder').input, outputs = model.layers[-1].output)
enc_model = Model(inputs=model.input,
                  outputs=model.get_layer('pre_encoder').output)

运行代码时出现如下错误:

ValueError                                Traceback (most recent call last)
Cell In[11], line 2
      1 # model.layers[-1].output
----> 2 model.input

File D:\Program_files\envs\btp_project\Lib\site-packages\keras\src\ops\operation.py:228, in Operation.input(self)
    218 @property
    219 def input(self):
    220     """Retrieves the input tensor(s) of a symbolic operation.
    221 
    222     Only returns the tensor(s) corresponding to the *first time*
   (...)
    226         Input tensor or list of input tensors.
    227     """
--> 228     return self._get_node_attribute_at_index(0, "input_tensors", "input")

File D:\Program_files\envs\btp_project\Lib\site-packages\keras\src\ops\operation.py:259, in Operation._get_node_attribute_at_index(self, node_index, attr, attr_name)
    243 """Private utility to retrieves an attribute (e.g. inputs) from a node.
    244 
    245 This is used to implement the properties:
   (...)
    256     The operation's attribute `attr` at the node of index `node_index`.
    257 """
    258 if not self._inbound_nodes:
--> 259     raise ValueError(
    260         f"The layer {self.name} has never been called "
    261         f"and thus has no defined {attr_name}."
    262     )
    263 if not len(self._inbound_nodes) > node_index:
    264     raise ValueError(
    265         f"Asked to get {attr_name} at node "
    266         f"{node_index}, but the operation has only "
    267         f"{len(self._inbound_nodes)} inbound nodes."
    268     )

ValueError: The layer sequential has never been called and thus has no defined input.

错误原因

Keras的Sequential模型在未被实际调用(传入数据执行前向传播)之前,不会生成具体的输入/输出张量节点。当你尝试访问model.input或通过model.get_layer('encoder').input创建子模型时,原模型还未完成一次前向计算,因此无法获取这些张量属性。

解决方案

方式一:触发模型前向传播

在创建子模型之前,喂入一个符合输入形状的测试数据,让模型完成一次前向计算,生成所需的节点信息:

import tensorflow as tf
from tensorflow.keras.models import Sequential, Model
from tensorflow.keras.layers import Embedding, Flatten, Reshape, Conv2DTranspose, Activation

# 假设已定义num_samples和PARAM_SIZE
num_samples = 10000
PARAM_SIZE = 128

model = Sequential()
model.add(Embedding(num_samples, PARAM_SIZE, input_shape=(1,)))
print(model.output_shape)
model.add(Flatten(name='pre_encoder'))
print(model.output_shape)
model.add(Reshape((PARAM_SIZE, 1, 1), name='encoder'))
print(model.output_shape)
model.add(Conv2DTranspose(256, 4))           #(4, 4)
model.add(Activation("relu"))
print(model.output_shape)
model.add(Conv2DTranspose(256, 4, strides=2))                #(10,10)
model.add(Activation("relu"))
print(model.output_shape)
model.add(Conv2DTranspose(128, 4))                #(13, 13)
model.add(Activation("relu"))
print(model.output_shape)
model.add(Conv2DTranspose(64, 4, strides=2))                #(28,28)
model.add(Activation("relu"))
print(model.output_shape)
model.add(Conv2DTranspose(32, 6, strides=2))                #(60,60)
model.add(Activation("relu"))
print(model.output_shape)
model.add(Conv2DTranspose(3, 6, strides=2))                #(124,124)
model.add(Activation("sigmoid"))
print(model.output_shape)
    
model.compile(optimizer='adam', loss='mse')

# 关键:喂入测试数据触发前向传播
test_input = tf.random.uniform((1, 1), maxval=num_samples, dtype=tf.int32)
model(test_input)

# 现在可正常创建子模型
func = Model(inputs=model.get_layer('encoder').input, outputs=model.layers[-1].output)
enc_model = Model(inputs=model.input, outputs=model.get_layer('pre_encoder').output)

方式二:改用函数式API构建模型

函数式API从一开始就显式定义张量流动,所有层的输入输出张量都是明确的,无需依赖模型调用生成节点,更适合需要提取中间层构建子模型的场景:

import tensorflow as tf
from tensorflow.keras.models import Model
from tensorflow.keras.layers import Input, Embedding, Flatten, Reshape, Conv2DTranspose, Activation

num_samples = 10000
PARAM_SIZE = 128

# 显式定义输入层
input_layer = Input(shape=(1,))
x = Embedding(num_samples, PARAM_SIZE)(input_layer)
print(x.shape)
pre_encoder = Flatten(name='pre_encoder')(x)
print(pre_encoder.shape)
encoder = Reshape((PARAM_SIZE, 1, 1), name='encoder')(pre_encoder)
print(encoder.shape)
x = Conv2DTranspose(256, 4)(encoder)           #(4, 4)
x = Activation("relu")(x)
print(x.shape)
x = Conv2DTranspose(256, 4, strides=2)(x)                #(10,10)
x = Activation("relu")(x)
print(x.shape)
x = Conv2DTranspose(128, 4)(x)                #(13, 13)
x = Activation("relu")(x)
print(x.shape)
x = Conv2DTranspose(64, 4, strides=2)(x)                #(28,28)
x = Activation("relu")(x)
print(x.shape)
x = Conv2DTranspose(32, 6, strides=2)(x)                #(60,60)
x = Activation("relu")(x)
print(x.shape)
output_layer = Conv2DTranspose(3, 6, strides=2)(x)                #(124,124)
output_layer = Activation("sigmoid")(output_layer)
print(output_layer.shape)

model = Model(inputs=input_layer, outputs=output_layer)
model.compile(optimizer='adam', loss='mse')

# 直接创建子模型,无需提前调用模型
func = Model(inputs=encoder, outputs=output_layer)
enc_model = Model(inputs=input_layer, outputs=pre_encoder)

内容的提问来源于stack exchange,提问作者Rishi Saini

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 18:58:12