parent
f3752bd411
commit
d40098d2ef
@ -0,0 +1,96 @@
|
|||||||
|
use super::*;
|
||||||
|
use crate::prelude::NeuraTrainableLayerBackprop;
|
||||||
|
|
||||||
|
impl<Input, Layer: NeuraLayer<Input>, ChildNetwork: NeuraLayer<Layer::Output>> NeuraLayer<Input>
|
||||||
|
for NeuraSequential<Layer, ChildNetwork>
|
||||||
|
{
|
||||||
|
type Output = ChildNetwork::Output;
|
||||||
|
|
||||||
|
fn eval(&self, input: &Input) -> Self::Output {
|
||||||
|
self.child_network.eval(&self.layer.eval(input))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<
|
||||||
|
Input,
|
||||||
|
Layer: NeuraTrainableLayerBase<Input>,
|
||||||
|
ChildNetwork: NeuraTrainableLayerBase<Layer::Output>,
|
||||||
|
> NeuraTrainableLayerBase<Input> for NeuraSequential<Layer, ChildNetwork>
|
||||||
|
{
|
||||||
|
type Gradient = (Layer::Gradient, Box<ChildNetwork::Gradient>);
|
||||||
|
type IntermediaryRepr = (Layer::IntermediaryRepr, Box<ChildNetwork::IntermediaryRepr>);
|
||||||
|
|
||||||
|
fn default_gradient(&self) -> Self::Gradient {
|
||||||
|
(
|
||||||
|
self.layer.default_gradient(),
|
||||||
|
Box::new(self.child_network.default_gradient()),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn eval_training(&self, input: &Input) -> (Self::Output, Self::IntermediaryRepr) {
|
||||||
|
let (layer_output, layer_intermediary) = self.layer.eval_training(input);
|
||||||
|
let (child_output, child_intermediary) = self.child_network.eval_training(&layer_output);
|
||||||
|
|
||||||
|
(
|
||||||
|
child_output,
|
||||||
|
(layer_intermediary, Box::new(child_intermediary)),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn prepare_layer(&mut self, is_training: bool) {
|
||||||
|
self.layer.prepare_layer(is_training);
|
||||||
|
self.child_network.prepare_layer(is_training);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn apply_gradient(&mut self, gradient: &Self::Gradient) {
|
||||||
|
self.layer.apply_gradient(&gradient.0);
|
||||||
|
self.child_network.apply_gradient(&gradient.1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<
|
||||||
|
Input,
|
||||||
|
Layer: NeuraTrainableLayerSelf<Input>,
|
||||||
|
ChildNetwork: NeuraTrainableLayerSelf<Layer::Output> + NeuraTrainableLayerBackprop<Layer::Output>,
|
||||||
|
> NeuraTrainableLayerSelf<Input> for NeuraSequential<Layer, ChildNetwork>
|
||||||
|
{
|
||||||
|
fn regularize_layer(&self) -> Self::Gradient {
|
||||||
|
(
|
||||||
|
self.layer.regularize_layer(),
|
||||||
|
Box::new(self.child_network.regularize_layer()),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_gradient(
|
||||||
|
&self,
|
||||||
|
input: &Input,
|
||||||
|
intermediary: &Self::IntermediaryRepr,
|
||||||
|
epsilon: &Self::Output,
|
||||||
|
) -> Self::Gradient {
|
||||||
|
unimplemented!("NeuraSequential::get_gradient is not yet implemented, sorry");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<
|
||||||
|
Input,
|
||||||
|
Layer: NeuraTrainableLayerBackprop<Input>,
|
||||||
|
ChildNetwork: NeuraTrainableLayerBackprop<Layer::Output>,
|
||||||
|
> NeuraTrainableLayerBackprop<Input> for NeuraSequential<Layer, ChildNetwork>
|
||||||
|
{
|
||||||
|
fn backprop_layer(
|
||||||
|
&self,
|
||||||
|
input: &Input,
|
||||||
|
intermediary: &Self::IntermediaryRepr,
|
||||||
|
incoming_epsilon: &Self::Output,
|
||||||
|
) -> Input {
|
||||||
|
let transient_output = self.layer.eval(input);
|
||||||
|
let transient_epsilon =
|
||||||
|
self.child_network
|
||||||
|
.backprop_layer(&transient_output, &intermediary.1, incoming_epsilon);
|
||||||
|
let outgoing_epsilon =
|
||||||
|
self.layer
|
||||||
|
.backprop_layer(input, &intermediary.0, &transient_epsilon);
|
||||||
|
|
||||||
|
outgoing_epsilon
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in new issue