concision_neural/model/traits/
models.rs

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