Custom loss function for time series data

Viewed 197

I am trying to write a custom loss function for the very first time. My model generates a time series data and I want a loss function which would penalize errors later in the series more than the earlier ones. Something like where index of tensor is used to determine the penalty. The tensors have following structure.

y_true <tf.Tensor 'IteratorGetNext:1' shape=(None, 48, 1) dtype=float32>

y_pred <tf.Tensor 'ResNet34/dense_1/BiasAdd:0' shape=(None, 48, 1) dtype=float32>

What should I do to make the penalty a function of index?

 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)
1 Answers

Maybe try using 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)

Update 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)
Related