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}