Source code for pyml.neural_network.loss.categorical_cross_entropy
"""Module defining the Categorical Cross-Entropy class for multi-class classification tasks.
This module contains the implementation of the CategoricalCrossentropy class,
which represents a loss function for multi-class classification problems. It provides
methods for both the forward and backward pass computations of the Categorical Cross-Entropy loss.
"""
from pyml.neural_network.loss import _Loss
import numpy as np
[docs]class CategoricalCrossentropy(_Loss):
"""Categorical Cross-Entropy loss function for multi-class classification tasks.
This class defines the forward and backward pass computations for calculating
the Categorical Cross-Entropy loss and its gradient with respect to the predicted values.
Attributes
----------
dinputs : numpy.ndarray
Gradient of the loss with respect to the predicted values.
"""
# Forward pass
[docs] def forward(self, y_pred:np.ndarray, y_true:np.ndarray) -> np.ndarray:
"""Compute the forward pass of the Categorical Cross-Entropy loss.
Parameters
----------
y_pred : numpy.ndarray
Predicted output from the model, representing class probabilities.
y_true : numpy.ndarray
Ground truth values, containing integer class labels or one-hot encoded vectors.
Returns
-------
numpy.ndarray
Array of negative log-likelihoods for each sample.
"""
# Number of samples in a batch
samples = len(y_pred)
# Clip data to prevent division by 0
# Clip both sides to not drag mean towards any value
y_pred_clipped = np.clip(y_pred, 1e-7, 1 - 1e-7)
# Probabilities for target values -
# only if categorical labels
if len(y_true.shape) == 1:
correct_confidences = y_pred_clipped[
range(samples),
y_true
]
# Mask values - only for one-hot encoded labels
elif len(y_true.shape) == 2:
correct_confidences = np.sum(
y_pred_clipped * y_true,
axis=1
)
# Losses
negative_log_likelihoods = -np.log(correct_confidences)
return negative_log_likelihoods
# Backward pass
[docs] def backward(self, dvalues:np.ndarray, y_true:np.ndarray) -> None:
"""Compute the backward pass to calculate the gradient of the loss with respect to the predicted values.
Parameters
----------
dvalues : numpy.ndarray
Gradient of the loss with respect to the predicted values.
y_true : numpy.ndarray
Ground truth values, containing integer class labels or one-hot encoded vectors.
"""
# Number of samples
samples = len(dvalues)
# Number of labels in every sample
# We'll use the first sample to count them
labels = len(dvalues[0])
# If labels are sparse, turn them into one-hot vector
if len(y_true.shape) == 1:
y_true = np.eye(labels)[y_true]
# Calculate gradient
self.dinputs = -y_true / dvalues
# Normalize gradient
self.dinputs = self.dinputs / samples