我正在进行有毒评论文字分类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个时期后获得99.11%的准确度。
然而,99.11%的准确度比最好的Kaggle提交要好一点。这让我觉得我(或许两者)a)过度拟合或b)滥用Keras的准确性。
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('淫秽')的类与真值进行比较。你认为这是发生了什么吗?
感谢您提供的任何帮助!
答案 0 :(得分:4)
对于多标签分类,我认为使用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。
我能想到的另一个遥远的可能性是你的训练数据。标签是否以某种方式“泄露”到x?只是一个疯狂的猜测。
答案 1 :(得分:1)
您可以参考Keras Metrics documentation来查看所有可用指标(例如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
)。
现在,您可以参考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
)。