TensorFlow医学二输入ML模型数据基数模糊错误求助
问题:TensorFlow二输入模型维度不匹配及准确率低下问题
触发异常
ValueError: Data cardinality is ambiguous:
x sizes: 1, 1
y sizes: 23
Make sure all arrays contain the same number of samples.
背景说明
用TensorFlow构建二输入模型,基于MRI光谱的**lactate(乳酸)和lipids(脂质)**指标预测高等级脑肿瘤概率,运行时触发上述维度异常,调整数据塑形后模型准确率仍极差。
相关代码
import tensorflow as tf import numpy as np # 定义lipidos和lactato输入层 lipidos_input = tf.keras.layers.Input(shape=(23,), name="lipidos_input") lactato_input = tf.keras.layers.Input(shape=(23,), name="lactato_input") # lipidos分支隐藏层 lipidos_hidden1 = tf.keras.layers.Dense(10, activation='relu')(lipidos_input) lipidos_hidden2 = tf.keras.layers.Dense(10, activation='relu')(lipidos_hidden1) # lactato分支隐藏层 lactato_hidden1 = tf.keras.layers.Dense(10, activation='relu')(lactato_input) lactato_hidden2 = tf.keras.layers.Dense(10, activation='relu')(lactato_hidden1) # 合并两个分支输出 merged = tf.keras.layers.concatenate([lipidos_hidden2, lactato_hidden2]) # 额外隐藏层 hidden_layer = tf.keras.layers.Dense(10, activation='relu')(merged) # 二分类输出层(sigmoid激活) output_layer = tf.keras.layers.Dense(1, activation='sigmoid', name="output")(hidden_layer) # 创建模型 model = tf.keras.models.Model(inputs=[lipidos_input, lactato_input], outputs=output_layer) # 编译模型 model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy']) # 输入数据 lipidos_data = np.array([ 0.016, 0.03, 0.05, 0.0008, 0.009, 0.01, 0.015, 0.15, 0.004, 0.016, 0.09, 0.003, 0.001, 0.003, 0.012, 0.01, 0.011, 0.01, 0.003, 0.02, 0.03, 0.001, 0 ], dtype=float) lactato_data = np.array([ 0.015, 0.021, 0.043, 0.0014, 0.011, 0.01, 0.015, 0.03, 0.02, 0.012, 0.075, 0.0025, 0.005, 0.01, 0.028, 0.011, 0.11, 0.032, 0.0045, 0.006, 0.005, 0, 0.002 ], dtype=float) alto_grado_data = np.array([ 1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,0,1,1,0,0 ], dtype=int) # 将输入数据转为2D数组 lipidos_data = lipidos_data.reshape(-1, 23) lactato_data = lactato_data.reshape(-1, 23) # 训练模型 model.fit([lipidos_data, lactato_data], alto_grado_data, epochs=100, batch_size=8) # 预测示例 lipidos_value = np.array([[0.015]], dtype=float) lactato_value = np.array([[0.015]], dtype=float) prediction = model.predict([lipidos_value, lactato_value]) predicted_alto_grado = round(prediction[0][0]) print("Predicted alto_grado:", predicted_alto_grado)
解决方案
1. 修复数据维度不匹配
当前核心错误是样本数不匹配:
- 你把
lipidos_data和lactato_datareshape成了(1,23)(1个样本,23个特征),但标签alto_grado_data是23个样本,两者数量必须一致。 - 正确逻辑是:23个样本,每个样本包含1个lipid特征和1个lactate特征。
修正代码:
# 调整输入数据维度:23个样本,每个样本1个特征 lipidos_data = lipidos_data.reshape(-1, 1) lactato_data = lactato_data.reshape(-1, 1) # 同步调整输入层shape为(1,) lipidos_input = tf.keras.layers.Input(shape=(1,), name="lipidos_input") lactato_input = tf.keras.layers.Input(shape=(1,), name="lactato_input")
2. 解决类别不平衡问题
标签数据中18个正样本、5个负样本,严重的类别不平衡会导致模型偏向预测多数类,看似准确率高但泛化能力差:
- 给少数类设置更高权重:
class_weight = {0: 18/5, 1: 1} # 负样本权重是正样本的3.6倍 model.fit([lipidos_data, lactato_data], alto_grado_data, epochs=100, batch_size=8, class_weight=class_weight)
- 改用更适合不平衡数据的评估指标:
from tensorflow.keras.metrics import AUC, Precision, Recall model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy', AUC(name='auc'), Precision(), Recall()])
3. 优化模型与训练流程
样本量仅23个,原模型结构过复杂易过拟合:
- 简化模型结构:
lipidos_input = tf.keras.layers.Input(shape=(1,), name="lipidos_input") lactato_input = tf.keras.layers.Input(shape=(1,), name="lactato_input") merged = tf.keras.layers.concatenate([lipidos_input, lactato_input]) hidden = tf.keras.layers.Dense(4, activation='relu')(merged) output = tf.keras.layers.Dense(1, activation='sigmoid')(hidden) model = tf.keras.models.Model(inputs=[lipidos_input, lactato_input], outputs=output)
- 加入正则化防止过拟合:
from tensorflow.keras.layers import Dropout from tensorflow.keras.regularizers import l2 hidden = tf.keras.layers.Dense(4, activation='relu', kernel_regularizer=l2(0.01))(merged) hidden = Dropout(0.2)(hidden)
- 划分训练/验证集监控泛化能力:
from sklearn.model_selection import train_test_split X_lipid_train, X_lipid_val, X_lactate_train, X_lactate_val, y_train, y_val = train_test_split( lipidos_data, lactato_data, alto_grado_data, test_size=0.2, random_state=42, stratify=alto_grado_data ) history = model.fit( [X_lipid_train, X_lactate_train], y_train, epochs=100, batch_size=4, validation_data=([X_lipid_val, X_lactate_val], y_val), class_weight=class_weight )
4. 修正预测输入
当前预测输入的(1,1)维度符合修正后的输入层要求,无需调整,但要确保输入值对应单个样本的特征。
内容的提问来源于stack exchange,提问作者FFalco
相关产品推荐
相关产品推荐

