2023-04-20 01:38:56 +00:00
|
|
|
from keras_core import backend
|
2023-04-20 01:43:07 +00:00
|
|
|
from keras_core import operations as ops
|
2023-04-21 20:59:07 +00:00
|
|
|
from keras_core.api_export import keras_core_export
|
2023-04-12 18:31:58 +00:00
|
|
|
from keras_core.losses.loss import Loss
|
2023-04-09 19:21:45 +00:00
|
|
|
from keras_core.losses.loss import squeeze_to_same_rank
|
2023-04-25 04:21:57 +00:00
|
|
|
from keras_core.saving import serialization_lib
|
2023-04-29 22:08:38 +00:00
|
|
|
from keras_core.utils.numerical_utils import normalize
|
2023-04-09 19:21:45 +00:00
|
|
|
|
|
|
|
|
|
|
|
class LossFunctionWrapper(Loss):
|
2023-04-12 18:00:14 +00:00
|
|
|
def __init__(
|
|
|
|
self, fn, reduction="sum_over_batch_size", name=None, **kwargs
|
|
|
|
):
|
2023-04-09 19:21:45 +00:00
|
|
|
super().__init__(reduction=reduction, name=name)
|
|
|
|
self.fn = fn
|
|
|
|
self._fn_kwargs = kwargs
|
|
|
|
|
|
|
|
def call(self, y_true, y_pred):
|
|
|
|
y_true, y_pred = squeeze_to_same_rank(y_true, y_pred)
|
|
|
|
return self.fn(y_true, y_pred, **self._fn_kwargs)
|
|
|
|
|
|
|
|
def get_config(self):
|
2023-04-25 04:21:57 +00:00
|
|
|
base_config = super().get_config()
|
|
|
|
config = {"fn": serialization_lib.serialize_keras_object(self.fn)}
|
|
|
|
config.update(serialization_lib.serialize_keras_object(self._fn_kwargs))
|
|
|
|
return {**base_config, **config}
|
2023-04-09 19:21:45 +00:00
|
|
|
|
|
|
|
@classmethod
|
2023-04-25 04:21:57 +00:00
|
|
|
def from_config(cls, config):
|
|
|
|
if "fn" in config:
|
|
|
|
config = serialization_lib.deserialize_keras_object(config)
|
|
|
|
return cls(**config)
|
2023-04-09 19:21:45 +00:00
|
|
|
|
|
|
|
|
2023-04-21 20:59:07 +00:00
|
|
|
@keras_core_export("keras_core.losses.MeanSquaredError")
|
2023-04-19 04:18:20 +00:00
|
|
|
class MeanSquaredError(LossFunctionWrapper):
|
|
|
|
"""Computes the mean of squares of errors between labels and predictions.
|
2023-04-09 19:21:45 +00:00
|
|
|
|
2023-04-20 01:43:07 +00:00
|
|
|
Formula:
|
|
|
|
|
|
|
|
```python
|
|
|
|
loss = mean(square(y_true - y_pred))
|
|
|
|
```
|
2023-04-19 04:18:20 +00:00
|
|
|
|
|
|
|
Args:
|
2023-05-01 17:21:40 +00:00
|
|
|
reduction: Type of reduction to apply to loss. For almost all cases
|
|
|
|
this defaults to `"sum_over_batch_size"`. Options are `"sum"`,
|
|
|
|
`"sum_over_batch_size"` or `None`.
|
|
|
|
name: Optional name for the instance.
|
2023-04-19 04:18:20 +00:00
|
|
|
"""
|
2023-04-09 19:21:45 +00:00
|
|
|
|
2023-04-12 18:00:14 +00:00
|
|
|
def __init__(
|
|
|
|
self, reduction="sum_over_batch_size", name="mean_squared_error"
|
|
|
|
):
|
2023-04-09 19:21:45 +00:00
|
|
|
super().__init__(mean_squared_error, reduction=reduction, name=name)
|
2023-04-19 04:18:20 +00:00
|
|
|
|
2023-04-25 04:21:57 +00:00
|
|
|
def get_config(self):
|
|
|
|
return Loss.get_config(self)
|
|
|
|
|
2023-04-19 04:18:20 +00:00
|
|
|
|
2023-04-21 20:59:07 +00:00
|
|
|
@keras_core_export("keras_core.losses.MeanAbsoluteError")
|
2023-04-19 04:18:20 +00:00
|
|
|
class MeanAbsoluteError(LossFunctionWrapper):
|
|
|
|
"""Computes the mean of absolute difference between labels and predictions.
|
|
|
|
|
2023-04-20 01:43:07 +00:00
|
|
|
Formula:
|
|
|
|
|
|
|
|
```python
|
|
|
|
loss = mean(abs(y_true - y_pred))
|
|
|
|
```
|
2023-04-19 04:18:20 +00:00
|
|
|
|
|
|
|
Args:
|
2023-05-01 17:21:40 +00:00
|
|
|
reduction: Type of reduction to apply to loss. For almost all cases
|
|
|
|
this defaults to `"sum_over_batch_size"`. Options are `"sum"`,
|
|
|
|
`"sum_over_batch_size"` or `None`.
|
|
|
|
name: Optional name for the instance.
|
2023-04-19 04:18:20 +00:00
|
|
|
"""
|
|
|
|
|
|
|
|
def __init__(
|
2023-04-20 01:38:56 +00:00
|
|
|
self, reduction="sum_over_batch_size", name="mean_absolute_error"
|
2023-04-19 04:18:20 +00:00
|
|
|
):
|
|
|
|
super().__init__(mean_absolute_error, reduction=reduction, name=name)
|
|
|
|
|
2023-04-25 04:21:57 +00:00
|
|
|
def get_config(self):
|
|
|
|
return Loss.get_config(self)
|
|
|
|
|
2023-04-19 04:18:20 +00:00
|
|
|
|
2023-04-21 20:59:07 +00:00
|
|
|
@keras_core_export("keras_core.losses.MeanAbsolutePercentageError")
|
2023-04-20 01:38:56 +00:00
|
|
|
class MeanAbsolutePercentageError(LossFunctionWrapper):
|
|
|
|
"""Computes the mean absolute percentage error between `y_true` & `y_pred`.
|
|
|
|
|
|
|
|
Formula:
|
|
|
|
|
2023-04-20 01:43:07 +00:00
|
|
|
```python
|
|
|
|
loss = 100 * mean(abs((y_true - y_pred) / y_true))
|
|
|
|
```
|
2023-04-20 01:38:56 +00:00
|
|
|
|
|
|
|
Args:
|
2023-05-01 17:21:40 +00:00
|
|
|
reduction: Type of reduction to apply to loss. For almost all cases
|
|
|
|
this defaults to `"sum_over_batch_size"`. Options are `"sum"`,
|
|
|
|
`"sum_over_batch_size"` or `None`.
|
|
|
|
name: Optional name for the instance.
|
2023-04-20 01:38:56 +00:00
|
|
|
"""
|
|
|
|
|
|
|
|
def __init__(
|
|
|
|
self,
|
|
|
|
reduction="sum_over_batch_size",
|
|
|
|
name="mean_absolute_percentage_error",
|
|
|
|
):
|
|
|
|
super().__init__(
|
|
|
|
mean_absolute_percentage_error, reduction=reduction, name=name
|
|
|
|
)
|
|
|
|
|
2023-04-25 04:21:57 +00:00
|
|
|
def get_config(self):
|
|
|
|
return Loss.get_config(self)
|
|
|
|
|
2023-04-20 01:38:56 +00:00
|
|
|
|
2023-04-21 20:59:07 +00:00
|
|
|
@keras_core_export("keras_core.losses.MeanSquaredLogarithmicError")
|
2023-04-20 01:38:56 +00:00
|
|
|
class MeanSquaredLogarithmicError(LossFunctionWrapper):
|
|
|
|
"""Computes the mean squared logarithmic error between `y_true` & `y_pred`.
|
|
|
|
|
2023-04-20 01:43:07 +00:00
|
|
|
Formula:
|
|
|
|
|
|
|
|
```python
|
|
|
|
loss = mean(square(log(y_true + 1) - log(y_pred + 1)))
|
|
|
|
```
|
2023-04-20 01:38:56 +00:00
|
|
|
|
|
|
|
Args:
|
2023-05-01 17:21:40 +00:00
|
|
|
reduction: Type of reduction to apply to loss. For almost all cases
|
|
|
|
this defaults to `"sum_over_batch_size"`. Options are `"sum"`,
|
|
|
|
`"sum_over_batch_size"` or `None`.
|
|
|
|
name: Optional name for the instance.
|
2023-04-20 01:38:56 +00:00
|
|
|
"""
|
|
|
|
|
|
|
|
def __init__(
|
|
|
|
self,
|
|
|
|
reduction="sum_over_batch_size",
|
|
|
|
name="mean_squared_logarithmic_error",
|
|
|
|
):
|
|
|
|
super().__init__(
|
|
|
|
mean_squared_logarithmic_error, reduction=reduction, name=name
|
|
|
|
)
|
|
|
|
|
2023-04-25 04:21:57 +00:00
|
|
|
def get_config(self):
|
|
|
|
return Loss.get_config(self)
|
|
|
|
|
2023-04-20 01:38:56 +00:00
|
|
|
|
2023-04-27 23:09:42 +00:00
|
|
|
@keras_core_export("keras_core.losses.CosineSimilarity")
|
|
|
|
class CosineSimilarity(LossFunctionWrapper):
|
|
|
|
"""Computes the cosine similarity between `y_true` & `y_pred`.
|
|
|
|
|
|
|
|
Note that it is a number between -1 and 1. When it is a negative number
|
|
|
|
between -1 and 0, 0 indicates orthogonality and values closer to -1
|
|
|
|
indicate greater similarity. This makes it usable as a loss function in a
|
|
|
|
setting where you try to maximize the proximity between predictions and
|
|
|
|
targets. If either `y_true` or `y_pred` is a zero vector, cosine similarity
|
|
|
|
will be 0 regardless of the proximity between predictions and targets.
|
|
|
|
|
|
|
|
Formula:
|
|
|
|
|
|
|
|
```python
|
|
|
|
loss = mean(square(log(y_true + 1) - log(y_pred + 1)))
|
|
|
|
```
|
|
|
|
|
|
|
|
Args:
|
|
|
|
axis: The axis along which the cosine similarity is computed
|
|
|
|
(the features axis). Defaults to -1.
|
2023-05-01 17:21:40 +00:00
|
|
|
reduction: Type of reduction to apply to loss. Options are `"sum"`,
|
|
|
|
`"sum_over_batch_size"` or `None`. Defaults to
|
|
|
|
`"sum_over_batch_size"`.
|
|
|
|
name: Optional name for the instance.
|
2023-04-27 23:09:42 +00:00
|
|
|
"""
|
|
|
|
|
|
|
|
def __init__(
|
|
|
|
self,
|
|
|
|
axis=-1,
|
|
|
|
reduction="sum_over_batch_size",
|
|
|
|
name="cosine_similarity",
|
|
|
|
):
|
|
|
|
super().__init__(
|
|
|
|
cosine_similarity, reduction=reduction, name=name, axis=axis
|
|
|
|
)
|
|
|
|
|
|
|
|
|
2023-04-23 21:02:44 +00:00
|
|
|
@keras_core_export("keras_core.losses.Hinge")
|
|
|
|
class Hinge(LossFunctionWrapper):
|
|
|
|
"""Computes the hinge loss between `y_true` & `y_pred`.
|
|
|
|
|
|
|
|
Formula:
|
|
|
|
|
|
|
|
```python
|
|
|
|
loss = maximum(1 - y_true * y_pred, 0)
|
|
|
|
```
|
|
|
|
|
|
|
|
`y_true` values are expected to be -1 or 1. If binary (0 or 1) labels are
|
|
|
|
provided we will convert them to -1 or 1.
|
|
|
|
|
|
|
|
Args:
|
2023-05-01 17:21:40 +00:00
|
|
|
reduction: Type of reduction to apply to loss. For almost all cases
|
|
|
|
this defaults to `"sum_over_batch_size"`. Options are `"sum"`,
|
|
|
|
`"sum_over_batch_size"` or `None`.
|
|
|
|
name: Optional name for the instance. Defaults to `"hinge"`
|
2023-04-23 21:02:44 +00:00
|
|
|
"""
|
|
|
|
|
|
|
|
def __init__(self, reduction="sum_over_batch_size", name="hinge"):
|
|
|
|
super().__init__(hinge, reduction=reduction, name=name)
|
|
|
|
|
2023-04-25 04:21:57 +00:00
|
|
|
def get_config(self):
|
|
|
|
return Loss.get_config(self)
|
|
|
|
|
2023-04-23 21:02:44 +00:00
|
|
|
|
|
|
|
@keras_core_export("keras_core.losses.SquaredHinge")
|
|
|
|
class SquaredHinge(LossFunctionWrapper):
|
|
|
|
"""Computes the squared hinge loss between `y_true` & `y_pred`.
|
|
|
|
|
|
|
|
Formula:
|
|
|
|
|
|
|
|
```python
|
|
|
|
loss = square(maximum(1 - y_true * y_pred, 0))
|
|
|
|
```
|
|
|
|
|
|
|
|
`y_true` values are expected to be -1 or 1. If binary (0 or 1) labels are
|
|
|
|
provided we will convert them to -1 or 1.
|
|
|
|
|
|
|
|
Args:
|
2023-05-01 17:21:40 +00:00
|
|
|
reduction: Type of reduction to apply to loss. For almost all cases
|
|
|
|
this defaults to `"sum_over_batch_size"`. Options are `"sum"`,
|
|
|
|
`"sum_over_batch_size"` or `None`.
|
|
|
|
name: Optional name for the instance. Defaults to `"squared_hinge"`
|
2023-04-23 21:02:44 +00:00
|
|
|
"""
|
|
|
|
|
|
|
|
def __init__(self, reduction="sum_over_batch_size", name="squared_hinge"):
|
|
|
|
super().__init__(squared_hinge, reduction=reduction, name=name)
|
|
|
|
|
2023-04-25 04:21:57 +00:00
|
|
|
def get_config(self):
|
|
|
|
return Loss.get_config(self)
|
|
|
|
|
2023-04-23 21:02:44 +00:00
|
|
|
|
|
|
|
@keras_core_export("keras_core.losses.CategoricalHinge")
|
|
|
|
class CategoricalHinge(LossFunctionWrapper):
|
|
|
|
"""Computes the categorical hinge loss between `y_true` & `y_pred`.
|
|
|
|
|
|
|
|
Formula:
|
|
|
|
|
|
|
|
```python
|
|
|
|
loss = maximum(neg - pos + 1, 0)
|
|
|
|
```
|
|
|
|
|
|
|
|
where `neg=maximum((1-y_true)*y_pred)` and `pos=sum(y_true*y_pred)`
|
|
|
|
|
|
|
|
Args:
|
2023-05-01 17:21:40 +00:00
|
|
|
reduction: Type of reduction to apply to loss. For almost all cases
|
|
|
|
this defaults to `"sum_over_batch_size"`. Options are `"sum"`,
|
|
|
|
`"sum_over_batch_size"` or `None`.
|
|
|
|
name: Optional name for the instance. Defaults to
|
|
|
|
`"categorical_hinge"`
|
2023-04-23 21:02:44 +00:00
|
|
|
"""
|
|
|
|
|
|
|
|
def __init__(
|
|
|
|
self, reduction="sum_over_batch_size", name="categorical_hinge"
|
|
|
|
):
|
|
|
|
super().__init__(categorical_hinge, reduction=reduction, name=name)
|
|
|
|
|
2023-04-25 04:21:57 +00:00
|
|
|
def get_config(self):
|
|
|
|
return Loss.get_config(self)
|
|
|
|
|
2023-04-23 21:02:44 +00:00
|
|
|
|
2023-05-01 03:09:49 +00:00
|
|
|
@keras_core_export("keras_core.losses.KLDivergence")
|
|
|
|
class KLDivergence(LossFunctionWrapper):
|
|
|
|
"""Computes Kullback-Leibler divergence loss between `y_true` & `y_pred`.
|
|
|
|
|
|
|
|
Formula:
|
|
|
|
|
|
|
|
```python
|
|
|
|
loss = y_true * log(y_true / y_pred)
|
|
|
|
```
|
|
|
|
|
|
|
|
Args:
|
2023-05-01 17:21:40 +00:00
|
|
|
reduction: Type of reduction to apply to loss. For almost all cases
|
|
|
|
this defaults to `"sum_over_batch_size"`. Options are `"sum"`,
|
|
|
|
`"sum_over_batch_size"` or `None`.
|
|
|
|
name: Optional name for the instance. Defaults to 'kl_divergence'.
|
2023-05-01 03:09:49 +00:00
|
|
|
"""
|
|
|
|
|
|
|
|
def __init__(self, reduction="sum_over_batch_size", name="kl_divergence"):
|
|
|
|
super().__init__(kl_divergence, reduction=reduction, name=name)
|
|
|
|
|
|
|
|
def get_config(self):
|
|
|
|
return Loss.get_config(self)
|
|
|
|
|
|
|
|
|
|
|
|
@keras_core_export("keras_core.losses.Poisson")
|
|
|
|
class Poisson(LossFunctionWrapper):
|
|
|
|
"""Computes the Poisson loss between `y_true` & `y_pred`.
|
|
|
|
|
|
|
|
Formula:
|
|
|
|
|
|
|
|
```python
|
|
|
|
loss = y_pred - y_true * log(y_pred)
|
|
|
|
```
|
|
|
|
|
|
|
|
Args:
|
2023-05-01 17:21:40 +00:00
|
|
|
reduction: Type of reduction to apply to loss. For almost all cases
|
|
|
|
this defaults to `"sum_over_batch_size"`. Options are `"sum"`,
|
|
|
|
`"sum_over_batch_size"` or `None`.
|
|
|
|
name: Optional name for the instance. Defaults to `"poisson"`
|
2023-05-01 03:09:49 +00:00
|
|
|
"""
|
|
|
|
|
|
|
|
def __init__(self, reduction="sum_over_batch_size", name="poisson"):
|
|
|
|
super().__init__(poisson, reduction=reduction, name=name)
|
|
|
|
|
|
|
|
def get_config(self):
|
|
|
|
return Loss.get_config(self)
|
|
|
|
|
|
|
|
|
2023-04-23 21:02:44 +00:00
|
|
|
def convert_binary_labels_to_hinge(y_true):
|
|
|
|
"""Converts binary labels into -1/1 for hinge loss/metric calculation."""
|
|
|
|
are_zeros = ops.equal(y_true, 0)
|
|
|
|
are_ones = ops.equal(y_true, 1)
|
|
|
|
is_binary = ops.all((ops.logical_or(are_zeros, are_ones)))
|
|
|
|
|
|
|
|
def _convert_binary_labels():
|
|
|
|
# Convert the binary labels to -1 or 1.
|
|
|
|
return 2.0 * y_true - 1.0
|
|
|
|
|
|
|
|
def _return_labels_unconverted():
|
|
|
|
# Returns the labels unchanged if they are non-binary
|
|
|
|
return y_true
|
|
|
|
|
|
|
|
updated_y_true = ops.cond(
|
|
|
|
is_binary, _convert_binary_labels, _return_labels_unconverted
|
|
|
|
)
|
|
|
|
return updated_y_true
|
|
|
|
|
|
|
|
|
|
|
|
@keras_core_export(
|
|
|
|
[
|
|
|
|
"keras_core.metrics.hinge",
|
|
|
|
"keras_core.losses.hinge",
|
|
|
|
]
|
|
|
|
)
|
|
|
|
def hinge(y_true, y_pred):
|
|
|
|
"""Computes the hinge loss between `y_true` & `y_pred`.
|
|
|
|
|
|
|
|
Formula:
|
|
|
|
|
|
|
|
```python
|
|
|
|
loss = mean(maximum(1 - y_true * y_pred, 0), axis=-1)
|
|
|
|
```
|
|
|
|
|
2023-05-01 17:21:40 +00:00
|
|
|
Standalone usage:
|
|
|
|
|
|
|
|
>>> y_true = np.random.choice([-1, 1], size=(2, 3))
|
|
|
|
>>> y_pred = np.random.random(size=(2, 3))
|
|
|
|
>>> loss = keras_core.losses.hinge(y_true, y_pred)
|
|
|
|
|
2023-04-23 21:02:44 +00:00
|
|
|
Args:
|
|
|
|
y_true: The ground truth values. `y_true` values are expected to be -1
|
|
|
|
or 1. If binary (0 or 1) labels are provided they will be converted
|
|
|
|
to -1 or 1 with shape = `[batch_size, d0, .. dN]`.
|
|
|
|
y_pred: The predicted values with shape = `[batch_size, d0, .. dN]`.
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
Hinge loss values with shape = `[batch_size, d0, .. dN-1]`.
|
|
|
|
"""
|
|
|
|
y_pred = ops.convert_to_tensor(y_pred)
|
|
|
|
y_true = ops.cast(y_true, dtype=y_pred.dtype)
|
|
|
|
y_true = ops.convert_to_tensor(y_true)
|
|
|
|
y_true = convert_binary_labels_to_hinge(y_true)
|
|
|
|
return ops.mean(ops.maximum(1.0 - y_true * y_pred, 0.0), axis=-1)
|
|
|
|
|
|
|
|
|
|
|
|
@keras_core_export(
|
|
|
|
[
|
|
|
|
"keras_core.metrics.squared_hinge",
|
|
|
|
"keras_core.losses.squared_hinge",
|
|
|
|
]
|
|
|
|
)
|
|
|
|
def squared_hinge(y_true, y_pred):
|
|
|
|
"""Computes the squared hinge loss between `y_true` & `y_pred`.
|
|
|
|
|
|
|
|
Formula:
|
|
|
|
|
|
|
|
```python
|
|
|
|
loss = mean(square(maximum(1 - y_true * y_pred, 0)), axis=-1)
|
|
|
|
```
|
|
|
|
|
2023-05-01 17:21:40 +00:00
|
|
|
Standalone usage:
|
|
|
|
|
|
|
|
>>> y_true = np.random.choice([-1, 1], size=(2, 3))
|
|
|
|
>>> y_pred = np.random.random(size=(2, 3))
|
|
|
|
>>> loss = keras_core.losses.squared_hinge(y_true, y_pred)
|
|
|
|
|
2023-04-23 21:02:44 +00:00
|
|
|
Args:
|
|
|
|
y_true: The ground truth values. `y_true` values are expected to be -1
|
|
|
|
or 1. If binary (0 or 1) labels are provided we will convert them
|
|
|
|
to -1 or 1 with shape = `[batch_size, d0, .. dN]`.
|
|
|
|
y_pred: The predicted values with shape = `[batch_size, d0, .. dN]`.
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
Squared hinge loss values with shape = `[batch_size, d0, .. dN-1]`.
|
|
|
|
"""
|
|
|
|
y_pred = ops.convert_to_tensor(y_pred)
|
|
|
|
y_true = ops.cast(y_true, y_pred.dtype)
|
|
|
|
y_true = convert_binary_labels_to_hinge(y_true)
|
|
|
|
return ops.mean(
|
|
|
|
ops.square(ops.maximum(1.0 - y_true * y_pred, 0.0)), axis=-1
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
@keras_core_export(
|
|
|
|
[
|
|
|
|
"keras_core.metrics.categorical_hinge",
|
|
|
|
"keras_core.losses.categorical_hinge",
|
|
|
|
]
|
|
|
|
)
|
|
|
|
def categorical_hinge(y_true, y_pred):
|
|
|
|
"""Computes the categorical hinge loss between `y_true` & `y_pred`.
|
|
|
|
|
|
|
|
Formula:
|
|
|
|
|
|
|
|
```python
|
|
|
|
loss = maximum(neg - pos + 1, 0)
|
|
|
|
```
|
|
|
|
|
|
|
|
where `neg=maximum((1-y_true)*y_pred)` and `pos=sum(y_true*y_pred)`
|
|
|
|
|
2023-05-01 17:21:40 +00:00
|
|
|
Standalone usage:
|
|
|
|
|
|
|
|
>>> y_true = np.random.randint(0, 3, size=(2,))
|
|
|
|
>>> y_true = np.eye(np.max(y_true) + 1)[y_true]
|
|
|
|
>>> y_pred = np.random.random(size=(2, 3))
|
|
|
|
>>> loss = keras_core.losses.categorical_hinge(y_true, y_pred)
|
|
|
|
|
2023-04-23 21:02:44 +00:00
|
|
|
Args:
|
|
|
|
y_true: The ground truth values. `y_true` values are expected to be
|
|
|
|
either `{-1, +1}` or `{0, 1}` (i.e. a one-hot-encoded tensor) with
|
|
|
|
shape = `[batch_size, d0, .. dN]`.
|
|
|
|
y_pred: The predicted values with shape = `[batch_size, d0, .. dN]`.
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
Categorical hinge loss values with shape = `[batch_size, d0, .. dN-1]`.
|
|
|
|
"""
|
|
|
|
y_pred = ops.convert_to_tensor(y_pred)
|
|
|
|
y_true = ops.cast(y_true, y_pred.dtype)
|
|
|
|
pos = ops.sum(y_true * y_pred, axis=-1)
|
|
|
|
neg = ops.max((1.0 - y_true) * y_pred, axis=-1)
|
|
|
|
zero = ops.cast(0.0, y_pred.dtype)
|
|
|
|
return ops.maximum(neg - pos + 1.0, zero)
|
|
|
|
|
|
|
|
|
2023-04-21 20:59:07 +00:00
|
|
|
@keras_core_export(
|
2023-04-21 22:01:17 +00:00
|
|
|
[
|
|
|
|
"keras_core.metrics.mean_squared_error",
|
|
|
|
"keras_core.losses.mean_squared_error",
|
|
|
|
]
|
2023-04-21 20:59:07 +00:00
|
|
|
)
|
2023-04-19 04:18:20 +00:00
|
|
|
def mean_squared_error(y_true, y_pred):
|
|
|
|
"""Computes the mean squared error between labels and predictions.
|
|
|
|
|
2023-04-20 01:43:07 +00:00
|
|
|
Formula:
|
2023-04-19 04:18:20 +00:00
|
|
|
|
2023-04-20 01:43:07 +00:00
|
|
|
```python
|
|
|
|
loss = mean(square(y_true - y_pred), axis=-1)
|
|
|
|
```
|
2023-04-19 04:18:20 +00:00
|
|
|
|
|
|
|
Standalone usage:
|
|
|
|
|
|
|
|
>>> y_true = np.random.randint(0, 2, size=(2, 3))
|
|
|
|
>>> y_pred = np.random.random(size=(2, 3))
|
|
|
|
>>> loss = keras_core.losses.mean_squared_error(y_true, y_pred)
|
|
|
|
|
|
|
|
Args:
|
|
|
|
y_true: Ground truth values with shape = `[batch_size, d0, .. dN]`.
|
|
|
|
y_pred: The predicted values with shape = `[batch_size, d0, .. dN]`.
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
Mean squared error values with shape = `[batch_size, d0, .. dN-1]`.
|
|
|
|
"""
|
|
|
|
y_pred = ops.convert_to_tensor(y_pred)
|
|
|
|
y_true = ops.convert_to_tensor(y_true, dtype=y_pred.dtype)
|
|
|
|
y_true, y_pred = squeeze_to_same_rank(y_true, y_pred)
|
|
|
|
return ops.mean(ops.square(y_true - y_pred), axis=-1)
|
|
|
|
|
|
|
|
|
2023-04-21 20:59:07 +00:00
|
|
|
@keras_core_export(
|
2023-04-21 22:01:17 +00:00
|
|
|
[
|
|
|
|
"keras_core.metrics.mean_absolute_error",
|
|
|
|
"keras_core.losses.mean_absolute_error",
|
|
|
|
]
|
2023-04-21 20:59:07 +00:00
|
|
|
)
|
2023-04-19 04:18:20 +00:00
|
|
|
def mean_absolute_error(y_true, y_pred):
|
|
|
|
"""Computes the mean absolute error between labels and predictions.
|
|
|
|
|
2023-04-20 01:43:07 +00:00
|
|
|
```python
|
|
|
|
loss = mean(abs(y_true - y_pred), axis=-1)
|
|
|
|
```
|
2023-04-19 04:18:20 +00:00
|
|
|
|
2023-05-01 17:21:40 +00:00
|
|
|
Standalone usage:
|
|
|
|
|
|
|
|
>>> y_true = np.random.randint(0, 2, size=(2, 3))
|
|
|
|
>>> y_pred = np.random.random(size=(2, 3))
|
|
|
|
>>> loss = keras_core.losses.mean_absolute_error(y_true, y_pred)
|
|
|
|
|
2023-04-19 04:18:20 +00:00
|
|
|
Args:
|
|
|
|
y_true: Ground truth values with shape = `[batch_size, d0, .. dN]`.
|
|
|
|
y_pred: The predicted values with shape = `[batch_size, d0, .. dN]`.
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
Mean absolute error values with shape = `[batch_size, d0, .. dN-1]`.
|
|
|
|
"""
|
|
|
|
y_pred = ops.convert_to_tensor(y_pred)
|
|
|
|
y_true = ops.convert_to_tensor(y_true, dtype=y_pred.dtype)
|
|
|
|
y_true, y_pred = squeeze_to_same_rank(y_true, y_pred)
|
|
|
|
return ops.mean(ops.abs(y_true - y_pred), axis=-1)
|
2023-04-20 01:38:56 +00:00
|
|
|
|
|
|
|
|
2023-04-21 20:59:07 +00:00
|
|
|
@keras_core_export(
|
2023-04-21 22:01:17 +00:00
|
|
|
[
|
|
|
|
"keras_core.metrics.mean_absolute_percentage_error",
|
|
|
|
"keras_core.losses.mean_absolute_percentage_error",
|
|
|
|
]
|
2023-04-21 20:59:07 +00:00
|
|
|
)
|
2023-04-20 01:38:56 +00:00
|
|
|
def mean_absolute_percentage_error(y_true, y_pred):
|
|
|
|
"""Computes the mean absolute percentage error between `y_true` & `y_pred`.
|
|
|
|
|
2023-05-01 17:21:40 +00:00
|
|
|
`loss = 100 * mean(abs((y_true - y_pred) / y_true), axis=-1)`
|
2023-04-20 01:38:56 +00:00
|
|
|
|
|
|
|
Division by zero is prevented by dividing by `maximum(y_true, epsilon)`
|
2023-04-20 01:43:07 +00:00
|
|
|
where `epsilon = keras_core.backend.epsilon()`
|
|
|
|
(default to `1e-7`).
|
2023-04-20 01:38:56 +00:00
|
|
|
|
2023-05-01 17:21:40 +00:00
|
|
|
Standalone usage:
|
|
|
|
|
|
|
|
>>> y_true = np.random.random(size=(2, 3))
|
|
|
|
>>> y_pred = np.random.random(size=(2, 3))
|
|
|
|
>>> loss = keras_core.losses.mean_absolute_percentage_error(y_true, y_pred)
|
|
|
|
|
2023-04-20 01:38:56 +00:00
|
|
|
Args:
|
|
|
|
y_true: Ground truth values with shape = `[batch_size, d0, .. dN]`.
|
|
|
|
y_pred: The predicted values with shape = `[batch_size, d0, .. dN]`.
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
Mean absolute percentage error values with shape = `[batch_size, d0, ..
|
|
|
|
dN-1]`.
|
|
|
|
"""
|
|
|
|
epsilon = ops.convert_to_tensor(backend.epsilon())
|
|
|
|
y_pred = ops.convert_to_tensor(y_pred)
|
|
|
|
y_true = ops.convert_to_tensor(y_true, dtype=y_pred.dtype)
|
|
|
|
y_true, y_pred = squeeze_to_same_rank(y_true, y_pred)
|
|
|
|
diff = ops.abs((y_true - y_pred) / ops.maximum(ops.abs(y_true), epsilon))
|
|
|
|
return 100.0 * ops.mean(diff, axis=-1)
|
|
|
|
|
|
|
|
|
2023-04-21 20:59:07 +00:00
|
|
|
@keras_core_export(
|
2023-04-21 22:01:17 +00:00
|
|
|
[
|
|
|
|
"keras_core.metrics.mean_squared_logarithmic_error",
|
|
|
|
"keras_core.losses.mean_squared_logarithmic_error",
|
|
|
|
]
|
2023-04-21 20:59:07 +00:00
|
|
|
)
|
2023-04-20 01:38:56 +00:00
|
|
|
def mean_squared_logarithmic_error(y_true, y_pred):
|
|
|
|
"""Computes the mean squared logarithmic error between `y_true` & `y_pred`.
|
|
|
|
|
2023-04-20 01:43:07 +00:00
|
|
|
Formula:
|
|
|
|
|
|
|
|
```python
|
|
|
|
loss = mean(square(log(y_true + 1) - log(y_pred + 1)), axis=-1)
|
|
|
|
```
|
2023-04-20 01:38:56 +00:00
|
|
|
|
|
|
|
Note that `y_pred` and `y_true` cannot be less or equal to 0. Negative
|
|
|
|
values and 0 values will be replaced with `keras_core.backend.epsilon()`
|
|
|
|
(default to `1e-7`).
|
|
|
|
|
2023-05-01 17:21:40 +00:00
|
|
|
Standalone usage:
|
|
|
|
|
|
|
|
>>> y_true = np.random.randint(0, 2, size=(2, 3))
|
|
|
|
>>> y_pred = np.random.random(size=(2, 3))
|
|
|
|
>>> loss = keras_core.losses.mean_squared_logarithmic_error(y_true, y_pred)
|
|
|
|
|
2023-04-20 01:38:56 +00:00
|
|
|
Args:
|
|
|
|
y_true: Ground truth values with shape = `[batch_size, d0, .. dN]`.
|
|
|
|
y_pred: The predicted values with shape = `[batch_size, d0, .. dN]`.
|
|
|
|
|
|
|
|
Returns:
|
2023-05-01 17:21:40 +00:00
|
|
|
Mean squared logarithmic error values. shape = `[batch_size, d0, ..
|
2023-04-20 01:38:56 +00:00
|
|
|
dN-1]`.
|
|
|
|
"""
|
|
|
|
epsilon = ops.convert_to_tensor(backend.epsilon())
|
|
|
|
y_pred = ops.convert_to_tensor(y_pred)
|
|
|
|
y_true = ops.convert_to_tensor(y_true, dtype=y_pred.dtype)
|
|
|
|
y_true, y_pred = squeeze_to_same_rank(y_true, y_pred)
|
|
|
|
first_log = ops.log(ops.maximum(y_pred, epsilon) + 1.0)
|
|
|
|
second_log = ops.log(ops.maximum(y_true, epsilon) + 1.0)
|
|
|
|
return ops.mean(ops.square(first_log - second_log), axis=-1)
|
2023-04-27 23:09:42 +00:00
|
|
|
|
|
|
|
|
|
|
|
@keras_core_export("keras_core.losses.cosine_similarity")
|
|
|
|
def cosine_similarity(y_true, y_pred, axis=-1):
|
|
|
|
"""Computes the cosine similarity between labels and predictions.
|
|
|
|
|
|
|
|
Formula:
|
|
|
|
```python
|
|
|
|
loss = -sum(l2_norm(y_true) * l2_norm(y_pred))
|
|
|
|
```
|
|
|
|
|
|
|
|
Note that it is a number between -1 and 1. When it is a negative number
|
|
|
|
between -1 and 0, 0 indicates orthogonality and values closer to -1
|
|
|
|
indicate greater similarity. This makes it usable as a loss function in a
|
|
|
|
setting where you try to maximize the proximity between predictions and
|
|
|
|
targets. If either `y_true` or `y_pred` is a zero vector, cosine
|
|
|
|
similarity will be 0 regardless of the proximity between predictions
|
|
|
|
and targets.
|
|
|
|
|
2023-05-01 17:21:40 +00:00
|
|
|
Standalone usage:
|
|
|
|
>>> y_true = [[0., 1.], [1., 1.], [1., 1.]]
|
|
|
|
>>> y_pred = [[1., 0.], [1., 1.], [-1., -1.]]
|
|
|
|
>>> loss = keras_core.losses.cosine_similarity(y_true, y_pred, axis=-1)
|
|
|
|
[-0., -0.99999994, 0.99999994]
|
|
|
|
|
2023-04-27 23:09:42 +00:00
|
|
|
Args:
|
|
|
|
y_true: Tensor of true targets.
|
|
|
|
y_pred: Tensor of predicted targets.
|
|
|
|
axis: Axis along which to determine similarity. Defaults to -1.
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
Cosine similarity tensor.
|
|
|
|
"""
|
|
|
|
y_pred = ops.convert_to_tensor(y_pred)
|
|
|
|
y_true = ops.convert_to_tensor(y_true, dtype=y_pred.dtype)
|
|
|
|
y_true, y_pred = squeeze_to_same_rank(y_true, y_pred)
|
2023-04-29 22:08:38 +00:00
|
|
|
y_pred = normalize(y_pred, axis=axis)
|
|
|
|
y_true = normalize(y_true, axis=axis)
|
2023-04-27 23:09:42 +00:00
|
|
|
return -ops.sum(y_true * y_pred, axis=axis)
|
2023-05-01 03:09:49 +00:00
|
|
|
|
|
|
|
|
|
|
|
@keras_core_export(
|
|
|
|
[
|
|
|
|
"keras_core.metrics.kl_divergence",
|
|
|
|
"keras_core.losses.kl_divergence",
|
|
|
|
]
|
|
|
|
)
|
|
|
|
def kl_divergence(y_true, y_pred):
|
|
|
|
"""Computes Kullback-Leibler divergence loss between `y_true` & `y_pred`.
|
|
|
|
|
|
|
|
Formula:
|
|
|
|
|
|
|
|
```python
|
|
|
|
loss = y_true * log(y_true / y_pred)
|
|
|
|
```
|
|
|
|
|
2023-05-01 17:21:40 +00:00
|
|
|
Standalone usage:
|
2023-05-01 03:09:49 +00:00
|
|
|
|
|
|
|
>>> y_true = np.random.randint(0, 2, size=(2, 3)).astype(np.float32)
|
|
|
|
>>> y_pred = np.random.random(size=(2, 3))
|
|
|
|
>>> loss = keras_core.losses.kl_divergence(y_true, y_pred)
|
|
|
|
>>> assert loss.shape == (2,)
|
|
|
|
>>> y_true = ops.clip(y_true, 1e-7, 1)
|
|
|
|
>>> y_pred = ops.clip(y_pred, 1e-7, 1)
|
|
|
|
>>> assert np.array_equal(
|
|
|
|
... loss, np.sum(y_true * np.log(y_true / y_pred), axis=-1))
|
2023-05-01 17:21:40 +00:00
|
|
|
|
|
|
|
Args:
|
|
|
|
y_true: Tensor of true targets.
|
|
|
|
y_pred: Tensor of predicted targets.
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
KL Divergence loss values with shape = `[batch_size, d0, .. dN-1]`.
|
2023-05-01 03:09:49 +00:00
|
|
|
"""
|
|
|
|
y_pred = ops.convert_to_tensor(y_pred)
|
|
|
|
y_true = ops.convert_to_tensor(y_true, y_pred.dtype)
|
|
|
|
y_true = ops.clip(y_true, backend.epsilon(), 1)
|
|
|
|
y_pred = ops.clip(y_pred, backend.epsilon(), 1)
|
|
|
|
return ops.sum(y_true * ops.log(y_true / y_pred), axis=-1)
|
|
|
|
|
|
|
|
|
|
|
|
@keras_core_export(
|
|
|
|
[
|
|
|
|
"keras_core.metrics.poisson",
|
|
|
|
"keras_core.losses.poisson",
|
|
|
|
]
|
|
|
|
)
|
|
|
|
def poisson(y_true, y_pred):
|
|
|
|
"""Computes the Poisson loss between y_true and y_pred.
|
|
|
|
|
|
|
|
Formula:
|
|
|
|
|
|
|
|
```python
|
|
|
|
loss = y_pred - y_true * log(y_pred)
|
|
|
|
```
|
|
|
|
|
2023-05-01 17:21:40 +00:00
|
|
|
Standalone usage:
|
2023-05-01 03:09:49 +00:00
|
|
|
|
|
|
|
>>> y_true = np.random.randint(0, 2, size=(2, 3))
|
|
|
|
>>> y_pred = np.random.random(size=(2, 3))
|
|
|
|
>>> loss = keras_core.losses.poisson(y_true, y_pred)
|
|
|
|
>>> assert loss.shape == (2,)
|
|
|
|
>>> y_pred = y_pred + 1e-7
|
|
|
|
>>> assert np.allclose(
|
|
|
|
... loss, np.mean(y_pred - y_true * np.log(y_pred), axis=-1),
|
|
|
|
... atol=1e-5)
|
|
|
|
|
|
|
|
Args:
|
|
|
|
y_true: Ground truth values. shape = `[batch_size, d0, .. dN]`.
|
|
|
|
y_pred: The predicted values. shape = `[batch_size, d0, .. dN]`.
|
2023-05-01 03:51:50 +00:00
|
|
|
|
|
|
|
Returns:
|
2023-05-01 17:21:40 +00:00
|
|
|
Poisson loss values with shape = `[batch_size, d0, .. dN-1]`.
|
2023-05-01 03:51:50 +00:00
|
|
|
"""
|
|
|
|
y_pred = ops.convert_to_tensor(y_pred)
|
2023-05-01 17:21:40 +00:00
|
|
|
y_true = ops.convert_to_tensor(y_true, dtype=y_pred.dtype)
|
|
|
|
epsilon = ops.convert_to_tensor(backend.epsilon())
|
|
|
|
return ops.mean(y_pred - y_true * ops.log(y_pred + epsilon), axis=-1)
|