Python 如何在keras损失函数中使用tf.nn.top_k?

Python 如何在keras损失函数中使用tf.nn.top_k?,python,tensorflow,neural-network,keras,Python,Tensorflow,Neural Network,Keras,我在使用此自定义损失函数时遇到了一些问题(它检查y_pred数据的排序是否与y_true提供的实际排序索引一致): 我可以使用示例数据正确运行它: 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.825

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

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

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
,则我的训练测试集中没有“None”值。模型编译良好,并正确地开始训练(但这显然不是我想要的损失函数)


我有一种微妙的感觉,在损失函数中使用
top_k
可能有点错误,因为我不知道它是如何可微的,但我没有更好的方法来评估预测顺序中的差异。提示/想法/论文/参考?:)

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

我确实不相信你能用top_k作为目标函数。就像你不能用精度作为目标函数一样

原因是数学上的。即使keras、tensorflow、theano和co.是人工智能的绝佳工具,让每个人都可以摆弄神经网络,但后者仍然是非常复杂的数学工具。这些数学很好地隐藏在幕后,但当你试图超越预制工具时,你应该意识到它们

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


我希望这有帮助:)

再次感谢您的帮助/输入Nassim,您所说的完全有道理,也是我所期望的。尽管如此,我看到人们在玩神经网络这类东西,我想知道是否有一种聪明的方法来解决这类问题。例如,检查的“弱”替代方法是使用MSE或分类交叉熵,但我会丢失很多关于数据顺序的信息。您能提供更多关于您试图实现的目标的信息吗?一个关于输入、目标和为什么要这样做的小例子将是完美的!
y_true
是订单数据还是订单数据的索引?@MarcinMożejko是第二个。y最初是有序的,然后在训练之前对其进行洗牌,y_true表示我想要预测的有序数据的索引。atm我默认使用MSE来预测它,但它不是超高效的。我可能会告诉你如何重写你的模型来优化它以得到你想要的结果。目前,你的模型可能做得很差。今晚我问自己同样的问题:“top-k是否可以区分?”我遇到了一个评论。
/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.