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
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
//! # mynn
//!
//! [](https://crates.io/crates/mynn)
//! [](https://docs.rs/mynn)
//! [](./LICENCE)
//!
//! An hobbyist no-std neural network library.
//!
//! ## Explanation
//!
//! This is a small library (currently ~200 lines minus doc comments and helper macros) I initially created during my lunch break when I had attempted to represent the shape of a neural network in Rust's type system, the result was I was able to make all the vectors into fixed sized arrays and allow the neural network to be no-std and in theory usable on microcontroller and embedded platforms.
//!
//! See this [example](https://github.com/jasonalexander-ja/mynn-attiny-example) of a pre-trained model approximating an XOR running on an ATtiny85.
//!
//! ## Installation
//!
//! Command line:
//! ```text
//! cargo add mynn
//! ```
//!
//! Cargo.toml:
//! ```text
//! mynn = "0.1.2"
//! ```
//!
//! To use `f32` in all operations, supply the `f32` flag:
//!
//! ```text
//! mynn = { version = "0.1.2", features = ["f32"] }
//! ```
//!
//! To remove recursion, use `recurse-opt`:
//! ```text
//! mynn = { version = "0.1.1", features = ["recurse-opt"] }
//! ```
//!
//! This will cause all the recursive method calls on each layer to be inlined, on larger models this may increase the size of the generated code, tradeoffs need to be considered.
//!
//! ## Example
//!
//! Short example approximates the output of a XOR gate.
//!
//! ```rust
//! use mynn::make_network;
//! use mynn::activations::SIGMOID;
//!
//! fn main() {
//! let inputs = [[0.0, 0.0], [0.0, 1.0], [1.0, 0.0], [1.0, 1.0]];
//! let targets = [[0.0], [1.0], [1.0], [0.0]];
//!
//!
//! let mut network = make_network!(2, 3, 1);
//! network.train(0.5, inputs, targets, 10_000, &SIGMOID);
//!
//!
//! println!("0 and 0: {:?}", network.predict([0.0, 0.0], &SIGMOID));
//! println!("1 and 0: {:?}", network.predict([1.0, 0.0], &SIGMOID));
//! println!("0 and 1: {:?}", network.predict([0.0, 1.0], &SIGMOID));
//! println!("1 and 1: {:?}", network.predict([1.0, 1.0], &SIGMOID));
//! }
//! ```
/// Contains types for and an example activation function.
/// Contains the types and functionality for processing matrices.
/// Contains the types and functionality for the neural network.
/// Centralized type for floating point operations that can be easily changed to [f32] or [f64] (default is [f64], use `f32` feature for [f32]).
pub type Float = f64;
/// Centralized type for floating point operations that can be easily changed to [f32] or [f64] (default is [f64], use `f32` feature for [f32]).
pub type Float = f32;
/// Helper macro, finds and evaluates to the final value from a token tree.
///
/// # Example
/// ```
/// use mynn::last_arg;
///
/// let foo = last_arg!(0, 1, 2, 3, 4);
/// assert_eq!(foo, 4);
/// ```
/// Helper macro, instantiates the inner recursive elements to a neural network without the type.
///
/// When used in combination with [make_net_type] within [make_network] this can instantiate a neural network.
///
/// # Example
/// ```
/// use mynn::network::{ProcessLayer, EndLayer};
/// use mynn::instantiate_net;
///
/// let network: ProcessLayer::<3, 2, 1, ProcessLayer<1, 3, 1, EndLayer<1>>> = ProcessLayer::new(instantiate_net!(2, 3, 1));
/// let network2: ProcessLayer::<3, 2, 1, ProcessLayer<1, 3, 1, EndLayer<1>>> = ProcessLayer::new(ProcessLayer::new(EndLayer()));
///
/// assert_eq!(std::any::type_name_of_val(&network), std::any::type_name_of_val(&network2));
/// ```
/// Helper macro, generates a type definition for the recursive types in a neural network.
///
/// When used with [instantiate_net] in [make_network] it can make instantiating large neural networks less verbose.
///
/// # Example
/// ```
/// use mynn::network::{ProcessLayer, EndLayer};
/// use mynn::make_net_type;
///
/// let network: make_net_type!(2, 3, 1) = ProcessLayer::new(ProcessLayer::new(EndLayer()));
/// ```
;
}
/// Helper macro used to initialize a neural network, simply pass a comma separated list the number of neurons for each layer, works for any sized neural network.
///
/// # Example
/// ```
/// use mynn::network::{ProcessLayer, EndLayer};
/// use mynn::make_network;
///
/// let network = make_network!(2, 3, 1);
/// let network2 = ProcessLayer::<3, 2, 1, ProcessLayer<1, 3, 1, EndLayer<1>>>::new(ProcessLayer::new(EndLayer()));
///
/// assert_eq!(std::any::type_name_of_val(&network), std::any::type_name_of_val(&network2));
/// ```
;
}