Keras:如何计算多标签分类的准确性?

22

我正在进行Toxic Comment Text Classification Kaggle挑战。共有6个类别:['threat', 'severe_toxic', 'obscene', 'insult', 'identity_hate', 'toxic']。一条评论可能属于多个类别,因此这是一个多标签分类问题。

我使用Keras构建了一个基本的神经网络,具体如下:

model = Sequential()
model.add(Embedding(10000, 128, input_length=250))
model.add(Flatten())
model.add(Dense(100, activation='relu'))
model.add(Dense(len(classes), activation='sigmoid'))
model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])

我运行了这行代码:

model.fit(X_train, train_y, validation_split=0.5, epochs=3)

在 3 个 epoch 后,准确率达到了 99.11%。

然而,99.11% 的准确率比最佳 Kaggle 提交的成绩高得多。这让我认为我可能出现了过拟合或误用 Keras 的准确度。

1)当我将数据的 50% 作为验证集并仅运行 3 个 epoch 时,出现过拟合似乎有点困难。

2)这里的准确率是否只是模型正确预测每个类别的百分比?

因此,如果我的输出是 [0, 0, 0, 0, 0, 1],而正确的输出是 [0, 0, 0, 0, 0, 0],则我的准确率将为 5/6

经过一番思考,我认为这里的accuracy指标只是查看模型预测的具有最高置信度的类别,并与真实值进行比较。

因此,如果我的模型输出为[0, 0, 0.9, 0, 0, 0],它将会将索引为 2('obscene')的类别与真实值进行比较。您认为这就是发生的情况吗?

感谢您提供的任何帮助!

2个回答

19
对于多标签分类,我认为使用 sigmoid 作为激活函数和 binary_crossentropy 作为损失函数是正确的。
如果输出是稀疏的多标签,也就是有少量正标签和大多数负标签,那么Keras中的accuracy指标将会被正确预测的负标签所抬升。如果我没记错的话,Keras不会选择具有最高概率的标签。对于二元分类,阈值为50%。因此,预测结果将是[0, 0, 0, 0, 0, 1]。如果实际标签为[0,0,0,0,0,0],则准确度为5/6。您可以通过创建一个总是预测负标签的模型并查看准确性来测试这个假设。
如果确实如此,您可以尝试使用其他指标,例如top_k_categorical_accuracy
我能想到的另一个可能性是您的训练数据。标签y是否以某种方式“泄漏”到x中?只是一个猜想。

这里为多标签问题定义了一个weighted_binary_crossentropy损失函数,其中存在大量负面预测:https://stats.stackexchange.com/a/313922/198729。然而我也在寻找一个`weighted_binary_accuracy`。 - CMCDragonkai
此外,在这种情况下,“top_k_categorical_accuracy”似乎不起作用,因为如果真实值是多热编码的,那么“top_k”是什么? - CMCDragonkai

5

您可以参考Keras指标文档,查看所有可用的指标(例如binary_accuracy)。您还可以创建自己的自定义指标(并确保它完全符合您的预期)。我想确保neurite对准确性如何计算是正确的,所以我做了以下操作(注意:activation="sigmoid"):

from keras.metrics import binary_accuracy
def custom_acc(y_true, y_pred):
    return binary_accuracy(y_true, y_pred)

# ...

model.compile(loss="binary_crossentropy", optimizer=optimizer, metrics=[
    "accuracy",
    "binary_accuracy",
    "categorical_accuracy",
    "sparse_categorical_accuracy",
    custom_acc
])

运行训练时,您将看到 custom_acc 始终等于 binary_accuracy(因此等于 custom_acc)。

现在,您可以参考 Github 上的 Keras 代码 以查看其计算方式:

K.mean(K.equal(y_true, K.round(y_pred)), axis=-1)

这证实了神经元所说的(即如果预测是[0, 0, 0, 0, 0, 1],而实际标签是[0, 0, 0, 0, 0, 0],则准确度将为5/6)。


2
我添加了所有可能的指标来确定使用哪一个并比较结果。这只是实验性的。 - smichaud

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接