Keras拼接Conv1D与Transformer构建集成模型报ValueError求解
问题描述
通过拼接自定义Conv1D模块与Transformer模块的输出层构建集成模型时,逐行验证从concatenate()操作到最终Dense层的所有执行步骤,各环节输出张量形状均符合预期,但执行到Model(inputs, outputs)模型实例化阶段时抛出如下错误:
ValueError: Found unexpected instance while processing input tensors for keras functional model. Expecting KerasTensor which is from tf.keras.Input() or output from keras layer call(). Got: 22
全局输入形状定义:input = (None, 22, 1)
Conv1D模块输出部分代码片段
、、、 x = Add()([x, skip]) x = Activation('relu')(x) x = MaxPooling1D(20)(x) x = Flatten()(x) out = Dense(512, activation="relu")(x) out1 = Dropout(0.5)(out) return out1 、、、
Transformer模块特征输出部分代码片段
、、、 for dim in mlp_units: x = layers.Dense(dim, activation="relu")(x) x = layers.Dropout(mlp_dropout)(x) output2 = layers.Dense(7, activation="softmax")(x) return out2 、、、
输出拼接与模型封装部分代码片段
、、、 def get_model(): inp = Input(input) out1 = Conv1D(inp) out2 = Transformer(inp) conc = concatenate([out1, out2]) x = Dense(512, activation='relu')(conc) x = Dropout(0.5)(x) outp = Dense(n_outputs, activation="softmax")(x) model = Model(inputs=inp ,outputs=outp) return model 、、、
报错触发位置
、、、 model = get_model() 、、、
报错根因
该错误本质是构建Keras函数式模型的计算图时,本该传入KerasTensor的位置混入了整数22,结合代码来看,问题集中在3个高概率点:
- 返回值拼写错误:Transformer模块循环内给输出赋值的变量名是
output2,但return语句返回的是out2,二者名称不一致。如果函数内部未定义out2,Python会自动查找全局作用域的同名变量,若全局存在值为22的out2变量,整数就会被混入计算图,直到Model实例化遍历计算节点时才触发报错。另外代码将最终分类Dense层写在for循环内部,会重复创建层对象,属于逻辑bug。 - 命名冲突:自定义卷积模块命名为
Conv1D,和Keras内置的tf.keras.layers.Conv1D层完全重名,如果存在通配符导入from tensorflow.keras.layers import *或导入顺序问题,调用Conv1D(inp)时实际触发的是Keras内置Conv1D层的初始化逻辑,参数错位后会把形状维度值22误传入计算图。此外输入形状变量命名为input,和Python内置input()函数重名,容易被意外覆盖为其他值。 - Input层传参不规范:直接将包含batch维度的形状元组作为位置参数传给
Input(),未明确指定参数名,极端情况下会触发参数解析错误,把形状中的维度值22识别为输入张量。
修复步骤
- 统一修改变量名避免冲突
- 将输入形状变量重命名为
input_shape,不要占用内置名称:input_shape = (None, 22, 1) - 将自定义Conv1D模块重命名为
conv1d_block,Transformer模块重命名为transformer_block,避免和Keras内置层重名。
- 将输入形状变量重命名为
- 修复Transformer模块的逻辑错误
对齐返回值变量名,将最终分类Dense层移到循环外部,避免重复创建层:、、、 for dim in mlp_units: x = layers.Dense(dim, activation="relu")(x) x = layers.Dropout(mlp_dropout)(x) # 输出层移到循环外,统一变量名为out2 out2 = layers.Dense(7, activation="softmax")(x) return out2 、、、 - 规范模型构建代码
明确Input层参数,调用自定义模块时使用新的命名,确认传入Model的参数都是KerasTensor:、、、 def get_model(): # 明确指定batch_shape参数,避免解析歧义 inp = Input(batch_shape=input_shape) out1 = conv1d_block(inp) out2 = transformer_block(inp) conc = concatenate([out1, out2]) x = Dense(512, activation='relu')(conc) x = Dropout(0.5)(x) outp = Dense(n_outputs, activation="softmax")(x) model = Model(inputs=inp, outputs=outp) return model 、、、 - 校验节点类型(可选排查手段)
若修改后仍报错,可在模型构建过程中逐行打印各节点类型,确认所有节点都是KerasTensor,快速定位混入非张量值的位置:print(type(inp)) # 正常输出应为<class 'keras.engine.keras_tensor.KerasTensor'>
内容的提问来源于stack exchange,提问作者NianTang Liu
相关产品推荐
相关产品推荐

