我培训文本分类模型,其中输入数据包含4096个术语频率 - 逆文档频率。
我的输出是416种可能的类别。每个数据都有3个类别,因此有41个零(一个热编码)数组中有3个数据
我的模型看起来像这样:
DataTable
当我用myBindingSource.DataSource = myDataTable
myDataGridView.DataSource = myBindingSource
myBindingSource.Filter = $"SomeColumn LIKE '%{myTextBox.Text}%'"
损失进行训练时,它在一个时期之后损失了0.185并且准确度为96%。在5个时期之后,损失为0.037,准确度为99.3%。我想这是错的,因为我的标签中有很多0,它正确分类。
当我以model = Sequential()
model.add(Dense(2048, activation="relu", input_dim=X.shape[1]))
model.add(Dense(512, activation="relu"))
model.add(Dense(416, activation="sigmoid"))
损失进行训练时,它在前几个时期内损失了15.0并且准确度低于5%,然后它在5.0的损失中停留并且准确度为12%在几个(超过50个)时代之后。
哪一个适合我的情况(大型单热编码多个1)?这些分数告诉我什么?
编辑:这些是binary_crossentropy
声明:
categorical_crossentropy
和
model.compile()
答案 0 :(得分:5)
简而言之:正如您已经猜到的那样,当您使用loss='binary_crossentropy'
时报告的(高)准确度不是正确的。对于您的问题,建议的损失为categorical_crossentropy
。
长期:
这种行为的根本原因是一个相当微妙的&未记录的问题,Keras实际上猜测使用哪种准确度,取决于您选择的损失函数,当您在模型编译中简单地包含metrics=['accuracy']
时,就像您所拥有的那样。换句话说,当你的第一个编译选项
model.compile(loss='categorical_crossentropy',
optimizer=keras.optimizers.Adam(),
metrics=['accuracy']
是有效的,你的第二个:
model.compile(loss='binary_crossentropy',
optimizer=keras.optimizers.Adam(),
metrics=['accuracy'])
不会产生你所期望的,但原因不是使用二元交叉熵(至少在原理上,它是绝对有效的损失函数)。
为什么?如果您选中metrics source code,则Keras不会定义单个精度指标,而是定义几个不同的指标,其中包括binary_accuracy
和categorical_accuracy
。 under the hood会发生什么,因为您选择了loss='binary_crossentropy'
并且未指定特定的准确度指标,因此Keras(错误地......)推断您对{ {1}},这就是它返回的内容 - 实际上你对binary_accuracy
感兴趣。
让我们使用Keras中的MNIST CNN example验证是否属于这种情况,并进行了以下修改:
categorical_accuracy
可以说,使用您自己的数据验证上述行为应该很简单。
只是为了讨论的完整性,无论出于什么原因,你坚持使用二进制交叉熵作为你的损失函数(正如我所说,至少在原则上没有任何问题),同时仍然得到分类当前问题所需的准确性,您应该在模型编译中明确询问model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy']) # WRONG way
model.fit(x_train, y_train,
batch_size=batch_size,
epochs=2, # only 2 epochs, for demonstration purposes
verbose=1,
validation_data=(x_test, y_test))
# Keras reported accuracy:
score = model.evaluate(x_test, y_test, verbose=0)
score[1]
# 0.9975801164627075
# Actual accuracy calculated manually:
import numpy as np
y_pred = model.predict(x_test)
acc = sum([np.argmax(y_test[i])==np.argmax(y_pred[i]) for i in range(10000)])/10000
acc
# 0.98780000000000001
score[1]==acc
# False
,如下所示:
categorical_accuracy
在MNIST示例中,在我上面显示的训练,评分和预测测试集之后,现在两个指标是相同的,应该是:
from keras.metrics import categorical_accuracy
model.compile(loss='binary_crossentropy', optimizer='adam', metrics=[categorical_accuracy])
系统设置:
# Keras reported accuracy:
score = model.evaluate(x_test, y_test, verbose=0)
score[1]
# 0.98580000000000001
# Actual accuracy calculated manually:
y_pred = model.predict(x_test)
acc = sum([np.argmax(y_test[i])==np.argmax(y_pred[i]) for i in range(10000)])/10000
acc
# 0.98580000000000001
score[1]==acc
# True