Skip to content

Commit 321aa89

Browse files
committed
Add Gaussian negative log likelihood loss algorithm
1 parent c1d29ba commit 321aa89

1 file changed

Lines changed: 54 additions & 0 deletions

File tree

machine_learning/loss_functions.py

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,60 @@ def categorical_focal_cross_entropy(
250250
return np.mean(cfce_loss)
251251

252252

253+
def gaussian_negative_log_likelihood_loss(
254+
y_true: np.ndarray,
255+
expectation_pred: np.ndarray,
256+
var_pred: np.ndarray,
257+
eps: float = 1e-6,
258+
) -> float:
259+
"""
260+
Calculate the negative log likelihood (NLL) loss between true labels and predicted
261+
Gaussian distributions.
262+
263+
NLL = -Σ(ln(1/(σ√(2π))) - 0.5 * ((y_true - μ)/σ)^2)
264+
265+
Reference: https://pytorch.org/docs/stable/generated/torch.nn.GaussianNLLLoss.html
266+
267+
Parameters:
268+
- y_true: True labels
269+
- expectation_pred: Predicted expectation (μ) of the Gaussian distribution
270+
- var_pred: Predicted variance (σ^2) of the Gaussian distribution
271+
- eps: Small constant to avoid numerical instability
272+
273+
Examples:
274+
>>> true_labels = np.array([1.0, 2.0, 3.0, 4.0, 5.0])
275+
>>> expectation = np.array([0.8, 2.1, 2.9, 4.2, 5.2])
276+
>>> variance = np.array([0.1, 0.2, 0.3, 0.4, 0.5])
277+
>>> loss = gaussian_negative_log_likelihood_loss(true_labels, expectation, variance)
278+
>>> np.isclose(loss, -0.60621)
279+
True
280+
281+
>>> true_labels = np.array([1.0, 2.0, 3.0, 4.0, 5.0])
282+
>>> expectation = np.array([0.8, 2.1, 2.9, 4.2, 5.2])
283+
>>> variance = np.array([0.1, 0.2, 0.3, 0.4])
284+
>>> gaussian_negative_log_likelihood_loss(true_labels, expectation, variance)
285+
Traceback (most recent call last):
286+
...
287+
ValueError: Input arrays must have the same length.
288+
"""
289+
290+
if (
291+
len(y_true) != len(expectation_pred)
292+
or len(y_true) != len(var_pred)
293+
or len(expectation_pred) != len(var_pred)
294+
):
295+
raise ValueError("Input arrays must have the same length.")
296+
297+
# The constant term `0.5 * np.log(2 * np.pi)` is ignored since it doesn't affect the
298+
# optimization. PyTorch also ignores this term by default.
299+
# See https://pytorch.org/docs/stable/generated/torch.nn.GaussianNLLLoss.html
300+
loss_var = 0.5 * (np.log(np.maximum(var_pred, eps)))
301+
loss_exp = 0.5 * (np.square(y_true - expectation_pred) / np.maximum(var_pred, eps))
302+
loss = loss_var + loss_exp
303+
304+
return np.mean(loss)
305+
306+
253307
def hinge_loss(y_true: np.ndarray, y_pred: np.ndarray) -> float:
254308
"""
255309
Calculate the mean hinge loss for between true labels and predicted probabilities

0 commit comments

Comments
 (0)