如何在Keras中包装自定义TensorFlow损失功能?

时间:2018-01-01 07:33:10

标签: tensorflow keras

这是我第三次尝试开展深度学习项目。我正在研究蛋白质序列。首先我尝试了TFLearn,然后是原始的TensorFlow,现在我正在尝试Keras。

之前的两次尝试教会了我很多,并给了我一些我可以重复使用的代码和概念。然而,总是有一个障碍,我问过开发人员无法回答的问题(在TFLearn的情况下),或者我只是陷入困境(TensorFlow对象内省是乏味的)。

我已经编写了这个TensorFlow丢失函数,我知道它有效:

{{1}}

我的目标值(tgt)可以包括NaN,因为我的蛋白质序列在4D Tensor中传递,尽管个体序列的长度不同。在您提出要求之前,数据无法像图像一样重新采样。所以我在tgt Tensor中使用NaN来表示“这里不需要预测”。在计算L2余弦损失之前,我用预测中的匹配值(pred)替换每个NaN,因此每个NaN的损失总是为零。

现在,如何在Keras中重复使用此功能?似乎Keras Lambda核心层不是一个好选择,因为Lambda只接受一个参数,而损失函数需要两个参数。

或者,我可以在Keras中重写此功能吗?我不应该使用Theano或CNTK后端,因此我没有必要在Keras中重写我的功能。我将使用任何有用的东西。

我只是看了一下Keras loss.py文件以获得一些线索。我导入了keras.backend并浏览了一下。我还找到了https://keras.io/backend/。我似乎没有找到我碰巧使用的任何TensorFlow函数调用的包装器:to_float(),count_nonzero(),is_finite(),where(),is_nan(),cosine_distance()或reduce_sum()。< / p>

感谢您的建议!

2 个答案:

答案 0 :(得分:5)

我回答了自己的问题。我正在为可能遇到同样问题的任何人发布解决方案。

我尝试直接在Keras使用我的TF损失功能,正如Matias Valdenegro独立建议的那样。我这样做没有引起Keras的任何错误,然而,损失价值立即转向NaN。

最终我发现了问题。 Keras损失函数的调用约定是 y_true (我称之为 tgt ),然后是 y_pred (我的 pred >)。但是TensorFlow损失函数的调用约定首先是 pred ,然后是 tgt 。因此,如果您想保留丢失函数的Tensorflow本机版本,此修复程序可以正常工作:

def keras_l2_angle_distance(tgt, pred):
    return l2_angle_distance(pred, tgt)

<snip>

model.compile(loss = keras_l2_angle_distance, optimizer = "something")

也许Theano或CNTK使用与Keras相同的参数顺序,我不知道。但是我回来了。

答案 1 :(得分:2)

您不需要使用keras.backend,因为您的损失直接写在TensorFlow中,然后您可以直接在Keras中使用它。后端函数是一个抽象层,因此您可以编写一个与Keras中多个可用后端一起使用的丢失/层。

您只需将您的损失记入model.compile来电:

model.compile(loss = l2_angle_distance, optimizer = "something")