You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

TensorFlow训练报错:Shapes (None,24)与(None,2)不兼容求助

问题根源

报错ValueError: Shapes (None, 24) and (None, 2) are incompatible的核心原因是标签编码不匹配:

  • 原数据中O对应标签14,X对应标签23,使用np_utils.to_categorical()时,会根据标签最大值(23)生成24维的one-hot向量
  • 但模型最后一层仅输出2维,两者形状无法匹配
修复步骤

1. 重新编码标签为0/1

把原标签14(O)替换为0,23(X)替换为1,确保one-hot编码后维度为2:

# 替换原标签编码
y = new_dataset['label'].replace({14:0, 23:1})

2. 匹配损失函数与输出层激活函数

根据二分类场景,有两种可选方案:

方案一:使用categorical_crossentropy(需one-hot标签)

  • 输出层激活函数用softmax
  • 标签保持one-hot编码
# 标签one-hot编码
y_train = np_utils.to_categorical(y_train)
y_test = np_utils.to_categorical(y_test)

# 模型最后一层调整
cls.add(tf.keras.layers.Dense(2, activation='softmax'))

# 编译模型
cls.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])

方案二:使用binary_crossentropy(无需one-hot标签)

  • 输出层激活函数用sigmoid
  • 标签保持原始0/1数值,不用one-hot编码
# 注释掉one-hot编码步骤
# y_train = np_utils.to_categorical(y_train)
# y_test = np_utils.to_categorical(y_test)

# 模型最后一层保持sigmoid(注意输出维度改为1)
cls.add(tf.keras.layers.Dense(1, activation='sigmoid'))

# 编译模型
cls.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])

3. 清理冗余代码

原代码中X_shuffle = shuffle(X)未实际使用,可删除;dataset_alphabets变量若仅用于查看,不影响训练可保留或删除。

完整修正代码
import os
import cv2
import numpy as np 
import pandas as pd 
import matplotlib.pyplot as plt
from sklearn.preprocessing import MinMaxScaler
import tensorflow as tf
from tensorflow.python.keras.models import Sequential
from tensorflow.python.keras.layers import Dense, Dropout, Flatten, Conv2D, MaxPooling2D
from tensorflow.python.keras.utils import np_utils
from sklearn.model_selection import train_test_split
from sklearn.metrics import confusion_matrix
from sklearn.utils import shuffle

dataset = pd.read_csv("./A_Z Handwritten Data.csv").astype('float32')
dataset_reduced_o = dataset[139811:197636]
dataset_reduced_x = dataset[349243:355515]
new_dataset = pd.concat([dataset_reduced_o, dataset_reduced_x])
new_dataset = new_dataset.reset_index(drop=True)
new_dataset.rename(columns={'0':'label'}, inplace=True)

# 拆分特征与标签,重新编码标签为0/1
X = new_dataset.drop('label',axis = 1)
y = new_dataset['label'].replace({14:0, 23:1})

# 打乱数据(直接对X和y一起打乱)
X, y = shuffle(X, y)

# 拆分训练集测试集
X_train, X_test, y_train, y_test = train_test_split(X,y)

# 数据标准化
standard_scaler = MinMaxScaler()
standard_scaler.fit(X_train)
X_train = standard_scaler.transform(X_train)
X_test = standard_scaler.transform(X_test)

# 调整输入形状为CNN要求的格式
X_train = X_train.reshape(X_train.shape[0], 28, 28, 1).astype('float32')
X_test = X_test.reshape(X_test.shape[0], 28, 28, 1).astype('float32')

# 方案一:使用categorical_crossentropy
y_train = np_utils.to_categorical(y_train)
y_test = np_utils.to_categorical(y_test)

# 构建模型
cls = tf.keras.models.Sequential()
cls.add(tf.keras.layers.Conv2D(32, (5, 5), input_shape=(28, 28, 1), activation='relu'))
cls.add(tf.keras.layers.MaxPooling2D(pool_size=(2, 2)))
cls.add(tf.keras.layers.Dropout(0.3))
cls.add(tf.keras.layers.Flatten())
cls.add(tf.keras.layers.Dense(128, activation='relu'))
cls.add(tf.keras.layers.Dense(2, activation='softmax'))

# 编译并训练
cls.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
history = cls.fit(X_train, y_train, epochs=3, validation_split=0.1)

# 评估模型
scores = cls.evaluate(X_test,y_test)
print("CNN Score:",scores[1])
cls.save('handwritten.model')

内容的提问来源于stack exchange,提问作者doozy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 17:33:10