|
1 | 1 | """
|
2 | 2 | Authors : inzapp
|
3 | 3 |
|
4 |
| -Github url : https://github.com/inzapp/absolute-logarithmic-error |
| 4 | +Github url : https://github.com/inzapp/adaptive-crossentropy |
5 | 5 |
|
6 |
| -Copyright 2022 inzapp Authors. All Rights Reserved. |
| 6 | +Copyright 2023 inzapp Authors. All Rights Reserved. |
7 | 7 |
|
8 | 8 | Licensed under the Apache License, Version 2.0 (the "License"),
|
9 | 9 | you may not use this file except in compliance with the License.
|
|
20 | 20 | import tensorflow as tf
|
21 | 21 |
|
22 | 22 |
|
23 |
| -class AbsoluteLogarithmicError(tf.keras.losses.Loss): |
24 |
| - """Computes the cross-entropy log scale loss between true labels and predicted labels. |
| 23 | +class AdaptiveCrossentropy(tf.keras.losses.Loss): |
| 24 | + """Computes the adaptive cross-entropy loss between true labels and predicted labels. |
25 | 25 |
|
26 |
| - This loss function can be used regardless of classification problem or regression problem. |
27 |
| -
|
28 |
| - See: https://github.com/inzapp/absolute-logarithmic-error |
| 26 | + See: https://github.com/inzapp/adaptive-crossentropy |
29 | 27 |
|
30 | 28 | Standalone usage:
|
31 | 29 | >>> y_true = [[0, 1], [0, 0]]
|
32 | 30 | >>> y_pred = [[0.6, 0.4], [0.4, 0.6]]
|
33 |
| - >>> ale = AbsoluteLogarithmicError() |
34 |
| - >>> loss = ale(y_true, y_pred) |
| 31 | + >>> ace = AdaptiveCrossentropy() |
| 32 | + >>> loss = ace(y_true, y_pred) |
35 | 33 | >>> loss.numpy()
|
36 |
| - array([[0.9162905, 0.9162905], [0.5108255, 0.9162905]], dtype=float32) |
| 34 | + array([[0.9162906 0.9162905], [0.5108254 0.9162906]], dtype=float32) |
37 | 35 |
|
38 | 36 | Usage:
|
39 |
| - model.compile(optimizer='sgd', loss=AbsoluteLogarithmicError()) |
| 37 | + model.compile(optimizer='sgd', loss=AdaptiveCrossentropy()) |
40 | 38 | """
|
41 |
| - def __init__(self, alpha=0.0, gamma=0.0, label_smoothing=0.0, reduce='none', name='AbsoluteLogarithmicError'): |
| 39 | + def __init__(self, alpha=0.0, gamma=0.0, label_smoothing=0.0, reduce='none', name='AdaptiveCrossentropy'): |
42 | 40 | """
|
43 | 41 | Args:
|
44 | 42 | alpha: Weight of the loss where not positive value positioned in y_true tensor.
|
@@ -79,14 +77,14 @@ def call(self, y_true, y_pred):
|
79 | 77 | eps = tf.cast(self.eps, y_pred.dtype)
|
80 | 78 | y_true_clip = tf.clip_by_value(y_true, self.label_smoothing, 1.0 - self.label_smoothing)
|
81 | 79 | y_pred_clip = tf.clip_by_value(y_pred, eps, 1.0 - eps)
|
82 |
| - abs_error = tf.abs(y_true_clip - y_pred_clip) |
83 |
| - loss = -tf.math.log((1.0 + eps) - abs_error) |
| 80 | + loss = -((y_true * tf.math.log(y_pred + eps)) + ((1.0 - y_true) * tf.math.log(1.0 - y_pred + eps))) |
84 | 81 | if self.alpha > 0.0:
|
85 | 82 | alpha = tf.ones_like(y_true) * self.alpha
|
86 | 83 | alpha = tf.where(y_true != 1.0, alpha, 1.0 - alpha)
|
87 | 84 | loss *= alpha
|
88 | 85 | if self.gamma >= 1.0:
|
89 |
| - loss *= tf.pow(abs_error, self.gamma) |
| 86 | + adaptive_weight = tf.pow(tf.abs(y_true_clip - y_pred_clip), self.gamma) |
| 87 | + loss *= adaptive_weight |
90 | 88 | if self.reduce == 'mean':
|
91 | 89 | loss = tf.reduce_mean(loss)
|
92 | 90 | elif self.reduce == 'sum':
|
|
0 commit comments