-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.c
More file actions
114 lines (88 loc) · 3.34 KB
/
main.c
File metadata and controls
114 lines (88 loc) · 3.34 KB
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
#include <stdio.h>
#include <stdlib.h>
#include "nn/structs.h"
#include "nn/nn.h"
#include "nn/activation.h"
#include "data_loader.h"
#include <string.h>
#define TRAIN_IMAGES "Datasets/MNIST/train-images-idx3-ubyte/train-images-idx3-ubyte"
#define TRAIN_LABELS "Datasets/MNIST/train-labels-idx1-ubyte/train-labels-idx1-ubyte"
#define IMAGE_SIZE 28*28
#define TEST_IMAGES "Datasets/MNIST/t10k-images.idx3-ubyte"
#define TEST_LABELS "Datasets/MNIST/t10k-labels.idx1-ubyte"
int get_predicted_class(float *output, int size) {
int predicted_class = 0;
float max_value = output[0];
// Find the index of the maximum value in the output array
for (int i = 1; i < size; i++) {
if (output[i] > max_value) {
max_value = output[i];
predicted_class = i;
}
}
return predicted_class;
}
int main(){
unsigned char *labels;
float *images;
int num_images, num_labels;
load_mnist_images(TRAIN_IMAGES, &images, &num_images);
printf("Num of images: %d\n", num_images);
load_mnist_labels(TRAIN_LABELS, &labels, &num_labels);
printf("Num of labels: %d\n", num_labels);
for (int i = 0; i < 1; ++i){
print_mnist_index(images, labels, i);
}
//one hot encoding
float *one_hot_matrix = (float *)malloc(num_labels * 10 * sizeof(float));
one_hot_encode(labels, num_labels, one_hot_matrix, 10);
// create layers
unsigned int epochs = 5;
FCLayer *layer1 = init_fc_layer(IMAGE_SIZE, 128, ReLU);
FCLayer *layer2 = init_fc_layer(128, 10, SOFTMAX);
for (int j = 0; j < epochs; j++){
int num_correct = 0;
for (int i = 0; i < 60000; ++i){
fc_forward(layer1, images+(IMAGE_SIZE*i));
fc_forward_softmax(layer2, layer1->output);
// find d_output
float *d_output = derivative_softmax_categorical_cross_entropy(layer2->output, one_hot_matrix+(10*i), 10);
fc_backward(layer2, d_output);
fc_backward(layer1, layer2->d_input);
// calculate loss
float loss = categorical_cross_entropy(layer2->output, one_hot_matrix+(10*i), layer2->output_size);
if (*(labels+(i)) == get_predicted_class(layer2->output, 10))
num_correct++;
if (i % 5 == 0)
printf("epoch: %d, loss, %f, actual: %d, predicted: %d, accuracy: %f\n", j+1, loss, *(labels+(i)), get_predicted_class(layer2->output, 10), num_correct/(float)i);
// update weights
float learning_rate = 0.001f;
update_weights(layer2, learning_rate);
update_weights(layer1, learning_rate);
free(d_output);
}
}
// load the training data
unsigned char *test_labels;
float *test_images;
load_mnist_images(TEST_IMAGES, &test_images, &num_images);
printf("Num of images: %d\n", num_images);
load_mnist_labels(TEST_LABELS, &test_labels, &num_labels);
printf("Num of labels: %d\n", num_labels);
//one hot encoding
float *test_one_hot_matrix = (float *)malloc(num_labels * 10 * sizeof(float));
one_hot_encode(test_labels, num_labels, test_one_hot_matrix, 10);
int num_correct = 0;
for (int i = 0; i < 10000; ++i){
fc_forward(layer1, test_images+(IMAGE_SIZE*i));
fc_forward_softmax(layer2, layer1->output);
if (*(test_labels+(i)) == get_predicted_class(layer2->output, 10))
num_correct++;
if (i % 5 == 0)
printf("accuracy: %f, actual: %d, predicted: %d\n", num_correct/10000.0f, *(test_labels+(i)), get_predicted_class(layer2->output, 10));
}
// Free allocated memory
free(one_hot_matrix);
free(images);
free(labels);
}