我在多标签分类中使用了sigmoid和binary_crossentropy。有一个非常相似的问题在这里提问。有人建议使用以下自定义指标:
from keras import backend as Kdef full_multi_label_metric(y_true, y_pred): comp = K.equal(y_true, K.round(y_pred)) return K.cast(K.all(comp, axis=-1), K.floatx())
但是我不想使用all(),因为对于一个真实标签为[1, 0, 0, 1, 1]且预测标签为[0, 0, 0, 1, 1]的单个样本,我不认为预测准确率为零(因为最后四个类别的标签预测正确)。
这是我的模型:
# 预期输入数据形状: (batch_size, timesteps, data_dim)model = Sequential()model.add(Masking(mask_value=-9999, input_shape=(197, 203)))model.add(LSTM(512, return_sequences=True))model.add(Dense(20, activation='sigmoid')) model.compile(loss='binary_crossentropy', optimizer=SGD(lr=1e-3, decay=1e-4, momentum=0.9, nesterov=True), metrics = ['accuracy'])print(model.summary())
这是一个样本的y_pred:
pred = model.predict(X_test)y_pred = pred[0,196,:]y_predarray([2.6081860e-01, 9.9079555e-01, 1.4816311e-01, 8.6009043e-01, 2.6759505e-04, 3.0792636e-01, 2.6738405e-02, 8.5339689e-01, 5.1105350e-02, 1.5427300e-01, 6.7039116e-05, 1.7909735e-02, 6.4140558e-04, 3.5133284e-01, 5.3054303e-02, 1.2765944e-01, 2.9298663e-04, 6.3041472e-01, 5.8620870e-03, 5.9656668e-01], dtype=float32)
这是一个样本的y_true:
y_true = Y_test[0,0,:]y_truearray([1., 0., 0., 0., 0., 0., 0., 0., 0., 1., 0., 0., 0., 1., 1., 0., 0., 0., 0., 1.])
我的问题是:如何设置Keras的自定义指标函数,以便y_pred中的每个元素与y_true中的每个元素进行比较,然后在训练过程中给出准确性测量?我希望在metrics = [X])
中使用这个指标?
回答:
除非我误解了,否则默认的binary_crossentropy指标/损失已经满足你的需求。以你的例子为例
import tensorflow as tffrom tensorflow import kerasy_true = tf.constant([[1, 0, 0, 1, 1]], dtype=tf.int32)y_pred = tf.constant([[0.6, 0, 0, 1, 1]], dtype=tf.float32)m = keras.metrics.binary_crossentropy(y_true, y_pred)m.numpy()
输出是[-log(0.6) / 5]。
即,批次的指标/损失考虑了模型20个输出的每个损失。我假设这些代表时间步长。
作为指标,更常见的是使用binary_accuracy。例如:
y_true = tf.constant([[1, 0, 0, 1, 1]], dtype=tf.int32)y_pred = tf.constant([[0.1, 0, 0, 1, 1]], dtype=tf.float32)keras.metrics.binary_accuracy(tf.cast(y_true, tf.float32), y_pred)
可以通过ROC指标(https://www.tensorflow.org/api_docs/python/tf/keras/metrics/AUC)更好地了解模型的性能,该指标在不同阈值下测量曲线,解释见https://towardsdatascience.com/understanding-auc-roc-curve-68b2303cc9c5。个人而言,我倾向于在训练过程中使用准确性指标,并在模型训练完成后查看精确度/召回率曲线,以检查模型是否按预期运行并选择预测阈值。