Omar
Omar

Reputation: 23

Custom loss function for time series data

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)

Upvotes: 2

Views: 903

Answers (1)

AloneTogether
AloneTogether

Reputation: 26708

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)

Upvotes: 2

Related Questions