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}