PandA-2024.02
backprop.c
Go to the documentation of this file.
1 #include "backprop.h"
2 
3 void soft_max(TYPE net_outputs[possible_outputs], TYPE activations[possible_outputs]) {
4  int i;
5  TYPE sum;
6  sum = (TYPE) 0.0;
7 
8  for(i=0; i < possible_outputs; i++) {
9  sum += exp(-activations[i]);
10  }
11  for(i=0; i < possible_outputs; i++) {
12  net_outputs[i] = exp(-activations[i])/sum;
13  }
14 }
15 
16 void RELU(TYPE activations[nodes_per_layer], TYPE dactivations[nodes_per_layer], int size) {
17  int i;
18  for( i = 0; i < size; i++) {
19  dactivations[i] = activations[i]*(1.0-activations[i]);
20  activations[i] = 1.0/(1.0+exp(-activations[i]));
21  }
22 }
23 
25  TYPE activations[nodes_per_layer],
26  int size) {
27  int i;
28  for( i = 0; i < size; i++){
29  activations[i] = activations[i] + biases[i];
30  }
31 }
32 
34  TYPE weights[input_dimension*nodes_per_layer],
35  TYPE activations[nodes_per_layer],
36  TYPE input_sample[input_dimension]){
37  int i,j;
38  for(j = 0; j < nodes_per_layer; j++){
39  activations[j] = (TYPE)0.0;
40  for (i = 0; i < input_dimension; i++){
41  activations[j] += weights[j*input_dimension + i] * input_sample[i];
42  }
43  }
44  add_bias_to_activations(biases, activations, nodes_per_layer);
45 }
46 
48  TYPE weights[nodes_per_layer*nodes_per_layer],
49  TYPE activations[nodes_per_layer],
50  TYPE input_activations[nodes_per_layer]){
51  int i,j;
52  for (i = 0; i < nodes_per_layer; i++){
53  activations[i] = (TYPE)0.0;
54  for(j = 0; j < nodes_per_layer; j++){
55  activations[i] += weights[i*nodes_per_layer + j] * input_activations[j];
56  }
57  }
58  add_bias_to_activations(biases, activations, nodes_per_layer);
59 }
60 
62  TYPE weights[nodes_per_layer*possible_outputs],
63  TYPE activations[possible_outputs],
64  TYPE input_activations[nodes_per_layer]){
65  int i, j;
66  for(j = 0; j < possible_outputs; j++){
67  activations[j] = (TYPE)0.0;
68  for (i = 0; i < nodes_per_layer; i++){
69  activations[j] += weights[j*nodes_per_layer + i] * input_activations[i];
70  }
71  }
72  add_bias_to_activations(biases, activations, possible_outputs);
73 }
74 
76  TYPE solutions[possible_outputs],
77  TYPE output_difference[possible_outputs],
78  TYPE dactivations[possible_outputs]) {
79  int i;
80  for( i = 0; i < possible_outputs; i++){
81  output_difference[i] = (((net_outputs[i]) - solutions[i]) * -1.0) * dactivations[i];
82  }
83 }
84 
86  TYPE output_difference[possible_outputs],
87  TYPE last_activations[nodes_per_layer]) {
88  int i, j;
89  for( i = 0; i < nodes_per_layer; i++) {
90  for( j = 0; j < possible_outputs; j++) {
91  delta_weights3[i*possible_outputs + j] = last_activations[i] * output_difference[j];
92  }
93  }
94 }
95 
97  TYPE output_differences[possible_outputs],
98  TYPE oracle_activations[nodes_per_layer],
99  TYPE dactivations[nodes_per_layer]) {
100  int i, j;
101  for( i = 0; i < nodes_per_layer; i++) {
102  oracle_activations[i] = (TYPE)0.0;
103  for( j = 0; j < possible_outputs; j++) {
104  oracle_activations[i] += output_differences[j] * weights3[i*possible_outputs + j];
105  }
106  oracle_activations[i] = oracle_activations[i] * dactivations[i];
107  }
108 }
109 
111  TYPE output_difference[nodes_per_layer],
112  TYPE last_activations[nodes_per_layer]) {
113  int i, j;
114  for( i = 0; i < nodes_per_layer; i++) {
115  for( j = 0; j < nodes_per_layer; j++) {
116  delta_weights2[i*nodes_per_layer + j] = last_activations[i] * output_difference[j];
117  }
118  }
119 }
120 
122  TYPE output_differences[nodes_per_layer],
123  TYPE oracle_activations[nodes_per_layer],
124  TYPE dactivations[nodes_per_layer]) {
125  int i, j;
126  for( i = 0; i < nodes_per_layer; i++) {
127  oracle_activations[i] = (TYPE)0.0;
128  for( j = 0; j < nodes_per_layer; j++) {
129  oracle_activations[i] += output_differences[j] * weights2[i*nodes_per_layer + j];
130  }
131  oracle_activations[i] = oracle_activations[i] * dactivations[i];
132  }
133 }
134 
136  TYPE output_difference[nodes_per_layer],
137  TYPE last_activations[input_dimension]) {
138  int i, j;
139  for( i = 0; i < input_dimension; i++) {
140  for( j = 0; j < nodes_per_layer; j++) {
141  delta_weights1[i*nodes_per_layer + j] = last_activations[i] * output_difference[j];
142  }
143  }
144 }
145 
147  TYPE weights2[nodes_per_layer*nodes_per_layer],
148  TYPE weights3[nodes_per_layer*possible_outputs],
149  TYPE d_weights1[input_dimension*nodes_per_layer],
150  TYPE d_weights2[nodes_per_layer*nodes_per_layer],
151  TYPE d_weights3[nodes_per_layer*possible_outputs],
152  TYPE biases1[nodes_per_layer],
153  TYPE biases2[nodes_per_layer],
154  TYPE biases3[possible_outputs],
155  TYPE d_biases1[nodes_per_layer],
156  TYPE d_biases2[nodes_per_layer],
157  TYPE d_biases3[possible_outputs]) {
158  int i, j;
159  double norm, bias_norm;
160  norm = 0.0;
161  bias_norm = 0.0;
162 
163  for(i=0; i < input_dimension; i++){
164  for(j = 0; j < nodes_per_layer; j++){
165  weights1[i*nodes_per_layer + j] -= (d_weights1[i*nodes_per_layer + j] * learning_rate);
166  norm += weights1[i*nodes_per_layer + j]*weights1[i*nodes_per_layer + j];
167  }
168  }
169  for(i=0; i < nodes_per_layer; i++){
170  biases1[i] -= (d_biases1[i]*learning_rate);
171  bias_norm += biases1[i]*biases1[i];
172  }
173 
174  norm = sqrt(norm);
175  bias_norm = sqrt(bias_norm);
176 
177  for(i=0; i < input_dimension; i++){
178  for(j = 0; j < nodes_per_layer; j++){
179  weights1[i*nodes_per_layer + j] = (weights1[i*nodes_per_layer + j]/norm);
180  }
181  }
182  for(i=0; i < nodes_per_layer; i++){
183  biases1[i] = (biases1[i]/bias_norm);
184  }
185 
186  norm = (double)0.0;
187  bias_norm = (double)0.0;
188 
189  for(i=0; i < nodes_per_layer; i++){
190  for(j = 0; j < nodes_per_layer; j++){
191  weights2[i*nodes_per_layer + j] -= (d_weights2[i*nodes_per_layer + j] * learning_rate);
192  norm += weights2[i*nodes_per_layer + j]*weights2[i*nodes_per_layer + j];
193  }
194  }
195  for(i=0; i < nodes_per_layer; i++){
196  biases2[i] -= (d_biases2[i]*learning_rate);
197  bias_norm += biases2[i]*biases2[i];
198  }
199 
200  norm = sqrt(norm);
201  bias_norm = sqrt(bias_norm);
202 
203  for(i=0; i < nodes_per_layer; i++){
204  for(j = 0; j < nodes_per_layer; j++){
205  weights2[i*nodes_per_layer + j] = (weights2[i*nodes_per_layer + j]/norm);
206  }
207  }
208  for(i=0; i < nodes_per_layer; i++){
209  biases2[i] = (biases2[i]/bias_norm);
210  }
211 
212  norm = (double)0.0;
213  bias_norm = (double)0.0;
214 
215  for(i=0; i < nodes_per_layer; i++){
216  for(j = 0; j < possible_outputs; j++){
217  weights3[i*possible_outputs + j] -= (d_weights3[i*possible_outputs + j] * learning_rate);
218  norm += weights3[i*possible_outputs + j]*weights3[i*possible_outputs + j];
219  }
220  }
221  for(i=0; i<possible_outputs;i++){
222  biases3[i] -= d_biases3[i]*learning_rate;
223  bias_norm += biases3[i]*biases3[i];
224  }
225 
226  norm = sqrt(norm);
227  bias_norm = sqrt(bias_norm);
228 
229  for(i=0; i < nodes_per_layer; i++){
230  for(j = 0; j < possible_outputs; j++){
231  weights3[i*possible_outputs + j] = (weights3[i*possible_outputs + j]/norm);
232  }
233  }
234  for(i=0; i < possible_outputs; i++){
235  biases3[i] = (biases3[i]/bias_norm);
236  }
237 }
238 
240  TYPE weights2[nodes_per_layer*nodes_per_layer],
241  TYPE weights3[nodes_per_layer*possible_outputs],
242  TYPE biases1[nodes_per_layer],
243  TYPE biases2[nodes_per_layer],
244  TYPE biases3[possible_outputs],
246  TYPE training_targets[training_sets*possible_outputs]) {
247  int i,j;
248  //Forward and training structures
249  TYPE activations1[nodes_per_layer];
250  TYPE activations2[nodes_per_layer];
251  TYPE activations3[possible_outputs];
252  TYPE dactivations1[nodes_per_layer];
253  TYPE dactivations2[nodes_per_layer];
254  TYPE dactivations3[possible_outputs];
255  TYPE net_outputs[possible_outputs];
256  //Training structure
257  TYPE output_difference[possible_outputs];
258  TYPE delta_weights1[input_dimension*nodes_per_layer];
259  TYPE delta_weights2[nodes_per_layer*nodes_per_layer];
260  TYPE delta_weights3[nodes_per_layer*possible_outputs];
261  TYPE oracle_activations1[nodes_per_layer];
262  TYPE oracle_activations2[nodes_per_layer];
263 
264  for(i=0; i<training_sets; i++){
265  for(j=0;j<nodes_per_layer;j++){
266  activations1[j] = (TYPE)0.0;
267  activations2[j] = (TYPE)0.0;
268  if(j<possible_outputs){
269  activations3[j] = (TYPE)0.0;
270  }
271  }
272  matrix_vector_product_with_bias_input_layer(biases1, weights1, activations1, &training_data[i*input_dimension]);
273  RELU(activations1, dactivations1, nodes_per_layer);
274  matrix_vector_product_with_bias_second_layer(biases2, weights2, activations2, activations1);
275  RELU(activations2, dactivations2, nodes_per_layer);
276  matrix_vector_product_with_bias_output_layer(biases3, weights3, activations3, activations2);
277  RELU(activations3, dactivations3, possible_outputs);
278  soft_max(net_outputs, activations3);
279  take_difference(net_outputs, &training_targets[i*possible_outputs], output_difference, dactivations3);
280  get_delta_matrix_weights3(delta_weights3, output_difference, activations2);
281  get_oracle_activations2(weights3, output_difference, oracle_activations2, dactivations2);
282  get_delta_matrix_weights2(delta_weights2, oracle_activations2, activations1);
283  get_oracle_activations1(weights2, oracle_activations2, oracle_activations1, dactivations1);
284  get_delta_matrix_weights1(delta_weights1, oracle_activations1, &training_data[i*input_dimension]);
285  update_weights(weights1, weights2, weights3, delta_weights1, delta_weights2, delta_weights3,
286  biases1, biases2, biases3, oracle_activations1, oracle_activations2, output_difference);
287  }
288 }
void matrix_vector_product_with_bias_output_layer(TYPE biases[possible_outputs], TYPE weights[nodes_per_layer *possible_outputs], TYPE activations[possible_outputs], TYPE input_activations[nodes_per_layer])
Definition: backprop.c:61
void take_difference(TYPE net_outputs[possible_outputs], TYPE solutions[possible_outputs], TYPE output_difference[possible_outputs], TYPE dactivations[possible_outputs])
Definition: backprop.c:75
#define input_dimension
Definition: backprop.h:7
void add_bias_to_activations(TYPE biases[nodes_per_layer], TYPE activations[nodes_per_layer], int size)
Definition: backprop.c:24
#define TYPE
Definition: backprop.h:21
TYPE weights1[input_dimension *nodes_per_layer]
Definition: backprop.h:38
void RELU(TYPE activations[nodes_per_layer], TYPE dactivations[nodes_per_layer], int size)
Definition: backprop.c:16
void get_delta_matrix_weights2(TYPE delta_weights2[nodes_per_layer *nodes_per_layer], TYPE output_difference[nodes_per_layer], TYPE last_activations[nodes_per_layer])
Definition: backprop.c:110
int sum
Definition: dotproduct.h:3
void get_delta_matrix_weights1(TYPE delta_weights1[input_dimension *nodes_per_layer], TYPE output_difference[nodes_per_layer], TYPE last_activations[input_dimension])
Definition: backprop.c:135
#define training_sets
Definition: backprop.h:9
TYPE biases3[possible_outputs]
Definition: backprop.h:43
#define possible_outputs
Definition: backprop.h:8
void backprop(TYPE weights1[input_dimension *nodes_per_layer], TYPE weights2[nodes_per_layer *nodes_per_layer], TYPE weights3[nodes_per_layer *possible_outputs], TYPE biases1[nodes_per_layer], TYPE biases2[nodes_per_layer], TYPE biases3[possible_outputs], TYPE training_data[training_sets *input_dimension], TYPE training_targets[training_sets *possible_outputs])
Definition: backprop.c:239
void get_oracle_activations1(TYPE weights2[nodes_per_layer *nodes_per_layer], TYPE output_differences[nodes_per_layer], TYPE oracle_activations[nodes_per_layer], TYPE dactivations[nodes_per_layer])
Definition: backprop.c:121
TYPE biases2[nodes_per_layer]
Definition: backprop.h:42
TYPE training_targets[training_sets *possible_outputs]
Definition: backprop.h:45
TYPE weights2[nodes_per_layer *nodes_per_layer]
Definition: backprop.h:39
TYPE biases1[nodes_per_layer]
Definition: backprop.h:41
void soft_max(TYPE net_outputs[possible_outputs], TYPE activations[possible_outputs])
Definition: backprop.c:3
TYPE weights3[nodes_per_layer *possible_outputs]
Definition: backprop.h:40
#define nodes_per_layer
Definition: backprop.h:10
void get_oracle_activations2(TYPE weights3[nodes_per_layer *possible_outputs], TYPE output_differences[possible_outputs], TYPE oracle_activations[nodes_per_layer], TYPE dactivations[nodes_per_layer])
Definition: backprop.c:96
void update_weights(TYPE weights1[input_dimension *nodes_per_layer], TYPE weights2[nodes_per_layer *nodes_per_layer], TYPE weights3[nodes_per_layer *possible_outputs], TYPE d_weights1[input_dimension *nodes_per_layer], TYPE d_weights2[nodes_per_layer *nodes_per_layer], TYPE d_weights3[nodes_per_layer *possible_outputs], TYPE biases1[nodes_per_layer], TYPE biases2[nodes_per_layer], TYPE biases3[possible_outputs], TYPE d_biases1[nodes_per_layer], TYPE d_biases2[nodes_per_layer], TYPE d_biases3[possible_outputs])
Definition: backprop.c:146
TYPE training_data[training_sets *input_dimension]
Definition: backprop.h:44
void matrix_vector_product_with_bias_input_layer(TYPE biases[nodes_per_layer], TYPE weights[input_dimension *nodes_per_layer], TYPE activations[nodes_per_layer], TYPE input_sample[input_dimension])
Definition: backprop.c:33
void matrix_vector_product_with_bias_second_layer(TYPE biases[nodes_per_layer], TYPE weights[nodes_per_layer *nodes_per_layer], TYPE activations[nodes_per_layer], TYPE input_activations[nodes_per_layer])
Definition: backprop.c:47
uint32_t exp
void get_delta_matrix_weights3(TYPE delta_weights3[nodes_per_layer *possible_outputs], TYPE output_difference[possible_outputs], TYPE last_activations[nodes_per_layer])
Definition: backprop.c:85
#define learning_rate
Definition: backprop.h:12

Generated on Mon Feb 12 2024 13:02:49 for PandA-2024.02 by doxygen 1.8.13