Keras自定义目标函数需要张量评估。

4

我希望创建一个自定义的目标函数来训练Keras深度神经网络。我正在研究不平衡数据的分类,并且在scikit-learn中经常使用F1分数。因此,我想到了将F1指标反转(1-F1分数)以将其作为Keras的损失函数/目标,以便在训练过程中最小化:

(from sklearn.metric import f1_score)

def F1Loss(y_true, y_pred):

    return 1. - f1_score(y_true, y_pred)

然而,scikit-learn中的f1_score方法需要使用numpy数组或列表来计算F1分数。我发现需要使用.eval()将张量Tensor转换为其numpy数组表示形式,这需要一个TensorFlow会话来执行此任务。
我不知道Keras使用的会话对象是什么。我尝试使用下面的代码,假定Keras后端在某个地方定义了其自己的会话对象,但这也没有起作用。
from keras import backend as K

K.eval(y_true)

诚然,由于我目前并不真正理解Keras或Tensorflow的更深层次工作原理,所以这只是一次瞎猜。

我的问题是:如何将y_truey_pred张量评估为它们的numpy数组对应项?

2个回答

2
您的问题是在Theano中实现不连续目标的经典问题。由于以下两个原因,这是不可能的:
  1. F1得分是不连续的: 这里 您可以阅读关于神经网络训练中目标函数应该具备的条件。F1得分不满足这些条件-因此无法用于训练神经网络。
  2. 张量和Numpy数组之间不存在等价性: 这是一个根本性问题。Theano张量就像学校方程中的 x。您不能期望代数变量等同于它可以分配给的任何对象。另一方面-作为计算图的一部分-应提供张量操作以计算目标。如果没有提供-则无法针对参数进行微分,这使得大多数常规方式的神经网络训练变得不可能。

这非常有帮助!我自己想不到这些要点。谢谢。我会寻找另一个解决方案的。 - timbit

0
如果您有以numpy数组格式表示的预测和实际张量,则可以使用以下代码片段:
correct_prediction = tf.equal(tf.argmax(actual_tensor,1), tf.argmax(predicted_tensor,1))

accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))

在Keras中,我认为你可以使用这个:

model.fit_generator(train_generator, validation_data=val_generator, nb_val_samples=X_val.shape[0],
                        samples_per_epoch=X_train.shape[0], nb_epoch=nb_epoch, verbose=1,
                        callbacks=[model_checkpoint, reduce_lr, tb], max_q_size=1000)

在训练过程中,train_generator和val_generator生成训练和验证数据,并打印出损失和准确率。

希望这能帮到你...


也许我误解了你的回答,但是我没有将它们存储为numpy数组格式。实际上,我正在寻找一种将张量“y_true”和“y_pred”转换为numpy数组的方法。我希望它们以numpy数组格式出现,这样我就可以将它们馈送到F1函数中,该函数只返回一个标量值。 - timbit
.eval() 方法返回的对象是在 numpy 数组中的,请参考此链接:https://dev59.com/_FsX5IYBdhLWcg3wNtLA - sansingh
是的,我知道。这就是为什么我在我的问题描述中清楚地说明我已经尝试过了。但是,如果没有会话对象,它是无法工作的,我不知道Keras默认使用哪个会话对象。然而,正如上面的答案所述,使用F1指标也不是数学上有效的方法,因此我将尝试另一种方法。 - timbit

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