TensorFlow训练CNN时报(None,1)与(None,150)形状不兼容错误求助
报错原因与解决方案
核心问题
你使用的损失函数categorical_crossentropy要求输入标签为one-hot编码后shape为(样本数, 150)的张量,但当前你的y_train、y_val均为字符串格式的宝可梦类别名称,shape为(样本数,),即使你尝试过One-Hot编码,也大概率是没有先完成类名字符串到整数索引的映射步骤,导致编码失效。
两种可行修复方案
方案1:保持损失函数不变,正确完成标签编码
提前将字符串类名映射为整数,再转为One-Hot格式,对应代码修改如下:
from sklearn.preprocessing import LabelEncoder from tensorflow.keras.utils import to_categorical # 1. 字符串类名转0-149的整数索引 label_encoder = LabelEncoder() img_labels_int = label_encoder.fit_transform(img_labels) # 2. 拆分数据集时使用整数标签 X_train, X_val, y_train, y_val=train_test_split(img_data, img_labels_int, test_size=0.3, random_state=42,shuffle=True) # 3. 整数标签转One-Hot编码,匹配损失函数要求 y_train = to_categorical(y_train, num_classes=150) y_val = to_categorical(y_val, num_classes=150)
后续训练代码无需修改即可正常运行。
方案2:不修改标签编码,更换适配整数标签的损失函数
无需做One-Hot编码,仅需要先把字符串类名转成整数索引,再把模型编译环节的损失函数替换为sparse_categorical_crossentropy即可,该损失函数原生支持整数格式的标签,代码更精简:
# 先完成字符串类名到整数索引的转换,同方案1第一步 from sklearn.preprocessing import LabelEncoder label_encoder = LabelEncoder() img_labels_int = label_encoder.fit_transform(img_labels) X_train, X_val, y_train, y_val=train_test_split(img_data, img_labels_int, test_size=0.3, random_state=42,shuffle=True) # 修改损失函数 model.compile(loss='sparse_categorical_crossentropy', optimizer=opt, metrics=['accuracy'])
内容的提问来源于stack exchange,提问作者liatkatz
相关产品推荐
相关产品推荐

