Keras拼接模型训练报错:数据基数不明确的解决方案咨询
问题根源
你的模型设计要求每个输入样本必须同时具备diags和labs特征(拼接层需要将两个子模型的输出按样本一一对应拼接),但当前两个输入数据集的样本数完全不匹配,且训练时传入了两个标签数组,和模型单输出的结构矛盾,导致Keras无法对齐样本,触发基数不匹配错误。
替代方案(无需补零)
方案1:对齐重叠样本
如果两个数据集存在重叠样本(比如共享患者ID),直接筛选出同时拥有diags和labs数据的样本,让两个输入的样本数统一。例如用pandas按ID合并数据,只保留非空行,之后训练代码修改为:
# 假设已完成数据对齐,得到样本数相同的x_diags_aligned、x_labs_aligned、y_aligned full_model.fit([x_diags_aligned, x_labs_aligned], y_aligned, batch_size=64, epochs=5)
方案2:多任务独立预测(放弃拼接)
如果需求是让两个子模型分别学习各自输入的特征、独立输出预测结果,可将模型改为多输出结构,这样就能接受不同样本数的输入,分别训练两个任务:
# 诊断数据分支 input_diags = tf.keras.layers.Input(shape=(1032,)) dense_1_diags = tf.keras.layers.Dense(16, activation='elu')(input_diags) dense_2_diags = tf.keras.layers.Dense(4, activation='elu')(dense_1_diags) output_diags = tf.keras.layers.Dense(1, activation='elu')(dense_2_diags) # 实验室数据分支 input_labs = tf.keras.layers.Input(shape=(230,)) dense_1_labs = tf.keras.layers.Dense(16, activation='elu')(input_labs) dense_2_labs = tf.keras.layers.Dense(4, activation='elu')(dense_1_labs) output_labs = tf.keras.layers.Dense(1, activation='elu')(dense_2_labs) # 多输出模型定义 full_model = tf.keras.Model(inputs=[input_diags, input_labs], outputs=[output_diags, output_labs]) # 编译(可给两个任务设置不同损失权重) full_model.compile( loss=[tf.keras.losses.BinaryCrossentropy(from_logits=False), tf.keras.losses.BinaryCrossentropy(from_logits=False)], optimizer=tf.keras.optimizers.Adam(learning_rate=0.001), metrics=[[tf.keras.metrics.AUC(), tf.keras.metrics.Precision(), tf.keras.metrics.Recall()], [tf.keras.metrics.AUC(), tf.keras.metrics.Precision(), tf.keras.metrics.Recall()]] ) # 训练时传入对应输入和标签 full_model.fit([x_train_diags, x_train_labs], [y_train_diags, y_train_labs], batch_size=64, epochs=5)
方案3:统计特征填充缺失值
如果样本属于同一批对象,但部分只有diags、部分只有labs,用特征均值/中位数替代补零,合并成完整数据集后训练:
import numpy as np # 计算诊断数据特征的均值,填充实验室样本的诊断特征 diags_mean = x_train_diags.mean(axis=0) x_labs_with_diags = np.hstack([np.tile(diags_mean, (x_train_labs.shape[0], 1)), x_train_labs]) # 计算实验室数据特征的均值,填充诊断样本的实验室特征 labs_mean = x_train_labs.mean(axis=0) x_diags_with_labs = np.hstack([x_train_diags, np.tile(labs_mean, (x_train_diags.shape[0], 1))]) # 合并数据集和标签 x_combined = np.vstack([x_diags_with_labs, x_labs_with_diags]) y_combined = np.vstack([y_train_diags, y_train_labs]) # 单输入模型训练 input_combined = tf.keras.layers.Input(shape=(1032+230,)) dense1 = tf.keras.layers.Dense(16, activation='elu')(input_combined) dense2 = tf.keras.layers.Dense(4, activation='elu')(dense1) output = tf.keras.layers.Dense(1, activation='elu')(dense2) model = tf.keras.Model(inputs=input_combined, outputs=output) model.compile( loss=tf.keras.losses.BinaryCrossentropy(from_logits=False), optimizer=tf.keras.optimizers.Adam(learning_rate=0.001), metrics=[tf.keras.metrics.AUC(), tf.keras.metrics.Precision(), tf.keras.metrics.Recall()] ) model.fit(x_combined, y_combined, batch_size=64, epochs=5)
内容的提问来源于stack exchange,提问作者Foxtrot_Romeo
相关产品推荐
相关产品推荐

