【问题标题】:keras model with tf.contrib.losses.metric_learning.triplet_semihard_loss Assertion error带有 tf.contrib.losses.metric_learning.triplet_semihard_loss 断言错误的 keras 模型
【发布时间】:2019-05-28 11:48:30
【问题描述】:

我正在将 python 3 与 anaconda 一起使用,并尝试将 tf.contrib 损失函数与 Keras 模型一起使用。

代码如下

from keras.layers import Dense, Flatten
from keras.optimizers import Adam
from keras.models import Sequential
from tensorflow.contrib.losses import metric_learning
model = Sequential()
model.add(Flatten(input_shape=input_shape))
model.add(Dense(50,  activation="relu"))
model.compile(loss=metric_learning.triplet_semihard_loss, optimizer=Adam())

我收到以下错误:

文件 "/home/user/.local/lib/python3.6/site-packages/keras/engine/training_utils.py", 第 404 行,加权 score_array = fn(y_true, y_pred) 文件“/home/user/anaconda3/envs/siamese/lib/python3.6/site-packages/tensorflow/contrib/losses/python/metric_learning/metric_loss_ops.py”, 第 179 行,在 Triplet_semihard_loss 中 断言 lshape.shape == 1 断言错误

当我使用带有 keras 损失函数的同一个网络时,它工作正常,我尝试将 tf 损失函数包装在这样的函数中

def func(y_true, y_pred): 
    import tensorflow as tf
    return tf.contrib.losses.metric_learning.triplet_semihard_loss(y_true, y_pred) 

仍然出现同样的错误

我在这里做错了什么?

更新: 当更改 func 以返回以下内容时

return K.categorical_crossentropy(y_true, y_pred)

一切正常! 但我不能让它与特定的 tf 损失函数一起工作......

当我进入 tf.contrib.losses.metric_learning.triplet_semihard_loss 并删除这行代码时:assert lshape.shape == 1 它运行良好

谢谢

【问题讨论】:

  • 仍然不清楚到底在哪里你的错误会弹出;是在fit 期间吗?在compile?发布完整的错误跟踪是个好主意...
  • @desertnaut 错误在编译函数中。当我进入 tf.contrib.losses.metric_learning.triplet_semihard_loss 并删除这行代码时: assert lshape.shape == 1 它运行良好
  • 您好,我也有同样的问题,但解决方案变得如此简单。您只需替换参数。首先设置标签,然后设置嵌入。
  • @thebeancounter 嘿!你能解决吗?我也遇到了同样的问题,不知道怎么办?

标签: python tensorflow machine-learning keras deep-learning


【解决方案1】:

问题是您将错误的输入传递给损失函数。

根据triplet_semihard_loss docstring,你需要通过labelsembeddings

所以你的代码必须是:

def func(y, embeddings): 
    return tf.contrib.losses.metric_learning.triplet_semihard_loss(labels=y, embeddings=embeddings) 

还有两个关于嵌入网络的注意事项:

  1. 最后一个密集层必须没有激活

  2. 别忘了标准化输出向量model.add(Lambda(lambda x: K.l2_normalize(x, axis=1)))

【讨论】:

  • 为什么说输入错误?在我看来,labels=y_true 与您在这里写的相似
【解决方案2】:

您的问题似乎来自损失函数中的错误输入。其实triplet loss要的是参数:

Args:
labels: 1-D tf.int32 `Tensor` with shape [batch_size] of
  multiclass integer labels.
embeddings: 2-D float `Tensor` of embedding vectors. Embeddings should
  be l2 normalized.

您确定y_true 的形状正确吗?你能告诉我们更多关于你使用的张量的细节吗?

【讨论】:

  • 这在获得 y-true 或任何输入之前就崩溃了。它在编译阶段崩溃
  • 它在运行任何计算之前崩溃,因为 Tensorflow 首先构建了计算图,所以如果张量的维度之间存在一些不匹配,它甚至会在为任何占位符提供其值之前引发错误。这是绝对正常的,那么任何其他信息都可能有助于调试您的代码
  • 问题是在损失函数中有一个断言,检查 y_true 形状是否为 2d 或更多,但是这个损失函数使用 y_true 作为整数(标签)的单维向量,所以它没有任何意义,我删除了断言,它工作正常@gabriele
猜你喜欢
  • 2020-08-14
  • 1970-01-01
  • 1970-01-01
  • 2020-07-26
  • 1970-01-01
  • 2017-07-08
  • 2022-01-14
  • 2021-07-02
  • 2023-03-15
相关资源
最近更新 更多