Keras中加权均方误差自定义损失函数

14

我正在处理时间序列数据,输出60天的预测。

我目前使用均方误差作为损失函数,但结果很糟糕。

我想实现加权均方误差,使得早期的输出比后期的更重要。

加权均方根公式:

Weighted Mean Square Root formula

因此,我需要一些方法来迭代一个张量的元素,带有一个索引(因为我需要同时迭代预测值和真实值,然后将结果写入一个只有一个元素的张量中。它们都是(?,60),但实际上是(1,60)列表。

但我尝试的所有方法都没有起作用。这是出问题版本的代码:

def weighted_mse(y_true,y_pred):
    wmse = K.cast(0.0,'float')

    size = K.shape(y_true)[0]
    for i in range(0,K.eval(size)):
        wmse += 1/(i+1)*K.square((y_true[i]-y_pred)[i])

    wmse /= K.eval(size)
    return wmse

我目前因此得到以下错误:

InvalidArgumentError (see above for traceback): You must feed a value for placeholder tensor 'dense_2_target' with dtype float
 [[Node: dense_2_target = Placeholder[dtype=DT_FLOAT, shape=[], _device="/job:localhost/replica:0/task:0/cpu:0"]()]]

阅读了类似帖子的回复,我认为口罩无法完成任务,而在一个张量中循环元素也不起作用,因为我将无法访问另一个张量中对应的元素。

任何建议都将不胜感激

1个回答

11

你可以采用这种方法:

def weighted_mse(yTrue,yPred):

    ones = K.ones_like(yTrue[0,:]) #a simple vector with ones shaped as (60,)
    idx = K.cumsum(ones) #similar to a 'range(1,61)'


    return K.mean((1/idx)*K.square(yTrue-yPred))

使用ones_likecumsum,可以将该损失函数应用于任何类型的(samples,classes)输出。


提示:在处理张量时始终使用后端函数。可以使用切片,但要避免迭代。


1
我花了好几个小时才弄明白这个问题。谢谢! - Eldar M.
(1/idx)*K.square(yTrue-yPred) 中,* 是元素级别操作还是矩阵乘法操作?谢谢! - username123
它是逐元素的。对于矩阵乘法,有K.dot()K.batch_dot() - Daniel Möller
@DanielMöller 谢谢!但是K.square(yTrue-yPred)的形状为(n_samples, n_components),而1/idx的形状为(n_components,),在这种情况下如何进行逐元素乘法? - username123
1
@username123,缺失的维度(n_samples)将被重复。 - Daniel Möller
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接