多输入多输出模型必须使用tf.keras.model而非sequential,因后者仅支持单输入单输出;需显式定义命名的input和output层,编译与训练时loss、metrics、数据均须按名称用字典匹配。

多输入多输出模型必须用 tf.keras.Model,不能用 Sequential
因为 Sequential 只支持单输入单输出的线性堆叠,遇到多个输入张量(比如图像 + 文本特征)或多个输出头(比如分类 + 回归),它会直接报错:ValueError: Layer model expects 1 input(s), but it received 2 input tensors。必须显式定义输入层、共享/分支结构、输出层,再用 tf.keras.Model 封装。
常见场景包括:图文联合预测(图像输入 + 标题文本输入 → 标签 + 置信度)、时序信号双任务(原始波形 + 统计特征 → 分类结果 + 异常分数)。
实操建议:
快速生成专业的 Python 脚本和应用代码。一键创建完整项目结构,支持CLI、API、爬虫、Bot、Django等多种项目类型,包含完整的项目结构、配置文件、依赖管理、测试、README和文档。
- 每个输入单独定义一个
tf.keras.Input,命名(如name="image_input")便于后续调试和保存时识别 - 输出层也需命名(
name="class_output"),否则训练时 loss 和 metrics 无法按名映射 - 不要在模型定义里调用
.fit()—— 那是编译后的事,先确保Model(inputs=[...], outputs=[...])能成功实例化
编译时 loss 和 metrics 必须按输出名传字典,不是列表
如果输出层叫 "class_output" 和 "reg_output",但编译时写成 model.compile(loss=["sparse_categorical_crossentropy", "mse"]),TensorFlow 会报 ValueError: Expected loss to be a dict。它需要明确知道哪个 loss 对应哪个输出。
实操建议:
- loss、metrics、loss_weights 都得用字典,key 是输出层的
name属性值 - 例如:
loss={"class_output": "sparse_categorical_crossentropy", "reg_output": "mse"} - 若某输出不需要 loss(比如只做中间特征提取),可在字典中省略该 key,但对应输出在训练数据中仍需提供占位值(如
None或全零张量) - 注意
loss_weights字典的 key 必须与输出名完全一致,大小写敏感
训练数据的 x 和 y 必须是列表或字典,顺序/键名要严格对齐
输入有两个 Input 层,但传入 .fit(x=...) 时给的是单个 NumPy 数组,就会触发 TypeError: Expected x to be a list or dict。同理,多个输出也必须结构匹配。
实操建议:
-
x可以是列表:[img_array, text_array](顺序必须和inputs=[input_a, input_b]一致) - 或字典:
{"image_input": img_array, "text_input": text_array}(key 必须等于 Input 的name) -
y同理:列表[label_array, score_array]或字典{"class_output": ..., "reg_output": ...} - 用字典方式更安全,尤其当模型后期增删输入/输出时不易错位
保存和加载模型要注意子模型结构是否完整
用 model.save("path") 默认保存为 SavedModel 格式,通常没问题;但如果手动拆解了子模型(比如把图像分支抽成独立 tf.keras.Model),再拼进主模型,加载时可能报 KeyError: 'image_branch' —— 因为子模型没被注册进主图的 trackable objects。
实操建议:
- 避免在主模型外定义可训练子模型后仅用函数调用方式复用(如
feat = image_branch(img)),而要用tf.keras.Model实例并作为层加入(self.image_branch = ImageBranchModel()) - 保存前执行
model(tf.nest.map_structure(lambda x: tf.zeros_like(x), sample_input))一次,确保所有子结构已 build - 加载后务必用
model.predict(sample_input)测试,别只看load_model不报错就认为成功
多输入多输出真正难的不是搭结构,而是数据管道和 loss 映射那几处细节——名字不一致、字典缺 key、输入顺序颠倒,都会让错误信息绕着弯指向无关位置。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










