aboutsummaryrefslogtreecommitdiff
path: root/src/lib/src/neuralnet.c
diff options
context:
space:
mode:
author3gg <3gg@shellblade.net>2023-11-23 08:38:59 -0800
committer3gg <3gg@shellblade.net>2023-11-23 08:38:59 -0800
commit6ca8a31143f087f3bc470d39eb3c00156443802a (patch)
tree8a7462d28e75d0cfc4eff323f0b83ff12c6dc860 /src/lib/src/neuralnet.c
parent041613467a0915e6ec07cdab0ca3e7b8d757fe5f (diff)
Formatting.
Diffstat (limited to 'src/lib/src/neuralnet.c')
-rw-r--r--src/lib/src/neuralnet.c65
1 files changed, 36 insertions, 29 deletions
diff --git a/src/lib/src/neuralnet.c b/src/lib/src/neuralnet.c
index cac611a..a5fc59b 100644
--- a/src/lib/src/neuralnet.c
+++ b/src/lib/src/neuralnet.c
@@ -1,13 +1,14 @@
1#include <neuralnet/neuralnet.h> 1#include <neuralnet/neuralnet.h>
2 2
3#include <neuralnet/matrix.h>
4#include "activation.h" 3#include "activation.h"
5#include "neuralnet_impl.h" 4#include "neuralnet_impl.h"
5#include <neuralnet/matrix.h>
6 6
7#include <assert.h> 7#include <assert.h>
8#include <stdlib.h> 8#include <stdlib.h>
9 9
10nnNeuralNetwork* nnMakeNet(int num_layers, const int* layer_sizes, const nnActivation* activations) { 10nnNeuralNetwork* nnMakeNet(
11 int num_layers, const int* layer_sizes, const nnActivation* activations) {
11 assert(num_layers > 0); 12 assert(num_layers > 0);
12 assert(layer_sizes); 13 assert(layer_sizes);
13 assert(activations); 14 assert(activations);
@@ -19,10 +20,10 @@ nnNeuralNetwork* nnMakeNet(int num_layers, const int* layer_sizes, const nnActiv
19 20
20 net->num_layers = num_layers; 21 net->num_layers = num_layers;
21 22
22 net->weights = calloc(num_layers, sizeof(nnMatrix)); 23 net->weights = calloc(num_layers, sizeof(nnMatrix));
23 net->biases = calloc(num_layers, sizeof(nnMatrix)); 24 net->biases = calloc(num_layers, sizeof(nnMatrix));
24 net->activations = calloc(num_layers, sizeof(nnActivation)); 25 net->activations = calloc(num_layers, sizeof(nnActivation));
25 if ( (net->weights == 0) || (net->biases == 0) || (net->activations == 0) ) { 26 if ((net->weights == 0) || (net->biases == 0) || (net->activations == 0)) {
26 nnDeleteNet(&net); 27 nnDeleteNet(&net);
27 return 0; 28 return 0;
28 } 29 }
@@ -30,15 +31,15 @@ nnNeuralNetwork* nnMakeNet(int num_layers, const int* layer_sizes, const nnActiv
30 for (int l = 0; l < num_layers; ++l) { 31 for (int l = 0; l < num_layers; ++l) {
31 // layer_sizes = { input layer size, first hidden layer size, ...} 32 // layer_sizes = { input layer size, first hidden layer size, ...}
32 const int layer_input_size = layer_sizes[l]; 33 const int layer_input_size = layer_sizes[l];
33 const int layer_output_size = layer_sizes[l+1]; 34 const int layer_output_size = layer_sizes[l + 1];
34 35
35 // We store the transpose of the weight matrix as written in textbooks. 36 // We store the transpose of the weight matrix as written in textbooks.
36 // Our vectors are row vectors and the matrices row-major. 37 // Our vectors are row vectors and the matrices row-major.
37 const int rows = layer_input_size; 38 const int rows = layer_input_size;
38 const int cols = layer_output_size; 39 const int cols = layer_output_size;
39 40
40 net->weights[l] = nnMatrixMake(rows, cols); 41 net->weights[l] = nnMatrixMake(rows, cols);
41 net->biases[l] = nnMatrixMake(1, cols); 42 net->biases[l] = nnMatrixMake(1, cols);
42 net->activations[l] = activations[l]; 43 net->activations[l] = activations[l];
43 } 44 }
44 45
@@ -46,7 +47,7 @@ nnNeuralNetwork* nnMakeNet(int num_layers, const int* layer_sizes, const nnActiv
46} 47}
47 48
48void nnDeleteNet(nnNeuralNetwork** net) { 49void nnDeleteNet(nnNeuralNetwork** net) {
49 if ( (!net) || (!(*net)) ) { 50 if ((!net) || (!(*net))) {
50 return; 51 return;
51 } 52 }
52 if ((*net)->weights != 0) { 53 if ((*net)->weights != 0) {
@@ -77,7 +78,7 @@ void nnSetWeights(nnNeuralNetwork* net, const R* weights) {
77 78
78 for (int l = 0; l < net->num_layers; ++l) { 79 for (int l = 0; l < net->num_layers; ++l) {
79 nnMatrix* layer_weights = &net->weights[l]; 80 nnMatrix* layer_weights = &net->weights[l];
80 R* layer_values = layer_weights->values; 81 R* layer_values = layer_weights->values;
81 82
82 for (int j = 0; j < layer_weights->rows * layer_weights->cols; ++j) { 83 for (int j = 0; j < layer_weights->rows * layer_weights->cols; ++j) {
83 *layer_values++ = *weights++; 84 *layer_values++ = *weights++;
@@ -91,7 +92,7 @@ void nnSetBiases(nnNeuralNetwork* net, const R* biases) {
91 92
92 for (int l = 0; l < net->num_layers; ++l) { 93 for (int l = 0; l < net->num_layers; ++l) {
93 nnMatrix* layer_biases = &net->biases[l]; 94 nnMatrix* layer_biases = &net->biases[l];
94 R* layer_values = layer_biases->values; 95 R* layer_values = layer_biases->values;
95 96
96 for (int j = 0; j < layer_biases->rows * layer_biases->cols; ++j) { 97 for (int j = 0; j < layer_biases->rows * layer_biases->cols; ++j) {
97 *layer_values++ = *biases++; 98 *layer_values++ = *biases++;
@@ -99,7 +100,8 @@ void nnSetBiases(nnNeuralNetwork* net, const R* biases) {
99 } 100 }
100} 101}
101 102
102void nnQuery(const nnNeuralNetwork* net, nnQueryObject* query, const nnMatrix* input) { 103void nnQuery(
104 const nnNeuralNetwork* net, nnQueryObject* query, const nnMatrix* input) {
103 assert(net); 105 assert(net);
104 assert(query); 106 assert(query);
105 assert(input); 107 assert(input);
@@ -123,29 +125,34 @@ void nnQuery(const nnNeuralNetwork* net, nnQueryObject* query, const nnMatrix* i
123 // We could also rewrite the original Mul function to go row x row, 125 // We could also rewrite the original Mul function to go row x row,
124 // decomposing the multiplication. Preserving the original meaning of Mul 126 // decomposing the multiplication. Preserving the original meaning of Mul
125 // makes everything clearer. 127 // makes everything clearer.
126 nnMatrix output_vector = nnMatrixBorrowRows(&query->layer_outputs[l], i, 1); 128 nnMatrix output_vector =
129 nnMatrixBorrowRows(&query->layer_outputs[l], i, 1);
127 nnMatrixMul(&input_vector, layer_weights, &output_vector); 130 nnMatrixMul(&input_vector, layer_weights, &output_vector);
128 nnMatrixAddRow(&output_vector, layer_biases, &output_vector); 131 nnMatrixAddRow(&output_vector, layer_biases, &output_vector);
129 132
130 switch (net->activations[l]) { 133 switch (net->activations[l]) {
131 case nnIdentity: 134 case nnIdentity:
132 break; // Nothing to do for the identity function. 135 break; // Nothing to do for the identity function.
133 case nnSigmoid: 136 case nnSigmoid:
134 sigmoid_array(output_vector.values, output_vector.values, output_vector.cols); 137 sigmoid_array(
135 break; 138 output_vector.values, output_vector.values, output_vector.cols);
136 case nnRelu: 139 break;
137 relu_array(output_vector.values, output_vector.values, output_vector.cols); 140 case nnRelu:
138 break; 141 relu_array(
139 default: 142 output_vector.values, output_vector.values, output_vector.cols);
140 assert(0); 143 break;
144 default:
145 assert(0);
141 } 146 }
142 147
143 input_vector = output_vector; // Borrow. 148 input_vector = output_vector; // Borrow.
144 } 149 }
145 } 150 }
146} 151}
147 152
148void nnQueryArray(const nnNeuralNetwork* net, nnQueryObject* query, const R* input, R* output) { 153void nnQueryArray(
154 const nnNeuralNetwork* net, nnQueryObject* query, const R* input,
155 R* output) {
149 assert(net); 156 assert(net);
150 assert(query); 157 assert(query);
151 assert(input); 158 assert(input);
@@ -177,9 +184,9 @@ nnQueryObject* nnMakeQueryObject(const nnNeuralNetwork* net, int num_inputs) {
177 return 0; 184 return 0;
178 } 185 }
179 for (int l = 0; l < net->num_layers; ++l) { 186 for (int l = 0; l < net->num_layers; ++l) {
180 const nnMatrix* layer_weights = &net->weights[l]; 187 const nnMatrix* layer_weights = &net->weights[l];
181 const int layer_output_size = nnLayerOutputSize(layer_weights); 188 const int layer_output_size = nnLayerOutputSize(layer_weights);
182 query->layer_outputs[l] = nnMatrixMake(num_inputs, layer_output_size); 189 query->layer_outputs[l] = nnMatrixMake(num_inputs, layer_output_size);
183 } 190 }
184 query->network_outputs = &query->layer_outputs[net->num_layers - 1]; 191 query->network_outputs = &query->layer_outputs[net->num_layers - 1];
185 192
@@ -187,7 +194,7 @@ nnQueryObject* nnMakeQueryObject(const nnNeuralNetwork* net, int num_inputs) {
187} 194}
188 195
189void nnDeleteQueryObject(nnQueryObject** query) { 196void nnDeleteQueryObject(nnQueryObject** query) {
190 if ( (!query) || (!(*query)) ) { 197 if ((!query) || (!(*query))) {
191 return; 198 return;
192 } 199 }
193 if ((*query)->layer_outputs != 0) { 200 if ((*query)->layer_outputs != 0) {