【问题标题】:How to use tf.nn.top_k in a keras loss function?如何在 keras 损失函数中使用 tf.nn.top_k?
【发布时间】:2017-02-28 15:41:21
【问题描述】:

我在使这个自定义损失函数(它检查y_pred 数据的排序是否与y_true 提供的实际排序索引一致)工作时遇到了一些问题:

def custom_objective(y_true, y_pred):
    y_true = tf.cast(y_true, tf.float32)
    ordered_output = tf.cast(tf.nn.top_k(-y_pred, k=5)[1], tf.float32)
    return tf.sqrt(tf.reduce_mean(tf.square(ordered_output - y_true), axis=-1))

我可以使用示例数据正确运行它:

with tf.Session() as sess:
    print(custom_objective(tf.constant([0, 1, 2, 3, 4, 5]), 
                           tf.constant([0.0, 0.9, 0.2, 0.3, 0.5, 0.8])).eval())  # 1.82574

但如果我在model.compile 中使用它,它会以某种方式不起作用,因为它会引发:

/Users/luca/.virtualenvs/python3/lib/python3.6/site-packages/tensorflow/python/framework/tensor_util.py in make_tensor_proto(values, dtype, shape, verify_shape)
    358   else:
    359     if values is None:
--> 360       raise ValueError("None values not supported.")
    361     # if dtype is provided, forces numpy array to be the type
    362     # provided if possible.

ValueError: None values not supported.

请注意,如果我将ordered_output = tf.cast(tf.nn.top_k(-y_pred, k=5)[1], tf.float32) 更改为ordered_output = -y_pred,我的训练测试集中没有“无”值,模型编译良好并开始正确训练(但这显然不是我想要的损失函数)。

我有一种微妙的感觉,在损失函数中使用 top_k 可能有问题,因为我看不出它是如何可区分的,但我没有更好的想法来评估预测排序的差异。提示/想法/论文/参考? :)

【问题讨论】:

  • y_true 是订单数据还是订单数据的索引?
  • @MarcinMożejko 第二个。 y 最初是有序的,然后在训练之前被打乱,y_true 表示我想要预测的有序数据的索引。 atm 我默认使用 MSE 来预测它,但它不是超级高效
  • 我可能会向您展示如何重写您的模型以优化它以获得您想要的结果。目前 - 您的模型可能做得很差。
  • 今晚我也在问自己同样的问题:“top-k 是否可微分?”我遇到了this sister site answer,它的评论指向this paper with a differentiable top-k approximation

标签: python tensorflow neural-network keras


【解决方案1】:

这可能会被否决,因为我不会真正修复您的代码,但这里什么都没有:

我确实不相信您可以使用 top_k 作为目标函数。就像您不能将准确性用作目标函数一样。

原因是数学上的。即使是 keras、tensorflow、theano 等。是非常棒的人工智能工具,让每个人都可以摆弄神经网络,后者仍然是非常复杂的数学工具。这些数学运算很好地隐藏在引擎盖下,但是当您尝试比预制工具更进一步时,您应该意识到它们。

当您训练一个网络时,您会计算网络在示例上的错误程度,然后反向传播该错误以从中学习。反向传播背后的算法是优化器,更准确地说,它们是基于梯度的优化器。计算梯度需要区分我们正在优化的函数,即损失/目标函数。这意味着目标必须是可微的。精度不是一个可微函数,它将一个介于 0 和 1 之间的实数作为输入,并输出一个阶跃函数:如果 x0.5,则为 1。该函数不可微,因为我们无法在 0.5 中得到它的梯度。 top_k 函数是某种精度函数。所以在我看来,你确实不能在目标中使用它,因为在幕后,智能张量流必须计算你函数的梯度。

我希望这会有所帮助:)

【讨论】:

  • 再次感谢您的帮助/输入 Nassim,您所说的非常有道理,也是我所期望的。尽管如此,我还是看到有人在玩神经网络来分类东西,我想知道是否有一种聪明的方法来解决这类问题。例如,检查的“弱”替代方法是使用 MSE 或分类交叉熵,但我会丢失很多关于数据排序的信息。
  • 你能提供更多关于你想要达到的目标的信息吗?输入、目标以及为什么要这样做的一个小例子会很完美!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-04-30
  • 1970-01-01
  • 2017-10-16
  • 2021-11-21
  • 2019-01-19
  • 2019-09-28
  • 2020-11-26
相关资源
最近更新 更多