自定义损失功能Keras Tensorflow

axi*_*iom 2 keras tensorflow

我需要一个自定义加权MSE损失函数.我在keras.backend中定义了它

from keras import backend as K
def weighted_loss(y_true, y_pred):
    return K.mean( K.square(y_pred - y_true) *
    K.exp(-K.log(1.7) * (K.log(1. + K.exp((y_true - 3)/5 ))))      
    ,axis=-1  )
Run Code Online (Sandbox Code Playgroud)

但是,测试运行会返回

    weighted_loss(1,2)
ValueError: Tensor conversion requested dtype int32 for Tensor with dtype float32: 'Tensor("Exp_37:0", shape=(), dtype=float32)'  
Run Code Online (Sandbox Code Playgroud)

要么

    weighted_loss(1.,2.)
ZeroDivisionError: integer division or modulo by zero   
Run Code Online (Sandbox Code Playgroud)

我想知道我在这里犯了什么错误.

5Ke*_*5Ke 6

无论您使用Tensorflow还是Theano都与您的问题无关.谷歌"张量"的意思,如果这个词让你感到困惑.

看看Keras如何在这里实现损失函数测试:

def test_metrics():
    y_a = K.variable(np.random.random((6, 7)))
    y_b = K.variable(np.random.random((6, 7)))
    for metric in all_metrics:
        output = metric(y_a, y_b)
        print(metric.__name__)
        assert K.eval(output).shape == (6,)
Run Code Online (Sandbox Code Playgroud)

您不能简单地将float或int提供给张量计算.还要注意使用K.eval来获得您正在寻找的结果.

所以尝试类似于你的功能:

from keras import backend as K
import numpy as np

y_a = K.variable(np.random.random((6, 7)))
y_b = K.variable(np.random.random((6, 7)))
output = weighted_loss(y_a,y_b)
result = K.eval(output)
Run Code Online (Sandbox Code Playgroud)

也没有必要在keras.backend中定义自定义函数 - 如果您决定稍后更新Keras会怎么样?

相反,您可以在自己的代码中执行以下操作:定义一个返回损失函数的函数

def weighted_loss(y_true, y_pred):
        return K.mean( K.square(y_pred - y_true) * K.exp(-K.log(1.7) * (K.log(1. + K.exp((y_true - 3)/5 )))),axis=-1  )
Run Code Online (Sandbox Code Playgroud)

然后,当您想使用损失函数编译模型时,您可以:

model.compile(loss = weighted_loss)
Run Code Online (Sandbox Code Playgroud)

  • @ 5Ke我认为没有理由需要将损失函数包装到另一个函数中,您可以通过名称传递它而无需调用它。原始帖子中的真正问题是OP试图用浮点输入来评估损失函数,而不是比张量输入。 (2认同)