Reputation: 23
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
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