凯拉斯:如何计算多标签分类的准确度?

2024-05-14 22:14:06 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在做有毒评论文本分类卡格尔挑战。共有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)

三个时期后的准确率为99.11%。

然而,99.11%的准确率比最好的Kaggle提交要高一点。这让我觉得我要么(可能两者都)过度拟合,要么误用了凯拉斯的准确性。

1)当我使用50%的数据作为验证分割并且只有3个时间段时,似乎有点难以过度拟合。

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')和真实值。你认为这就是发生的事吗?

谢谢你的帮助!


Tags: 模型文本addmodel评论trainactivationdense
2条回答

对于多标签分类,我认为使用sigmoid作为激活,使用binary_crossentropy作为丢失是正确的。

如果输出是稀疏多标签(即少数正标签,多数为负标签),则Kerasaccuracy度量将被正确预测的负标签溢出。如果我没记错的话,凯拉斯不会选择概率最高的标签。相反,对于二进制分类,阈值是50%。所以预测是[0, 0, 0, 0, 0, 1]。如果实际的标签是[0, 0, 0, 0, 0, 0],那么准确度是5/6。你可以通过建立一个模型来检验这个假设,这个模型总是预测负面标签,并观察其准确性。

如果确实是这样,您可以尝试不同的度量,例如top_k_categorical_accuracy

我能想到的另一个遥远的可能性是你的训练数据。这些标签是不是“泄露”给了x?只是一个疯狂的猜测。

您可以参考Keras Metrics documentation查看所有可用的度量(例如二进制精度)。您还可以创建自己的自定义度量(并确保它完全符合您的期望)。我想确定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)。

现在您可以参考Keras code on Github来查看它是如何计算的:

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

这证实了neurite所说的(即,如果预测值是[0, 0, 0, 0, 0, 1],而实际标签是[0, 0, 0, 0, 0, 0],那么准确度是5/6)。

相关问题 更多 >

    热门问题