use crate::error::Error;
use crate::neural_network::Tensor;
use crate::neural_network::losses::validate_same_shape;
use crate::neural_network::traits::Loss;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub struct MeanAbsoluteError;
impl MeanAbsoluteError {
pub fn new() -> Self {
Self {}
}
}
impl Loss for MeanAbsoluteError {
fn compute_loss(&self, y_true: &Tensor, y_pred: &Tensor) -> Result<f32, Error> {
validate_same_shape(y_true, y_pred)?;
let mut diff = y_pred - y_true;
diff.par_mapv_inplace(|x| x.abs());
Ok(diff.sum() / (y_true.len() as f32))
}
fn compute_grad(&self, y_true: &Tensor, y_pred: &Tensor) -> Result<Tensor, Error> {
validate_same_shape(y_true, y_pred)?;
let n = y_true.len() as f32;
let mut result = y_pred - y_true;
result.par_mapv_inplace(|x| {
if x > 0.0 {
1.0 / n
} else if x < 0.0 {
-1.0 / n
} else if x == 0.0 {
0.0
} else {
f32::NAN
}
});
Ok(result)
}
}