Source code for pyml.neural_network.loss.binary_cross_entropy

"""
Module defining the Binary Cross-Entropy class for binary classification tasks.

This module contains the implementation of the BinaryCrossentropy class,
which represents a loss function for binary classification problems. It provides
methods for both the forward and backward pass computations of the Binary Cross-Entropy loss.
"""

from pyml.neural_network.loss import _Loss
import numpy as np

# Binary cross-entropy loss
[docs]class BinaryCrossentropy(_Loss): """Binary Cross-Entropy loss function for binary classification tasks. This class defines the forward and backward pass computations for calculating the Binary 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 Binary Cross-Entropy loss. Parameters ---------- y_pred : numpy.ndarray Predicted output from the model, representing class probabilities. y_true : numpy.ndarray Ground truth values, containing binary labels. Returns ------- numpy.ndarray Array of sample-wise binary cross-entropy losses. """ # 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) # Calculate sample-wise loss sample_losses = -(y_true * np.log(y_pred_clipped) + (1 - y_true) * np.log(1 - y_pred_clipped)) sample_losses = np.mean(sample_losses, axis=-1) # Return losses return sample_losses
# 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 binary labels. """ # Number of samples samples = len(dvalues) # Number of outputs in every sample # We'll use the first sample to count them outputs = len(dvalues[0]) # Clip data to prevent division by 0 # Clip both sides to not drag mean towards any value clipped_dvalues = np.clip(dvalues, 1e-7, 1 - 1e-7) # Calculate gradient self.dinputs = -(y_true / clipped_dvalues - (1 - y_true) / (1 - clipped_dvalues)) / outputs # Normalize gradient self.dinputs = self.dinputs / samples