Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/323.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python Keras自定义RMSLE公制_Python_Deep Learning_Keras_Metrics - Fatal编程技术网

Python Keras自定义RMSLE公制

Python Keras自定义RMSLE公制,python,deep-learning,keras,metrics,Python,Deep Learning,Keras,Metrics,我如何在Keras中实现此指标?我下面的代码给出了错误的结果! 请注意,我正在通过exp(x)-1撤消以前的日志(x+1)转换,并且负面预测被剪裁为0: def rmsle_cust(y_true, y_pred): first_log = K.clip(K.exp(y_pred) - 1.0, 0, None) second_log = K.clip(K.exp(y_true) - 1.0, 0, None) return K.sqrt(K.mean(K.square(

我如何在Keras中实现此指标?我下面的代码给出了错误的结果! 请注意,我正在通过exp(x)-1撤消以前的日志(x+1)转换,并且负面预测被剪裁为0:

def rmsle_cust(y_true, y_pred):
    first_log = K.clip(K.exp(y_pred) - 1.0, 0, None)
    second_log = K.clip(K.exp(y_true) - 1.0, 0, None)
    return K.sqrt(K.mean(K.square(K.log(first_log + 1.) - K.log(second_log + 1.)), axis=-1)
作为比较,这里是标准的numpy实现:

def rmsle_cust_py(y, y_pred, **kwargs):
    # undo 1 + log
    y = np.exp(y) - 1
    y_pred = np.exp(y_pred) - 1

    y_pred[y_pred < 0] = 0.0
    to_sum = [(math.log(y_pred[i] + 1) - math.log(y[i] + 1)) ** 2.0 for i,pred in enumerate(y_pred)]
    return (sum(to_sum) * (1.0/len(y))) ** 0.5
def rmsle_cust_py(y,y_pred,**kwargs):
#撤消1+日志
y=np.exp(y)-1
y_pred=np.exp(y_pred)-1
y_pred[y_pred<0]=0.0
to_sum=[(math.log(y_pred[i]+1)-math.log(y[i]+1))**2.0表示i,枚举中的pred(y_pred)]
回报率(总和)*(1.0/len(y))**0.5
我做错了什么?谢谢

编辑:设置
axis=0
似乎给出了一个非常接近正确值的值,但我不确定,因为我看到的所有代码都使用
axis=-1
通过在numpy实现中使用列表(
to_sum
),我怀疑您的numpy数组具有形状
(长度,)

在Keras上,由于轴=0和轴=1的结果不同,所以可能会得到类似于长度1的形状

另外,在创建
to_sum
列表时,您使用的是
y[i]
y_pred[i]
,这意味着您在numpy实现中从
轴=0
获取元素

numpy实现还将计算
sum(to_sum)
中平均值的所有内容相加。因此,您实际上不需要在
K.mean
中使用任何


如果确保模型的输出形状为
(长度,)
(长度,1)
,则可以仅使用
K.mean(值)
,而无需传递轴参数

我遇到了同样的问题并搜索了它,以下是我找到的

经过一点修改后,这似乎对我有效,
rmsle_K
方法使用
Keras
TensorFlow
实现

import numpy as np
import math
from keras import backend as K
import tensorflow as tf

def rmsle(y, y0):
    assert len(y) == len(y0)
    return np.sqrt(np.mean(np.power(np.log1p(y)-np.log1p(y0), 2)))

def rmsle_loop(y, y0):
    assert len(y) == len(y0)
    terms_to_sum = [(math.log(y0[i] + 1) - math.log(y[i] + 1)) ** 2.0 for i,pred in enumerate(y0)]
    return (sum(terms_to_sum) * (1.0/len(y))) ** 0.5

def rmsle_K(y, y0):
    return K.sqrt(K.mean(K.square(tf.log1p(y) - tf.log1p(y0))))

r = rmsle(y=[5, 20, 12], y0=[8, 16, 12])
r1 = rmsle_loop(y=[5, 20, 12], y0=[8, 16, 12])
r2 = rmsle_K(y=[5., 20., 12.], y0=[8., 16., 12.])

print(r)

print(r1)

sess = tf.Session()

print(sess.run(r2))
结果:

使用TensorFlow后端

0.263978210565

0.263978210565

0.263978

谢谢,但是exp(x)-1转换呢?@Fernando我认为你不需要那个转换,尽管我需要,因为我的模型符合log(x+1),所以我需要通过exp(x)-1转换回来,然后应用RMSLE。最小化日志错误不会也会最小化真实错误,因为日志函数是单调转换吗?我注意到,但是,对于同一对(y,y_pred),Keras给出的结果略有不同。我不知道为什么。