meuron 0.4.0

Meuron is a modular neural network library written in rust for training simple neural networks.
Documentation
use crate::NeuralNetwork;
use crate::backend::Backend;
use crate::cost::Cost;
use crate::layer::Layer;
use ndarray::{Array, Axis, Dimension};
use serde::{Deserialize, Serialize};

pub trait Forward<B: Backend> {
    type Input: Dimension;
    type Output: Dimension;
    fn run(&mut self, x: &B::Tensor<Self::Input>) -> B::Tensor<Self::Output>;
}

impl<L, C, B> Forward<B> for NeuralNetwork<L, C, B>
where
    B: Backend,
    L: Layer<B> + Serialize + for<'de> Deserialize<'de>,
    C: Cost<B>,
{
    type Input = L::Input;
    type Output = L::Output;

    fn run(&mut self, x: &B::Tensor<L::Input>) -> B::Tensor<L::Output> {
        self.forward(x.clone())
    }
}

pub fn accuracy<B, N, I, T>(network: &mut N, test_data: I, test_labels: T) -> f32
where
    B: Backend,
    N: Forward<B>,
    I: Into<B::Tensor<N::Input>>,
    T: Into<Array<f32, N::Output>>,
{
    let test_data = test_data.into();
    let test_labels = test_labels.into();

    let predictions = network.run(&test_data);
    let pred_arr = B::to_array(&predictions).into_dyn();
    let label_arr = test_labels.into_dyn();

    let n = pred_arr.shape()[0];
    assert_eq!(n, label_arr.shape()[0], "shape mismatch");

    let argmax = |row: ndarray::ArrayView1<f32>| -> f32 {
        row.iter()
            .enumerate()
            .max_by(|a, b| a.1.partial_cmp(b.1).unwrap())
            .map(|(i, _)| i as f32)
            .unwrap_or(0.0)
    };

    let last = Axis(pred_arr.ndim() - 1);
    let pred_classes = pred_arr.map_axis(last, argmax);
    let label_classes = label_arr.map_axis(last, argmax);

    pred_classes
        .iter()
        .zip(label_classes.iter())
        .filter(|(p, l)| (*p - *l).abs() < 0.5)
        .count() as f32
        / n as f32
}