【问题标题】:Custom loss function for time series data时间序列数据的自定义损失函数
【发布时间】:2022-02-16 17:19:54
【问题描述】:

我第一次尝试编写自定义损失函数。我的模型生成一个时间序列数据,我想要一个损失函数,它会比早期的错误更多地惩罚系列后期的错误。类似于张量指数用于确定惩罚的地方。张量具有以下结构。

y_true

y_pred

我应该怎么做才能使惩罚成为索引的函数?

 def custom_loss_function(y_true, y_pred):
   squared_difference = tf.square(y_true - y_pred) * 'sqrt(tensor_index)'  <- Desired part
   return tf.reduce_mean(squared_difference, axis=-1)

【问题讨论】:

  • “类似于张量索引用于确定惩罚的地方”
  • 当然,误差平方是针对每个点计算的,一共是 48 个点。第一点是指 t=0,而最后一点是指 t=47。我希望将 t=47 处的误差乘以一个数字以增加整体误差,从而增加系列后期的误差惩罚。 biggining (t=0) 的错误与我无关,因此它可以保持原样。希望这能让它更清楚一点。
  • 好的,所以你只想索引最后一个元素并乘以某个因子?
  • 是的,但不仅仅是最后一个元素。我希望每个元素都与一个因子相乘,并且随着我们向最后一个元素移动,该因子会增加。假设第一个元素的因子为 1,当我们到达第 48 个元素时,因子为 5。只是一个例子。对于 numpy 数组来说很容易,但不知道如何为张量完成它。

标签: python tensorflow keras loss-function


【解决方案1】:

或许可以试试tf.linspace:

import tensorflow as tf

y_true = tf.random.normal((1, 48, 1))
y_pred = tf.random.normal((1, 48, 1))

def custom_loss_function(y_true, y_pred):
   penalty = tf.cast(tf.linspace(start = 1, stop = 5, num = y_pred.shape[1]), dtype=tf.float32)
   print(penalty)
   squared_difference = tf.square(y_true - y_pred) * tf.expand_dims(penalty, axis=-1)
   return tf.reduce_mean(squared_difference, axis=-1)

print(custom_loss_function(y_true, y_pred))
tf.Tensor(
[1.        1.0851064 1.1702127 1.2553191 1.3404255 1.4255319 1.5106384
 1.5957447 1.6808511 1.7659575 1.8510638 1.9361702 2.0212767 2.106383
 2.1914895 2.2765958 2.3617022 2.4468086 2.531915  2.6170213 2.7021277
 2.787234  2.8723404 2.9574468 3.0425532 3.1276596 3.212766  3.2978723
 3.3829787 3.468085  3.5531914 3.6382978 3.7234042 3.8085105 3.893617
 3.9787233 4.06383   4.1489363 4.2340426 4.319149  4.4042554 4.489362
 4.574468  4.6595745 4.744681  4.8297873 4.9148936 5.       ], shape=(48,), dtype=float32)
tf.Tensor(
[[1.3424503e+00 1.7936407e+00 9.5141016e-02 4.1933870e-01 2.9060142e-02
  1.6663458e+00 3.7182972e+00 2.3884547e-01 1.6393075e+00 9.8062935e+00
  1.4726014e+00 6.4087069e-01 1.4197667e+00 2.7730075e-01 2.6717324e+00
  1.2410884e+01 2.8422637e+00 2.2836231e+01 1.9438576e+00 7.2612977e-01
  2.9226139e+00 1.3040878e+01 5.8225789e+00 2.3456068e+00 2.8281093e+00
  4.2308202e+00 2.6682162e+00 4.0025130e-01 3.5946998e-01 8.0574770e-03
  2.7833527e-01 3.8349494e-01 7.1913116e-02 3.0325607e-03 5.8022089e+00
  4.4835452e-02 4.7429881e+00 6.4035267e-01 5.0330186e+00 2.7156603e+00
  1.2085355e-01 3.5016473e-02 7.9860941e-02 3.1455503e+01 5.3314602e+01
  3.8006527e+01 1.1620968e+01 4.1495290e+00]], shape=(1, 48), dtype=float32)

更新 1

import tensorflow as tf

y_true = tf.random.normal((2, 48, 1))
y_pred = tf.random.normal((2, 48, 1))
def custom_loss_function(y_true, y_pred):
   penalty = tf.cast(tf.linspace(start = 1, stop = 5, num = tf.shape(y_pred)[1]), dtype=tf.float32)
   penalty = tf.expand_dims(penalty, axis=-1)
   penalty = tf.expand_dims(tf.transpose(tf.repeat(penalty, repeats=tf.shape(y_pred)[0], axis=1)), axis=-1)
   squared_difference = tf.square(y_true - y_pred) * penalty
   return tf.reduce_mean(squared_difference, axis=-1)

【讨论】:

  • 谢谢你,我试试看。会尽快回复您。
  • 我收到了更多警告,并且张量“惩罚”的形状不是我所期望的。 “" num = tf.shape(a_in)[1] 无法正常工作。我希望这里有 48 个,而不是 None
  • 您的第一个答案是正确的。只需要一个小修复。 ````` 惩罚 = tf.cast(tf.linspace(start = 1, stop = 5, num = y_pred.shape[1]), dtype=tf.float32)
  • 修复后的原始答案有效。谢谢。我没有尝试更新的。 :)
猜你喜欢
  • 2020-12-19
  • 2017-04-04
  • 2017-12-18
  • 2020-03-27
  • 2020-11-16
  • 2019-05-27
  • 2020-02-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多