concision_neural/model/
mod.rs

1/*
2    Appellation: model <module>
3    Contrib: @FL03
4*/
5//! This module provides the scaffolding for creating models and layers in a neural network.
6
7#[doc(inline)]
8pub use self::{
9    config::StandardModelConfig, layout::*, model_params::ModelParams, trainer::Trainer,
10};
11
12pub mod config;
13pub mod layout;
14pub mod model_params;
15pub mod trainer;
16
17pub(crate) mod prelude {
18    pub use super::Model;
19    pub use super::config::*;
20    pub use super::layout::*;
21    pub use super::model_params::*;
22    pub use super::trainer::*;
23}
24
25use crate::{NetworkConfig, Predict, Train};
26use concision_core::params::Params;
27use concision_data::DatasetBase;
28
29/// The base interface for all models; each model provides access to a configuration object
30/// defined as the associated type [`Config`](Model::Config). The configuration object is used
31/// to provide hyperparameters and other control related parameters. In addition, the model's
32/// layout is defined by the [`features`](Model::features) method which aptly returns a copy of
33/// its [ModelFeatures] object.
34pub trait Model<T = f32> {
35    /// The configuration type for the model
36    type Config: NetworkConfig<T>;
37    /// the type of layout used by the model
38    type Layout;
39    /// returns an immutable reference to the models configuration; this is typically used to
40    /// access the models hyperparameters (i.e. learning rate, momentum, etc.) and other
41    /// related control parameters.
42    fn config(&self) -> &Self::Config;
43    /// returns a mutable reference to the models configuration; useful for setting hyperparams
44    fn config_mut(&mut self) -> &mut Self::Config;
45    /// returns a copy of the model's current layout (features); a type providing the model
46    /// with a particular number of features for the various layers of a deep neural network.
47    ///
48    /// the layout is used in everything from creation and initialization routines to
49    /// validating the dimensionality of the model's inputs, outputs, training data, etc.
50    fn layout(&self) -> Self::Layout;
51    /// returns an immutable reference to the model parameters
52    fn params(&self) -> &ModelParams<T>;
53    /// returns a mutable reference to the model's parameters
54    fn params_mut(&mut self) -> &mut ModelParams<T>;
55    /// propagates the input through the model; each layer is applied in sequence meaning that
56    /// the output of each previous layer is the input to the next layer. This pattern
57    /// repeats until the output layer returns the final result.
58    ///
59    /// By default, the trait simply passes each output from one layer to the next, however,
60    /// custom models will likely override this method to inject activation methods and other
61    /// related logic
62    fn predict<U, V>(&self, inputs: &U) -> crate::NeuralResult<V>
63    where
64        Self: Predict<U, Output = V>,
65    {
66        Predict::predict(self, inputs)
67    }
68    /// a convience method that trains the model using the provided dataset; this method
69    /// requires that the model implements the [`Train`] trait and that the dataset
70    fn train<U, V, W>(&mut self, dataset: &DatasetBase<U, V>) -> crate::NeuralResult<W>
71    where
72        Self: Train<U, V, Output = W>,
73    {
74        Train::train(self, dataset.records(), dataset.targets())
75    }
76}
77
78pub trait ModelExt<T>: Model<T>
79where
80    Self::Layout: ModelLayout,
81{
82    /// replaces the current configuration and returns the old one;
83    fn replace_config(&mut self, config: Self::Config) -> Self::Config {
84        core::mem::replace(self.config_mut(), config)
85    }
86    /// replaces the current model parameters and returns the old one;
87    fn replace_params(&mut self, params: ModelParams<T>) -> ModelParams<T> {
88        core::mem::replace(self.params_mut(), params)
89    }
90    /// overrides the current configuration and returns a mutable reference to the model;
91    fn set_config(&mut self, config: Self::Config) -> &mut Self {
92        *self.config_mut() = config;
93        self
94    }
95    /// overrides the current model parameters and returns a mutable reference to the model;
96    fn set_params(&mut self, params: ModelParams<T>) -> &mut Self {
97        *self.params_mut() = params;
98        self
99    }
100    /// returns an immutable reference to the input layer;
101    #[inline]
102    fn input_layer(&self) -> &Params<T> {
103        self.params().input()
104    }
105    /// returns a mutable reference to the input layer;
106    #[inline]
107    fn input_layer_mut(&mut self) -> &mut Params<T> {
108        self.params_mut().input_mut()
109    }
110    /// returns an immutable reference to the hidden layer(s);
111    #[inline]
112    fn hidden_layers(&self) -> &Vec<Params<T>> {
113        self.params().hidden()
114    }
115    /// returns a mutable reference to the hidden layer(s);
116    #[inline]
117    fn hidden_layers_mut(&mut self) -> &mut Vec<Params<T>> {
118        self.params_mut().hidden_mut()
119    }
120    /// returns an immutable reference to the output layer;
121    #[inline]
122    fn output_layer(&self) -> &Params<T> {
123        self.params().output()
124    }
125    /// returns a mutable reference to the output layer;
126    #[inline]
127    fn output_layer_mut(&mut self) -> &mut Params<T> {
128        self.params_mut().output_mut()
129    }
130    #[inline]
131    fn set_input_layer(&mut self, layer: Params<T>) -> &mut Self {
132        self.params_mut().set_input(layer);
133        self
134    }
135    #[inline]
136    fn set_hidden_layers(&mut self, layers: Vec<Params<T>>) -> &mut Self {
137        self.params_mut().set_hidden(layers);
138        self
139    }
140    #[inline]
141    fn set_output_layer(&mut self, layer: Params<T>) -> &mut Self {
142        self.params_mut().set_output(layer);
143        self
144    }
145    /// returns a 2-tuple representing the dimensions of the input layer; (input, hidden)
146    fn input_dim(&self) -> (usize, usize) {
147        self.layout().dim_input()
148    }
149    /// returns a 2-tuple representing the dimensions of the hidden layers; (hidden, hidden)
150    fn hidden_dim(&self) -> (usize, usize) {
151        self.layout().dim_hidden()
152    }
153    /// returns the total number of hidden layers in the model;
154    fn hidden_layers_count(&self) -> usize {
155        self.layout().layers()
156    }
157    /// returns a 2-tuple representing the dimensions of the output layer; (hidden, output)
158    fn output_dim(&self) -> (usize, usize) {
159        self.layout().dim_output()
160    }
161}
162
163impl<M, T> ModelExt<T> for M
164where
165    M: Model<T>,
166    M::Layout: ModelLayout,
167{
168}
169
170/// The [`DeepNeuralNetwork`] trait is a specialization of the [`Model`] trait that
171/// provides additional functionality for deep neural networks. This trait is
172pub trait DeepNeuralNetwork<T = f32>: Model<T> {}
173
174pub trait ModelTrainer<T> {
175    type Model: Model<T>;
176    /// returns a model trainer prepared to train the model; this is a convenience method
177    /// that creates a new trainer instance and returns it. Trainers are lazily evaluated
178    /// meaning that the training process won't begin until the user calls the `begin` method.
179    fn trainer<'a, U, V>(
180        &mut self,
181        dataset: DatasetBase<U, V>,
182        model: &'a mut Self::Model,
183    ) -> Trainer<'a, Self::Model, T, DatasetBase<U, V>>
184    where
185        Self: Sized,
186        T: Default,
187        for<'b> &'b mut Self::Model: Model<T>,
188    {
189        Trainer::new(model, dataset)
190    }
191}