我需要一个自定义的加权MSE损失函数。我在keras.back中定义了它
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 )
但是,测试运行返回
weighted_loss(1,2)
ValueError: Tensor conversion requested dtype int32 for Tensor with dtype float32: 'Tensor("Exp_37:0", shape=(), dtype=float32)'
或
weighted_loss(1.,2.)
ZeroDivisionError: integer division or modulo by zero
我想知道我在这里犯了什么错误。
无论你使用的是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,)
您不能简单地将浮点数或 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)
也无需在 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 )
然后,当您想使用损失函数编译模型时,您可以执行以下操作:
model.compile(loss = weighted_loss)
如果你想定义一个更通用的损失函数,其中权重取决于一些输入,你需要包装这个函数。所以例如:
def get_weighted_loss(my_input):
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)/my_input )))),axis=-1 )
return weighted_loss
然后,当您想使用损失函数编译模型时,您可以执行以下操作:
model.compile(loss = get_weighted_loss(5))