我正在使用以下代码在 keras 中为 NLP 任务训练一个简单的模型。对于训练、测试和验证集,变量名称是不言自明的。该数据集有 19 个类,因此网络的最后一层有 19 个输出。标签也是 one-hot 编码的。
nb_classes = 19 model1 = Sequential() model1.add(Embedding(nb_words, EMBEDDING_DIM, weights=[embedding_matrix], input_length=MAX_SEQUENCE_LENGTH, trainable=False)) model1.add(LSTM(num_lstm, dropout=rate_drop_lstm, recurrent_dropout=rate_drop_lstm)) model1.add(Dropout(rate_drop_dense)) model1.add(BatchNormalization()) model1.add(Dense(num_dense, activation=act)) model1.add(Dropout(rate_drop_dense)) model1.add(BatchNormalization()) model1.add(Dense(nb_classes, activation = 'sigmoid')) model1.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy']) #One hot encode all labels ytrain_enc = np_utils.to_categorical(train_labels) yval_enc = np_utils.to_categorical(val_labels) ytestenc = np_utils.to_categorical(test_labels) model1.fit(train_data, ytrain_enc, validation_data=(val_data, yval_enc), epochs=200, batch_size=384, shuffle=True, verbose=1)
在第一个时代之后,这给了我这些输出。
Epoch 1/200 216632/216632 [==============================] - 2442s - loss: 0.1427 - acc: 0.9443 - val_loss: 0.0526 - val_acc: 0.9826
然后我在测试数据集上评估我的模型,这也表明我的准确度在 0.98 左右。
model1.evaluate(test_data, y = ytestenc, batch_size=384, verbose=1)
但是,标签是一次性编码的,所以我需要类的预测向量,以便生成混淆矩阵等。所以我使用,
PREDICTED_CLASSES = model1.predict_classes(test_data, batch_size=384, verbose=1) temp = sum(test_labels == PREDICTED_CLASSES) temp/len(test_labels) 0.83
这表明总预测类别准确率为 83%,但准确率为model1.evaluate98%!我在这里做错了什么?我的损失函数适用于分类类标签吗?我sigmoid为预测层选择的激活函数可以吗?还是keras评估模型的方式有所不同?请就可能出现的问题提出建议。这是我第一次尝试制作深度模型,所以我不太了解这里出了什么问题。
model1.evaluate
sigmoid
我发现了问题。metrics=['accuracy']根据成本函数自动计算准确度。因此使用binary_crossentropy显示二进制精度,而不是分类精度。使用categorical_crossentropy自动切换到分类精度,现在它与使用手动计算相同model1.predict()。Yu-Yang 指出了多类问题的成本函数和激活函数是正确的。
metrics=['accuracy']
binary_crossentropy
categorical_crossentropy
model1.predict()
PS:一个可以通过使用获得分类和二进制精度metrics=['binary_accuracy', 'categorical_accuracy']
metrics=['binary_accuracy', 'categorical_accuracy']