Shad Amethyst 2 years ago
parent dd278e7b90
commit 060b801ad6

@ -2,7 +2,7 @@ use num::ToPrimitive;
use crate::{ use crate::{
derivable::NeuraLoss, layer::NeuraTrainableLayerBackprop, layer::NeuraTrainableLayerSelf, derivable::NeuraLoss, layer::NeuraTrainableLayerBackprop, layer::NeuraTrainableLayerSelf,
network::NeuraTrainableNetworkBase, network::NeuraOldTrainableNetworkBase,
}; };
use super::*; use super::*;
@ -20,12 +20,12 @@ impl<Loss> NeuraBackprop<Loss> {
impl< impl<
Input, Input,
Target, Target,
Trainable: NeuraTrainableNetworkBase<Input>, Trainable: NeuraOldTrainableNetworkBase<Input>,
Loss: NeuraLoss<Trainable::Output, Target = Target> + Clone, Loss: NeuraLoss<Trainable::Output, Target = Target> + Clone,
> NeuraGradientSolver<Input, Target, Trainable> for NeuraBackprop<Loss> > NeuraGradientSolver<Input, Target, Trainable> for NeuraBackprop<Loss>
where where
<Loss as NeuraLoss<Trainable::Output>>::Output: ToPrimitive, <Loss as NeuraLoss<Trainable::Output>>::Output: ToPrimitive,
Trainable: for<'a> NeuraTrainableNetwork<Input, (&'a NeuraBackprop<Loss>, &'a Target)>, Trainable: for<'a> NeuraOldTrainableNetwork<Input, (&'a NeuraBackprop<Loss>, &'a Target)>,
{ {
fn get_gradient( fn get_gradient(
&self, &self,

@ -30,7 +30,7 @@ impl<
F, F,
Act: Clone + NeuraDerivable<f64>, Act: Clone + NeuraDerivable<f64>,
Input, Input,
Trainable: NeuraTrainableNetwork<Input, NeuraForwardPair<Act>, Output = DVector<F>>, Trainable: NeuraOldTrainableNetwork<Input, NeuraForwardPair<Act>, Output = DVector<F>>,
> NeuraGradientSolver<Input, bool, Trainable> for NeuraForwardForward<Act> > NeuraGradientSolver<Input, bool, Trainable> for NeuraForwardForward<Act>
where where
F: ToPrimitive, F: ToPrimitive,
@ -138,7 +138,7 @@ impl<
fn map_epsilon<From, To, Gradient, Cb: Fn(From) -> To>( fn map_epsilon<From, To, Gradient, Cb: Fn(From) -> To>(
&self, &self,
rec_opt_output: Self::Output<From, Gradient>, rec_opt_output: Self::Output<From, Gradient>,
callback: Cb _callback: Cb
) -> Self::Output<To, Gradient> { ) -> Self::Output<To, Gradient> {
rec_opt_output rec_opt_output
} }

@ -6,7 +6,7 @@ pub use forward_forward::NeuraForwardForward;
use crate::{ use crate::{
layer::NeuraTrainableLayerBase, layer::NeuraTrainableLayerBase,
network::{NeuraTrainableNetwork, NeuraTrainableNetworkBase}, network::{NeuraOldTrainableNetwork, NeuraOldTrainableNetworkBase},
}; };
pub trait NeuraGradientSolverBase { pub trait NeuraGradientSolverBase {
@ -37,7 +37,7 @@ pub trait NeuraGradientSolverTransient<Input, Layer: NeuraTrainableLayerBase<Inp
) -> Self::Output<To, Gradient>; ) -> Self::Output<To, Gradient>;
} }
pub trait NeuraGradientSolver<Input, Target, Trainable: NeuraTrainableNetworkBase<Input>> { pub trait NeuraGradientSolver<Input, Target, Trainable: NeuraOldTrainableNetworkBase<Input>> {
fn get_gradient( fn get_gradient(
&self, &self,
trainable: &Trainable, trainable: &Trainable,

@ -2,11 +2,11 @@ use crate::{
algebra::NeuraVectorSpace, gradient_solver::{NeuraGradientSolverBase, NeuraGradientSolverFinal}, layer::NeuraLayer, algebra::NeuraVectorSpace, gradient_solver::{NeuraGradientSolverBase, NeuraGradientSolverFinal}, layer::NeuraLayer,
}; };
pub mod residual; // pub mod residual;
pub mod sequential; pub mod sequential;
// TODO: extract regularize from this, so that we can drop the trait constraints on NeuraSequential's impl // TODO: extract regularize from this, so that we can drop the trait constraints on NeuraSequential's impl
pub trait NeuraTrainableNetworkBase<Input>: NeuraLayer<Input> { pub trait NeuraOldTrainableNetworkBase<Input>: NeuraLayer<Input> {
type Gradient: NeuraVectorSpace; type Gradient: NeuraVectorSpace;
type LayerOutput; type LayerOutput;
@ -21,7 +21,7 @@ pub trait NeuraTrainableNetworkBase<Input>: NeuraLayer<Input> {
fn prepare(&mut self, train_iteration: bool); fn prepare(&mut self, train_iteration: bool);
} }
pub trait NeuraTrainableNetwork<Input, Optimizer>: NeuraTrainableNetworkBase<Input> pub trait NeuraOldTrainableNetwork<Input, Optimizer>: NeuraOldTrainableNetworkBase<Input>
where where
Optimizer: NeuraGradientSolverBase, Optimizer: NeuraGradientSolverBase,
{ {
@ -33,7 +33,7 @@ where
} }
impl<Input: Clone, Optimizer: NeuraGradientSolverFinal<Input>> impl<Input: Clone, Optimizer: NeuraGradientSolverFinal<Input>>
NeuraTrainableNetwork<Input, Optimizer> for () NeuraOldTrainableNetwork<Input, Optimizer> for ()
{ {
fn traverse( fn traverse(
&self, &self,

@ -174,16 +174,25 @@ where
let child_result = self.child_network.traverse(&rest, optimizer); let child_result = self.child_network.traverse(&rest, optimizer);
// TODO: maybe move this to a custom impl of NeuraGradientSolverTransient for NeuraResidualInput? // TODO: maybe move this to a custom impl of NeuraGradientSolverTransient for NeuraResidualInput?
// Or have a different set of traits for NeuraTrainableNetwork specific to NeuraResidualNodes // Or have a different set of traits for NeuraTrainableNetwork specific to NeuraResidualNodes
let child_result = optimizer.map_epsilon(child_result, |epsilon| { let child_result = optimizer.map_epsilon(child_result, |_epsilon| {
// Pop the first value from `epsilon`, then: // Pop the first value from `epsilon`, then:
// - compute its sum // - compute its sum
// - use it to compute the outcoming epsilon of the current layer // - use it to compute the outcoming epsilon of the current layer
// - split the oucoming epsilon into its original components, and push those back onto the rest // - split the oucoming epsilon into its original components, and push those back onto the rest
// At this point, the value for `epsilon` in the gradient solver's state should be ready for another iteration, // At this point, the value for `epsilon` in the gradient solver's state should be ready for another iteration,
// with the first value containing the unsummed incoming epsilon values from the downstream layers // with the first value containing the unsummed incoming epsilon values from the downstream layers
todo!(); todo!()
}); });
optimizer.eval_layer(
&self.layer,
&layer_input,
&layer_output,
&layer_intermediary,
child_result,
|this_gradient, child_gradient| (this_gradient, Box::new(child_gradient))
);
todo!(); todo!();
} }
} }

@ -1,6 +1,6 @@
use super::{NeuraTrainableNetwork, NeuraTrainableNetworkBase}; use super::{NeuraOldTrainableNetwork, NeuraOldTrainableNetworkBase};
use crate::{ use crate::{
gradient_solver::{NeuraGradientSolverFinal, NeuraGradientSolverTransient}, gradient_solver::{NeuraGradientSolverTransient},
layer::{ layer::{
NeuraLayer, NeuraPartialLayer, NeuraShape, NeuraTrainableLayerBase, NeuraTrainableLayerSelf, NeuraLayer, NeuraPartialLayer, NeuraShape, NeuraTrainableLayerBase, NeuraTrainableLayerSelf,
}, },
@ -82,8 +82,8 @@ impl<Layer, ChildNetwork> NeuraSequential<Layer, ChildNetwork> {
impl< impl<
Input, Input,
Layer: NeuraTrainableLayerBase<Input> + NeuraTrainableLayerSelf<Input>, Layer: NeuraTrainableLayerBase<Input> + NeuraTrainableLayerSelf<Input>,
ChildNetwork: NeuraTrainableNetworkBase<Layer::Output>, ChildNetwork: NeuraOldTrainableNetworkBase<Layer::Output>,
> NeuraTrainableNetworkBase<Input> for NeuraSequential<Layer, ChildNetwork> > NeuraOldTrainableNetworkBase<Input> for NeuraSequential<Layer, ChildNetwork>
{ {
type Gradient = (Layer::Gradient, Box<ChildNetwork::Gradient>); type Gradient = (Layer::Gradient, Box<ChildNetwork::Gradient>);
type LayerOutput = Layer::Output; type LayerOutput = Layer::Output;
@ -114,7 +114,7 @@ impl<
} }
/// A dummy implementation of `NeuraTrainableNetwork`, which simply calls `loss.eval` in `backpropagate`. /// A dummy implementation of `NeuraTrainableNetwork`, which simply calls `loss.eval` in `backpropagate`.
impl<Input: Clone> NeuraTrainableNetworkBase<Input> for () { impl<Input: Clone> NeuraOldTrainableNetworkBase<Input> for () {
type Gradient = (); type Gradient = ();
type LayerOutput = Input; type LayerOutput = Input;
@ -143,10 +143,10 @@ impl<
Input, Input,
Layer: NeuraTrainableLayerBase<Input> + NeuraTrainableLayerSelf<Input>, Layer: NeuraTrainableLayerBase<Input> + NeuraTrainableLayerSelf<Input>,
Optimizer: NeuraGradientSolverTransient<Input, Layer>, Optimizer: NeuraGradientSolverTransient<Input, Layer>,
ChildNetwork: NeuraTrainableNetworkBase<Layer::Output>, ChildNetwork: NeuraOldTrainableNetworkBase<Layer::Output>,
> NeuraTrainableNetwork<Input, Optimizer> for NeuraSequential<Layer, ChildNetwork> > NeuraOldTrainableNetwork<Input, Optimizer> for NeuraSequential<Layer, ChildNetwork>
where where
ChildNetwork: NeuraTrainableNetwork<Layer::Output, Optimizer>, ChildNetwork: NeuraOldTrainableNetwork<Layer::Output, Optimizer>,
{ {
fn traverse( fn traverse(
&self, &self,

@ -1,6 +1,6 @@
use crate::{ use crate::{
algebra::NeuraVectorSpace, gradient_solver::NeuraGradientSolver, algebra::NeuraVectorSpace, gradient_solver::NeuraGradientSolver,
network::NeuraTrainableNetworkBase, network::NeuraOldTrainableNetworkBase,
}; };
#[non_exhaustive] #[non_exhaustive]
@ -73,7 +73,7 @@ impl NeuraBatchedTrainer {
pub fn train< pub fn train<
Input: Clone, Input: Clone,
Target: Clone, Target: Clone,
Network: NeuraTrainableNetworkBase<Input>, Network: NeuraOldTrainableNetworkBase<Input>,
GradientSolver: NeuraGradientSolver<Input, Target, Network>, GradientSolver: NeuraGradientSolver<Input, Target, Network>,
Inputs: IntoIterator<Item = (Input, Target)>, Inputs: IntoIterator<Item = (Input, Target)>,
>( >(
@ -84,7 +84,7 @@ impl NeuraBatchedTrainer {
test_inputs: &[(Input, Target)], test_inputs: &[(Input, Target)],
) -> Vec<(f64, f64)> ) -> Vec<(f64, f64)>
where where
<Network as NeuraTrainableNetworkBase<Input>>::Gradient: std::fmt::Debug, <Network as NeuraOldTrainableNetworkBase<Input>>::Gradient: std::fmt::Debug,
{ {
let mut losses = Vec::new(); let mut losses = Vec::new();
let mut iter = inputs.into_iter(); let mut iter = inputs.into_iter();

Loading…
Cancel
Save