使用Keras LSTM进行768维特征向量多分类时遇形状匹配错误求助
解决Keras LSTM多分类中的形状不匹配错误
你的错误核心在于损失函数和标签格式不匹配,另外还有一个容易忽略的问题:你的输入是768维连续特征向量,用Embedding层并不合适,这也会影响模型的输入处理。下面一步步帮你修正:
1. 损失函数与标签的匹配问题
你当前使用的是sparse_categorical_crossentropy损失函数,这个函数要求标签是整数形式的单值(比如每个样本的标签是0-9中的一个数字,形状为(样本数, 1)),但从错误信息看,你的y_train是one-hot编码的10维向量(形状(61171, 10)),两者不匹配。
解决方法有两种,二选一即可:
- 如果你的标签已经是one-hot编码,把损失函数改成
categorical_crossentropy - 如果想保留
sparse_categorical_crossentropy,需要把one-hot编码的标签转换为整数形式(可以用np.argmax(y_train, axis=1)实现)
推荐第一种,因为你的数据已经是one-hot格式,直接改损失函数更方便。
2. 替换Embedding层以适配连续特征
Embedding层是用来处理离散的索引序列(比如自然语言中的词索引),而你的输入是768维的连续特征向量,应该调整输入形状后直接接入LSTM——因为LSTM要求输入是3D张量:(batch_size, timesteps, features)。
你的768维特征可以看作是768个时间步,每个时间步1个特征,所以需要把输入从(样本数,768)转换成(样本数,768,1),再接入LSTM层。
修改后的完整代码
def do_experiment(train_file, validation_file, test_file, experiment_number, optimizer_name): def scheduler(epoch): if epoch % 4 == 0 and epoch: K.set_value(model.optimizer.lr, K.get_value(model.optimizer.lr)*0.9) print(K.get_value(model.optimizer.lr)) return K.get_value(model.optimizer.lr) change_lr = LearningRateScheduler(scheduler) early_stopper = EarlyStopping(min_delta=0.001, patience=15) csv_logger = CSVLogger('lstm.csv') weights_file="trained_model/" + str(experiment_number) + "-weights.h5" model_checkpoint= ModelCheckpoint(weights_file, monitor="val_loss", save_best_only=True, save_weights_only=True, mode='auto') x_train, y_train, groundtruth_train= du.loaddata(train_file, experiment_number) x_validation, y_validation, groundtruth_validation= du.loaddata(validation_file, experiment_number) # 调整输入形状,适配LSTM的3D输入要求 x_train = x_train.reshape(x_train.shape[0], 768, 1) x_validation = x_validation.reshape(x_validation.shape[0], 768, 1) batch_size = 32 nb_classes = 10 nb_epoch = 100 model = Sequential() # 去掉Embedding层,直接接入LSTM并指定输入形状 model.add(LSTM(100, dropout=0.2, recurrent_dropout=0.2, input_shape=(768, 1))) model.add(Dense(10, activation='softmax')) # 替换损失函数,适配one-hot标签格式 model.compile(loss='categorical_crossentropy', optimizer=optimizer_name, metrics=['accuracy']) model.fit(x_train, y_train, batch_size=batch_size, epochs=nb_epoch, validation_data=(x_validation, y_validation), shuffle=True, callbacks=[change_lr, early_stopper, csv_logger, model_checkpoint])
关键修改点说明
- 输入形状调整:通过
reshape把2D的特征向量转换成3D张量,满足LSTM对输入维度的要求 - 移除Embedding层:换成直接指定
input_shape=(768,1)的LSTM层,适配连续特征输入 - 损失函数替换:用
categorical_crossentropy替代sparse_categorical_crossentropy,匹配one-hot编码的标签格式
这样修改后,应该就能解决你遇到的形状不匹配错误,顺利完成768维特征向量的多分类任务了。
内容的提问来源于stack exchange,提问作者mad
相关产品推荐
相关产品推荐

