多分类模型训练时标签形状不兼容与数据类型错误求助
Keras多分类模型报错原因分析与修复
错误根源拆解
输出层与标签维度不匹配
你设置的输出层是Dense(8, activation='softmax'),输出维度为(None,8),但标签经过独热编码后是7类(num_classes=7),维度为(None,7),两者形状不兼容,直接触发Shapes (None, 8) and (None, 7) are incompatible错误。数据类型冲突
TensorFlow计算categorical_crossentropy损失时默认使用float32张量,但你给独热编码标签指定了dtype='int64',类型不匹配导致Tensor conversion requested dtype float32 for Tensor with dtype int64错误。索引越界的本质
IndexError: index 7 is out of bounds for axis 1 with size 7是维度不匹配的衍生问题——模型输出的第8个神经元对应索引7,但标签只有7个维度(索引0-6),自然触发越界报错。
修复方案
1. 对齐输出层神经元数量与类别数
把输出层神经元数改成和类别数一致的7:
model.add(Dense(7, activation='softmax')) # 替换原Dense(8,...)
2. 统一标签数据类型为float32
独热编码时要么去掉dtype='int64'(默认输出float32),要么显式指定float32:
# 方式一:使用默认类型 Y_train = to_categorical(Y_train_encoded, num_classes=7) Y_test = to_categorical(Y_test_encoded, num_classes=7) # 方式二:显式指定float32 Y_train = to_categorical(Y_train_encoded, num_classes=7, dtype='float32') Y_test = to_categorical(Y_test_encoded, num_classes=7, dtype='float32')
3. 清理冗余预处理逻辑
代码里有两套标签预处理流程(# OR分隔),实际运行只能选一种,避免逻辑混乱:
- 若原始标签已是0-6的连续整数,直接用
to_categorical即可 - 若标签是字符串/非连续整数,先用
LabelEncoder转成0开始的连续整数,再做独热编码
修正后的完整代码
import pandas as pd from sklearn.model_selection import train_test_split from sklearn.preprocessing import StandardScaler, LabelEncoder from tensorflow.keras.models import Sequential from tensorflow.keras.layers import InputLayer, Dense from tensorflow.keras.optimizers import Adam from tensorflow.keras.utils import to_categorical from tensorflow.keras.metrics import CategoricalAccuracy, F1Score, AUC, Precision, Recall # 数据准备 features = df.iloc[:, :-1] labels = df.iloc[:, -1] X_train, X_test, Y_train, Y_test = train_test_split(features, labels, test_size=0.33, random_state=42, stratify=labels) # 特征标准化 scaler = StandardScaler() X_train = scaler.fit_transform(X_train) X_test = scaler.transform(X_test) # 标签预处理(LabelEncoder+独热编码) le = LabelEncoder() Y_train_encoded = le.fit_transform(Y_train.astype('int64')) Y_test_encoded = le.transform(Y_test.astype('int64')) Y_train = to_categorical(Y_train_encoded, num_classes=7, dtype='float32') Y_test = to_categorical(Y_test_encoded, num_classes=7, dtype='float32') # 模型构建 model = Sequential(name='forest') model.add(InputLayer(input_shape=(X_train.shape[1],))) model.add(Dense(64, activation='relu')) model.add(Dense(32, activation='relu')) model.add(Dense(7, activation='softmax')) # 匹配7类 # 模型编译 ls_optimizer = Adam(learning_rate=0.001) model.compile(optimizer=ls_optimizer, loss='categorical_crossentropy', metrics=[CategoricalAccuracy(name='accuracy'), F1Score(average='weighted', name='f1_score'), AUC(name='auc'), Precision(name='precision'), Recall(name='recall')]) # 训练与评估 history = model.fit(X_train, Y_train, epochs=100, batch_size=16, verbose=1) loss, accuracy, f1_score, auc, precision, recall = model.evaluate(X_test, Y_test, verbose=0)
内容的提问来源于stack exchange,提问作者Никита Зерекидзе
相关产品推荐
相关产品推荐

