这是我开展深度学习项目的第三次尝试。我正在研究蛋白质序列。首先,我尝试了TFLearn,然后尝试了原始TensorFlow,现在我尝试了Keras。
前两次尝试教给了我很多东西,并给了我一些我可以重用的代码和概念。但是,总会有障碍,我问过开发人员无法回答的问题(在TFLearn的情况下),或者我只是陷入了困境(TensorFlow对象自省很乏味)。
我已经编写了这个TensorFlow损失函数,并且我知道它可以工作:
def l2_angle_distance(pred, tgt):
with tf.name_scope("L2AngleDistance"):
# Scaling factor
count = tgt[...,0,0]
scale = tf.to_float(tf.count_nonzero(tf.is_finite(count)))
# Mask NaN in tgt
tgt = tf.where(tf.is_nan(tgt), pred, tgt)
# Calculate L1 losses
losses = tf.losses.cosine_distance(pred, tgt, -1, reduction=tf.losses.Reduction.NONE)
# Square the losses, then sum, to get L2 scalar loss.
# Divide the loss result by the scaling factor.
return tf.reduce_sum(losses * losses) / scale
Run Code Online (Sandbox Code Playgroud)
我的目标值(tgt)可以包含NaN,因为我的蛋白质序列是通过4D张量传递的,尽管各个序列的长度不同。在您询问之前,无法像图像一样对数据进行重新采样。因此,我在tgt张量中使用NaN来表示“此处无需预测”。在计算L2余弦损耗之前,我用预测(预测)中的匹配值替换每个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()。
感谢您的建议!
我回答了我自己的问题。我将解决方案发布给可能遇到相同问题的任何人。
Matias Valdenegro独立建议,我尝试直接在Keras中使用TF损失函数。我这样做并没有引起Keras的任何错误,但是损失值立即转到了NaN。
最终我找到了问题所在。Keras损失函数的调用约定是y_true(我称为tgt),然后是y_pred(我的pred)。但是,对于一个TensorFlow损失函数调用约定预解码,再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")
Run Code Online (Sandbox Code Playgroud)
我不知道,也许Theano或CNTK使用与Keras相同的参数顺序。但是我又回来了。
| 归档时间: |
|
| 查看次数: |
1977 次 |
| 最近记录: |