keras自定义丢失函数转换为张量时的值错误

时间:2017-10-30 04:05:39

标签: python tensorflow keras

我正在尝试使用tensorflow后端为keras实现自定义丢失功能。我正在使用的想法是提供“信号”的“成本”作为y_true并将信号处理为y_pred。这基本上是一个复杂的分类情况。

作为一个例子,假设我有3个可能的输出信号和N个样本,那么我将有一个Nx3的成本矩阵,我的预测也将是Nx3(这样就不会遇到y_true和y_pred需要的问题相同的大小。

我选择实际信号的方法是取三个输出值的最大值,然后该信号的成本就是相应指数的成本矩阵中的值。总费用是这些个人费用的总和。

我已经在tensorflow中实现了这个(我需要使用gather_nd所以我不能使用keras.backend,但我在网上阅读的所有例子似乎并不关心这个事实)。我的实现代码是:

def maxSignalLossTF(costs, signals):

    signalChoices = tf.transpose(tf.stack((tf.to_int64(tf.range(tf.shape(signals)[0])), tf.argmax(signals, axis=1))))

    signalCosts = tf.gather_nd(costs, signalChoices)
    return tf.reduce_sum(signalCosts)

我已经确认此功能通过将其与numpy等效项进行比较而按预期工作。我在编译时将这个损失函数传递给我的模型:

model = Sequential()
model.add(Dense(250, input_shape=(trainX.shape[1],)))
model.add(Activation('relu'))
model.add(Dropout(0.1))

model.add(Dense(250))
model.add(Activation('relu'))

model.add(Dense(3))
model.add(Activation('linear'))
model.compile(optimizer='adam', loss=maxSignalLossTF)

所有这些看起来都很好,直到我尝试使用以下模型:     model.fit(TrainX,TrainY,epochs = 100) 此时控制台会发出以下无用的消息

    Traceback (most recent call last):
  File "tensortest.py", line 331, in <module>
    model.fit(TrainX, TrainY, epochs=100)
  File "/home/myname/anaconda2/lib/python2.7/site-packages/keras/models.py", line 845, in fit
    initial_epoch=initial_epoch)
  File "/home/myname/anaconda2/lib/python2.7/site-packages/keras/engine/training.py", line 1457, in fit
    self._make_train_function()
  File "/home/myname/anaconda2/lib/python2.7/site-packages/keras/engine/training.py", line 1001, in _make_train_function
    self.total_loss)
  File "/home/myname/anaconda2/lib/python2.7/site-packages/keras/optimizers.py", line 398, in get_updates
    m_t = (self.beta_1 * m) + (1. - self.beta_1) * g
  File "/home/myname/anaconda2/lib/python2.7/site-packages/tensorflow/python/ops/math_ops.py", line 856, in binary_op_wrapper
    y = ops.convert_to_tensor(y, dtype=x.dtype.base_dtype, name="y")
  File "/home/myname/anaconda2/lib/python2.7/site-packages/tensorflow/python/framework/ops.py", line 611, in convert_to_tensor
    as_ref=False)
  File "/home/myname/anaconda2/lib/python2.7/site-packages/tensorflow/python/framework/ops.py", line 676, in internal_convert_to_tensor
    ret = conversion_func(value, dtype=dtype, name=name, as_ref=as_ref)
  File "/home/myname/anaconda2/lib/python2.7/site-packages/tensorflow/python/framework/constant_op.py", line 121, in _constant_tensor_conversion_function
    return constant(v, dtype=dtype, name=name)
  File "/home/myname/anaconda2/lib/python2.7/site-packages/tensorflow/python/framework/constant_op.py", line 102, in constant
    tensor_util.make_tensor_proto(value, dtype=dtype, shape=shape, verify_shape=verify_shape))
  File "/home/myname/anaconda2/lib/python2.7/site-packages/tensorflow/python/framework/tensor_util.py", line 364, in make_tensor_proto
    raise ValueError("None values not supported.")
ValueError: None values not supported.

我试图在keras和tensorflow中追踪这条消息的来源,但是当我找到这些函数时,它并没有给我带来太多洞察力,因为我做错了什么。我已经绝望地完全实现了在我的输入X和Y上使用tf.convert_to_tensor()手动计算,这没有任何问题所以我很难在这一点上出错。

我是Keras和tensorflow的新手,虽然我已经看过基本上每个例子我都能找到它很可能我错过了一些非常简单的东西。所以任何帮助都非常感谢。提前致谢

此外,如果有这种成本设置的预制解决方案,我很乐意了解它们。我在修改了一些不同的标准选项后得出了这个想法而没有太大的成功,所以我决定尝试一些能让我更好地直接控制各种输出信号的东西,这些信号可以更好地捕捉潜在的问题(某些样本的误分类不是与错误分类其他样本一样重要)

1 个答案:

答案 0 :(得分:0)

这种情况正在发生,因为您的损失函数与您的模型权重无法区分。

您的结果完全基于&#34;常数&#34;来自&#34; y_true&#34; (这是&#34;费用&#34;)。

虽然它是真的,你可以通过改变哪些信号最大来改变损失函数的结果,但是如果没有可微函数,就不可能知道要采用哪个方向。

起初,我无法想到替换你的功能,而根据我的理解,重要的是3个结果中的一个比其他结果更大,与它们的价值无关。这真的是你的意图吗?

例如:

For a cost [1,4,2], any of the following signals are ok by your function:

[10,9,3]
[1,0,0]   
[10e+45,1,10e-12]
etc....

as long as the first one is greater, your loss is the lowest.