【问题标题】:How can I implement this custom loss function in Keras?如何在 Keras 中实现这个自定义损失函数?
【发布时间】:2021-05-23 00:53:03
【问题描述】:

我正在尝试在我的神经网络上实现一个自定义损失函数,如果张量是 numpy 数组,它看起来像这样:

def custom_loss(y_true, y_pred):
    activated = y_pred[y_true > 1]
    return np.abs(activated.mean() - activated.std()) / activated.std()

y's 的形状为(batch_size, 1);也就是说,它是每个输入行的标量输出。

obs:这篇文章 (Converting Tensor to np.array using K.eval() in Keras returns InvalidArgumentError) 给了我一个初步的前进方向。

编辑:

这是我尝试应用自定义损失函数的可重现设置:

import numpy as np

import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers


X = np.random.normal(0, 1, (256, 5))
Y = np.random.normal(0, 1, (256, 1))

model = keras.Sequential([
    layers.Dense(1),
])

model.compile(optimizer='adam', loss=custom_loss)

model.fit(X, Y)

如果我按照上面的问题定义custom_loss,最后一行的.fit() 会引发错误AttributeError: 'Tensor' object has no attribute 'mean'

【问题讨论】:

  • 这能回答你的问题吗? Make a custom loss function in keras
  • @M.Innat,我无法根据您的情况调整您建议的答案。我什至尝试使用相同的代码(答案中的那个),但我收到了错误 TypeError: Input 'y' of 'Mul' Op has type bool that does not match type float32 of argument 'x'. 。不确定最新的张量流和那里的张量流之间是否存在版本兼容性问题。
  • 你能给出一些可重现的代码吗?我遇到过这样的问题,如果你能提供一些重现代码,那就太好了。

标签: python tensorflow keras


【解决方案1】:

这是一个简单的捕获。您可以按如下方式使用自定义损失

def custom_loss(y_true, y_pred):
    activated = y_pred[y_true > 1]
    return tf.math.abs(tf.reduce_mean(activated) - 
                       tf.math.reduce_std(activated)) / tf.math.reduce_std(activated)

或者如果您想使用tf.boolean_mask(tensor, mask, ..),那么您需要确保mask 条件的形状为(None,)1D。如果我们应用 tf.where(y_true>1) ,它将产生一个 2D 张量,需要根据您的情况重新整形。

def custom_loss(y_true, y_pred):
    activated = tf.boolean_mask(y_pred, tf.reshape(tf.where(y_true>1),[-1]) )
    return tf.math.abs(tf.reduce_mean(activated) - 
                       tf.math.reduce_std(activated)) / tf.math.reduce_std(activated)

【讨论】:

    【解决方案2】:

    您是否尝试过在 tensorflow 中编写它,因为有梯度问题?或者这只是在张量流中如何做到这一点? ——别担心,我不会给你一个经典的有毒SO反应! 我会尝试这样的事情(未经测试,但似乎在正确的轨道上):

    def custom_loss(y_true, y_pred):
        activated = tf.boolean_mask(y_pred, tf.where(y_true>1))
        return tf.math.abs(tf.reduce_mean(activated) - tf.math.reduce_std(activated)) / tf.math.reduce_std(activated))
    

    您可能需要在其中使用尺寸,因为所有这些功能都允许指定要使用的尺寸。

    另外,保存模型时会丢失损失函数,除非您对一般损失函数进行子类化。这可能比您想要的更详细,但如果您在保存和加载模型时遇到问题,请告诉我。

    【讨论】:

    • 我尝试使用一些 tensorflow 的张量运算符,但无法正确使用。出现的错误之一与我在您建议的函数的第一行中遇到的相同是:ValueError: Shapes (32, 1) and (None, 2) are incompatible。感谢您的友好。
    • y_true 和 y_pred 的形状是什么?看起来是广播问题。 boolean_mask() 函数在张量和条件之间的形状方面非常具体,因此我怀疑该函数是引发错误的函数。
    • 当我在函数顶部调用print(y_true.shape, y_pred.shape)时,结果是(32, 1), (32, 1)
    • 批量大小是 32 吗?我猜如果它是二维的,它在确定批量大小与特征大小时会遇到问题。我会尝试将两者的尺寸都扩展为 (32, 1, 1),这样批量大小就很明显了,或者明确说明您想要应用布尔掩码和以下函数的尺寸
    • 是的,32 是 batch_size(默认情况下)。特征表确实是二维的。我尝试用tf.expand_dims(y, axis=-1) 扩展尺寸,所以现在的形状是(32, 1, 1)。错误信息略微更改为ValueError: Shapes (32, 1) and (None, 3) are incompatible
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-06-07
    • 2021-10-25
    • 2017-08-20
    • 2018-05-25
    • 2020-12-19
    • 2017-12-18
    • 2020-03-27
    相关资源
    最近更新 更多