Keras自定义损失函数:形状为batch_size(y_true)的变量

时间:2019-01-27 13:51:28

标签: python tensorflow keras deep-learning loss-function

在Keras中实现自定义损失功能时,我需要一个tf.Variable,其形状为我的输入数据(y_true, y_pred)的批量大小。

def custom_loss(y_true, y_pred):

    counter = tf.Variable(tf.zeros(K.shape(y_true)[0], dtype=tf.float32))
    ...

但是,这会产生错误:

You must feed a value for placeholder tensor 'dense_17_target' with dtype float and shape [?,?]

如果我将batch_size固定为一个值:

def custom_loss(y_true, y_pred):

    counter = tf.Variable(tf.zeros(batch_size, dtype=tf.float32))
    ...

使得|training_set| % batch_size|val_set| % batch_size等于零,一切正常。

有什么建议,为什么基于输入形状(y_truey_pred)的批量大小的变量分配不起作用?

解决方案

我找到了令人满意的解决方案。 我以最大的batch_size可能值初始化了变量(在模型构建期间指定),并且仅将K.shape(y_true)[0]用于切片变量。这样,它可以完美工作。这里的代码:

def custom_loss(y_true, y_pred):
    counter = tf.Variable(tf.zeros(batch_size, dtype=tf.float32))
    ...
    true_counter = counter[:K.shape(y_true)[0]]
    ...

2 个答案:

答案 0 :(得分:0)

它不起作用,因为K.shape返回一个符号形状,它是张量本身,而不是int值的元组。要从张量获取值,您必须在会话下对其进行评估。参见documentation。要在评估之前获得实际价值,请使用K.int_shapehttps://keras.io/backend/#int_shape

但是,K.int_shape在这里也不起作用,因为它只是一些静态元数据,通常不会反映当前的批处理大小,但是具有占位符值None

您发现的解决方案(可以控制批次大小并在损失范围内使用它)确实是一个很好的解决方案。

我相信问题是因为您需要在定义时知道批量大小以构建变量,但是只有在会话运行时才能知道。

如果像张量一样使用它,应该没问题,请参见example

答案 1 :(得分:0)

另一种解决方案是使用tf.assignvalidate_shape=False动态创建变量并改变其形状:

counter = tf.Variable(0.0)
...
val = tf.zeros(tf.shape(y_true)[:1], 0.0)
counter = tf.assign(counter, val, validate_shape=False)