1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83

use std::any::Any;
use std::fmt::Debug;


/// Layer is a layer in the neural network. In order for 

/// the network to be evolved, it must be able to be cloned which is where LayerClone

/// comes in - allowing the Box<dyn Layer> to be cloned without knowing which type it 

/// really is under the hood. Any allows for the underlying object to be downcast to a concrete type

#[typetag::serde(tag = "type")]
pub trait Layer: LayerClone + Any + Debug + Send + Sync {
    
    /// propagate an input vec through this layer. This is done differently 

    /// depending on the type of layer, just the same as backpropagation is.

    /// if the layer is just being evolved, it needs to not keep track of the 

    /// meta data within because there is no need for the network  to backprop after

    /// Return the output as a vec 

    fn forward(&mut self, inputs: &Vec<f32>) -> Option<Vec<f32>>;

    /// Take the errors of the feed forward and backpropagate them through the network

    /// to adjust the weights of the connections between the neurons. Return the error 

    /// of the input neurons from this layer - needed to transfer error from layer to layer

    fn backward(&mut self, errors: &Vec<f32>, learning_rate: f32) -> Option<Vec<f32>>;

    /// Get a reference to the underlying type without generics in order to downcast to a concrete type

    fn as_ref_any(&self) -> &dyn Any;

    /// Get a mutable reference to the underlying type without generics in order to downcast to a concrete type

    fn as_mut_any(&mut self) -> &mut dyn Any;

    /// Return the (input size, output size) of this layer - used to make specifying layer sizes easier 

    /// so the user only needs the say the size of the output, not the input. That would be too redundant.

    fn shape(&self) -> (usize, usize);

    /// reset the layer, not a necessary implementation

    fn reset(&mut self) { }

    // add tracers to keep track of meta data for historical back propagation

    fn add_tracer(&mut self) { }

    /// remove the tracer from a layer so that it can be evolved without keeping track of data

    fn remove_tracer(&mut self) { }

}



/// Turns out cloning a Box<dyn trait> is harder than it seems. 

/// This isn't meant to be implemented outside of this file and is only used

/// to clone the trait object 

pub trait LayerClone {
    fn clone_box(&self) -> Box<dyn Layer>;
}



/// Implement LayerClone for any type <L> that implements Layer 

/// and is also Clone

impl<L> LayerClone for L
    where L: 'static + Layer + Clone 
{
    fn clone_box(&self) -> Box<dyn Layer> {
        Box::new((*self).clone())
    }
}



/// required for the dyn layer to be Clone in order for 

/// LayerClone to work, so implement Clone for any Layer

impl Clone for Box<dyn Layer> {
    fn clone(&self) -> Box<dyn Layer> {
        self.clone_box()
    }
}


/// Need to able to compare dyn layers (is there a better way to do this?)

impl PartialEq for dyn Layer {
    fn eq(&self, other: &Self) -> bool {
        self == other
    }
}