|
| 1 | +# ruff: noqa: RUF002 -- ambiguous-unicode-character-docstring |
| 2 | + |
1 | 3 | import numpy as np |
2 | 4 |
|
3 | 5 |
|
@@ -302,6 +304,60 @@ def categorical_focal_cross_entropy( |
302 | 304 | return np.mean(cfce_loss) |
303 | 305 |
|
304 | 306 |
|
| 307 | +def gaussian_negative_log_likelihood_loss( |
| 308 | + y_true: np.ndarray, |
| 309 | + expectation_pred: np.ndarray, |
| 310 | + var_pred: np.ndarray, |
| 311 | + eps: float = 1e-6, |
| 312 | +) -> float: |
| 313 | + """ |
| 314 | + Calculate the negative log likelihood (NLL) loss between true labels and predicted |
| 315 | + Gaussian distributions. |
| 316 | +
|
| 317 | + NLL = -Σ(ln(1/(σ√(2π))) - 0.5 * ((y_true - μ)/σ)^2) |
| 318 | +
|
| 319 | + Reference: https://pytorch.org/docs/stable/generated/torch.nn.GaussianNLLLoss.html |
| 320 | +
|
| 321 | + Parameters: |
| 322 | + - y_true: True labels |
| 323 | + - expectation_pred: Predicted expectation (μ) of the Gaussian distribution |
| 324 | + - var_pred: Predicted variance (σ^2) of the Gaussian distribution |
| 325 | + - eps: Small constant to avoid numerical instability |
| 326 | +
|
| 327 | + Examples: |
| 328 | + >>> true_labels = np.array([1.0, 2.0, 3.0, 4.0, 5.0]) |
| 329 | + >>> expectation = np.array([0.8, 2.1, 2.9, 4.2, 5.2]) |
| 330 | + >>> variance = np.array([0.1, 0.2, 0.3, 0.4, 0.5]) |
| 331 | + >>> loss = gaussian_negative_log_likelihood_loss(true_labels, expectation, variance) |
| 332 | + >>> bool(np.isclose(loss, -0.60621)) |
| 333 | + True |
| 334 | +
|
| 335 | + >>> true_labels = np.array([1.0, 2.0, 3.0, 4.0, 5.0]) |
| 336 | + >>> expectation = np.array([0.8, 2.1, 2.9, 4.2, 5.2]) |
| 337 | + >>> variance = np.array([0.1, 0.2, 0.3, 0.4]) |
| 338 | + >>> gaussian_negative_log_likelihood_loss(true_labels, expectation, variance) |
| 339 | + Traceback (most recent call last): |
| 340 | + ... |
| 341 | + ValueError: Input arrays must have the same length. |
| 342 | + """ |
| 343 | + |
| 344 | + if ( |
| 345 | + len(y_true) != len(expectation_pred) |
| 346 | + or len(y_true) != len(var_pred) |
| 347 | + or len(expectation_pred) != len(var_pred) |
| 348 | + ): |
| 349 | + raise ValueError("Input arrays must have the same length.") |
| 350 | + |
| 351 | + # The constant term `0.5 * np.log(2 * np.pi)` is ignored since it doesn't affect the |
| 352 | + # optimization. PyTorch also ignores this term by default. |
| 353 | + # See https://pytorch.org/docs/stable/generated/torch.nn.GaussianNLLLoss.html |
| 354 | + loss_var = 0.5 * (np.log(np.maximum(var_pred, eps))) |
| 355 | + loss_exp = 0.5 * (np.square(y_true - expectation_pred) / np.maximum(var_pred, eps)) |
| 356 | + loss = loss_var + loss_exp |
| 357 | + |
| 358 | + return np.mean(loss) |
| 359 | + |
| 360 | + |
305 | 361 | def hinge_loss(y_true: np.ndarray, y_pred: np.ndarray) -> float: |
306 | 362 | """ |
307 | 363 | Calculate the mean hinge loss for between true labels and predicted probabilities |
|
0 commit comments