Skip to main content

sklears_multioutput/
loss.rs

1//! Loss functions for neural network training
2//!
3//! This module provides various loss functions commonly used in neural network training,
4//! including Mean Squared Error for regression and Cross-Entropy for classification.
5
6// Use SciRS2-Core for arrays (SciRS2 Policy)
7use scirs2_core::ndarray::Array2;
8use sklears_core::types::Float;
9
10/// Loss functions for neural network training
11#[derive(Debug, Clone, Copy, PartialEq)]
12pub enum LossFunction {
13    /// Mean squared error for regression
14    MeanSquaredError,
15    /// Cross-entropy for classification
16    CrossEntropy,
17    /// Binary cross-entropy for multi-label classification
18    BinaryCrossEntropy,
19}
20
21impl LossFunction {
22    /// Compute loss between predictions and targets
23    pub fn compute_loss(&self, y_pred: &Array2<Float>, y_true: &Array2<Float>) -> Float {
24        match self {
25            LossFunction::MeanSquaredError => {
26                let diff = y_pred - y_true;
27                diff.map(|x| x * x)
28                    .mean()
29                    .expect("array should have elements for mean computation")
30            }
31            LossFunction::CrossEntropy => {
32                let mut total_loss = 0.0;
33                for i in 0..y_pred.nrows() {
34                    for j in 0..y_pred.ncols() {
35                        let pred = y_pred[[i, j]].clamp(1e-15, 1.0 - 1e-15); // Clip for numerical stability
36                        total_loss -= y_true[[i, j]] * pred.ln();
37                    }
38                }
39                total_loss / (y_pred.nrows() as Float)
40            }
41            LossFunction::BinaryCrossEntropy => {
42                let mut total_loss = 0.0;
43                for i in 0..y_pred.nrows() {
44                    for j in 0..y_pred.ncols() {
45                        let pred = y_pred[[i, j]].clamp(1e-15, 1.0 - 1e-15); // Clip for numerical stability
46                        total_loss -=
47                            y_true[[i, j]] * pred.ln() + (1.0 - y_true[[i, j]]) * (1.0 - pred).ln();
48                    }
49                }
50                total_loss / (y_pred.nrows() as Float * y_pred.ncols() as Float)
51            }
52        }
53    }
54}