parent
5a20acf595
commit
d3d5f57a2b
@ -0,0 +1,62 @@
|
||||
use crate::{
|
||||
derivable::NeuraLoss,
|
||||
layer::NeuraLayer,
|
||||
network::NeuraNetwork,
|
||||
// utils::{assign_add_vector, chunked},
|
||||
algebra::NeuraAddAssign,
|
||||
};
|
||||
|
||||
|
||||
pub trait NeuraTrainableLayer: NeuraLayer {
|
||||
type Delta: NeuraAddAssign;
|
||||
|
||||
/// Computes the backpropagation term and the derivative of the internal weights,
|
||||
/// using the `input` vector outputted by the previous layer and the backpropagation term `epsilon` of the next layer.
|
||||
///
|
||||
/// Note: we introduce the term `epsilon`, which together with the activation of the current function can be used to compute `delta_l`:
|
||||
/// ```no_rust
|
||||
/// f_l'(a_l) * epsilon_l = delta_l
|
||||
/// ```
|
||||
///
|
||||
/// The function should then return a pair `(epsilon_{l-1}, δW_l)`,
|
||||
/// with `epsilon_{l-1}` being multiplied by `f_{l-1}'(activation)`.
|
||||
fn backpropagate(&self, input: &Self::Input, epsilon: Self::Output) -> (Self::Input, Self::Delta);
|
||||
}
|
||||
|
||||
pub trait NeuraTrainable: NeuraLayer {
|
||||
type Delta: NeuraAddAssign;
|
||||
|
||||
fn backpropagate<Loss: NeuraLoss<Self::Output>>(&self, input: &Self::Input, target: Loss::Target, loss: Loss) -> (Self::Input, Self::Delta);
|
||||
}
|
||||
|
||||
pub trait NeuraTrainer<F, Loss: NeuraLoss<F>> {
|
||||
fn get_gradient<Layer: NeuraLayer, ChildNetwork>(
|
||||
&self,
|
||||
trainable: &NeuraNetwork<Layer, ChildNetwork>,
|
||||
input: &Layer::Input,
|
||||
target: Loss::Target,
|
||||
loss: Loss,
|
||||
) -> <NeuraNetwork<Layer, ChildNetwork> as NeuraTrainable>::Delta where
|
||||
NeuraNetwork<Layer, ChildNetwork>: NeuraTrainable<Input = Layer::Input, Output = F>
|
||||
;
|
||||
}
|
||||
|
||||
#[non_exhaustive]
|
||||
pub struct NeuraBackprop {
|
||||
pub epsilon: f64,
|
||||
pub batch_size: usize,
|
||||
}
|
||||
|
||||
impl<const N: usize, Loss: NeuraLoss<[f64; N]>> NeuraTrainer<[f64; N], Loss> for NeuraBackprop {
|
||||
fn get_gradient<Layer: NeuraLayer, ChildNetwork>(
|
||||
&self,
|
||||
trainable: &NeuraNetwork<Layer, ChildNetwork>,
|
||||
input: &Layer::Input,
|
||||
target: Loss::Target,
|
||||
loss: Loss,
|
||||
) -> <NeuraNetwork<Layer, ChildNetwork> as NeuraTrainable>::Delta where
|
||||
NeuraNetwork<Layer, ChildNetwork>: NeuraTrainable<Input = Layer::Input, Output = [f64; N]>,
|
||||
{
|
||||
trainable.backpropagate(input, target, loss).1
|
||||
}
|
||||
}
|
Loading…
Reference in new issue