diff --git a/.gitignore b/.gitignore index 868ec50..01adc20 100644 --- a/.gitignore +++ b/.gitignore @@ -53,4 +53,6 @@ Kernel Module Compile Results modules.order Module.symvers Mkfile.old -dkms.conf \ No newline at end of file +dkms.conf +/.idea/.name +/.idea/misc.xml diff --git a/matrix.c b/matrix.c index e2f4416..62a82d7 100644 --- a/matrix.c +++ b/matrix.c @@ -248,21 +248,29 @@ Matrix* transpose(Matrix* matrix) { //file operations void matrix_save(Matrix* matrix, char* file_string){ - FILE *fptr = fopen(file_string, "w+"); - if(!fptr){ - printf("Unable to get handle for \"%s\"", file_string); + + // open the file in append mode + FILE *file = fopen(file_string, "a"); + + // check if the file could be found + if(file == NULL) { + printf("ERROR: Unable to get handle for \"%s\"! (matrix_save)", file_string); exit(1); } - fprintf(fptr, "%d\n", matrix->rows); - fprintf(fptr, "%d\n", matrix->columns); + // save the size of the matrix + fprintf(file, "%d\n", matrix->rows); + fprintf(file, "%d\n", matrix->columns); + + // save all the numbers of the matrix into the file for(int i = 0; i < matrix->rows; i++){ for(int j = 0; j < matrix->columns; j++){ - fprintf(fptr, "%.10f\n", matrix->numbers[i][j]); + fprintf(file, "%.10f\n", matrix->numbers[i][j]); } } - printf("saved matrix to %s", file_string); - fclose(fptr); + + // close the file + fclose(file); } Matrix* matrix_load(char* file_string){ diff --git a/neuronal_network.c b/neuronal_network.c new file mode 100644 index 0000000..6a352d6 --- /dev/null +++ b/neuronal_network.c @@ -0,0 +1,120 @@ +#include +#include "neuronal_network.h" +#include +#include + +Neural_Network* new_network(int input_size, int hidden_size, int output_size, double learning_rate){ + Neural_Network network = malloc(sizeof(Neural_Network)); + // initialize networks variables + network.input_size = input_size; + network.hidden_size = hidden_size; + network.output_size = output_size; + network.learning_rate = learning_rate; + + network.weights_1 = matrix_randomize(matrix_create(hidden_size, input_size)); + network.weights_2 = matrix_randomize(matrix_create(hidden_size, hidden_size)); + network.weights_3 = matrix_randomize(matrix_create(hidden_size, hidden_size)); + network.weights_output = matrix_randomize(matrix_create(output_size, hidden_size)); + network.bias_1 = matrix_randomize(matrix_create(hidden_size, 1)); + network.bias_2 = matrix_randomize(matrix_create(hidden_size, 1)); + network.bias_3 = matrix_randomize(matrix_create(hidden_size, 1)); + //network.bias_output = matrix_create(output_size, 1); // do we need it? + + return network; +} + +//void print_network(Neural_Network* network){}; + +void free_network(Neural_Network* network){ + matrix_free(network->weights_1); + matrix_free(network->weights_2); + matrix_free(network->weights_3); + matrix_free(network->weights_output); + matrix_free(network->bias_1); + matrix_free(network->bias_2); + matrix_free(network->bias_3); + free(network); +} + + +void save_network(Neural_Network* network) { + + // create file name and file string + time_t seconds; + time(&seconds); + char* file_name = "../networks/"; + sprintf(file_name, "%ld", seconds); + + // create file + FILE* save_file = fopen(file_name, "w"); + + // check if file is successfully opened + if(save_file == NULL) { + printf("ERROR: Something went wrong in file creation! (save_network)"); + exit(1); + } + + // save network size to first line of the file + fprintf(save_file, "%d\n", network->input_size); + fprintf(save_file, "%d\n", network->hidden_size); + fprintf(save_file, "%d\n", network->output_size); + + // close the file + fclose(file_name); + + // save first layer + matrix_save(network->bias_1, file_name); + matrix_save(network->weights_1, file_name); + + // save second layer + matrix_save(network->bias_2, file_name); + matrix_save(network->weights_2, file_name); + + // save third layer + matrix_save(network->bias_3, file_name); + matrix_save(network->weights_3, file_name); + + // save output weights + matrix_save(network->weights_output, file_name); + + printf("Network Saved!"); +} + +Neural_Network* load_network(char* file) { + +} + +double predict_images(Neural_Network* network, Image** images, int amount) { + int num_correct = 0; + for (int i = 0; i < amount; i++) { + Matrix* prediction = predict_image(network, images[i]); + if (matrix_argmax(prediction) == images[i]->image_label) { + num_correct++; + } + matrix_free(prediction); + } + return 1.0 * num_correct / amount; +} +Matrix* predict_image(Neural_Network* network, Image*); + +Matrix* predict(Neural_Network* network, Matrix* image_data) { + Matrix* hidden1_outputs = apply(relu, add(dot(network->weights_1, image_data), network->bias_1)); + + Matrix* hidden2_outputs = apply(relu, add(dot(network->weights_2, hidden1_outputs), network->bias_2)); + + Matrix* hidden3_outputs = apply(relu, add(dot(network->weights_3, hidden2_outputs), network->bias_3)); + + Matrix* final_outputs = apply(relu, dot(network->weights_output, hidden3_outputs)); + + Matrix* result = softmax(final_outputs); + + matrix_free(hidden1_outputs); + matrix_free(hidden2_outputs); + matrix_free(hidden3_outputs); + matrix_free(final_outputs); + + return result; +} + +void train_network(Neural_Network* network, Matrix* input, Matrix* output); +void batch_train_network(Neural_Network* network, Image** images, int size); \ No newline at end of file diff --git a/neuronal_network.cpp b/neuronal_network.cpp deleted file mode 100644 index dcd02e5..0000000 --- a/neuronal_network.cpp +++ /dev/null @@ -1,3 +0,0 @@ -// -// Created by danie on 19.09.2023. -// diff --git a/neuronal_network.h b/neuronal_network.h index c0d14c8..09ec61c 100644 --- a/neuronal_network.h +++ b/neuronal_network.h @@ -1,7 +1,40 @@ #pragma once -typedef struct { - Matrix* input; - Matrix* output; +#include "matrix.h" +#include "image.h" -} Neuronal_Network; \ No newline at end of file +typedef struct { + int input_size; + //Matrix* input; as local variable given to function + + // hidden layers + int hidden_size; + Matrix* weights_1; + Matrix* bias_1; + Matrix* weights_2; + Matrix* bias_2; + Matrix* weights_3; + Matrix* bias_3; + + int output_size; + Matrix* weights_output; + //Matrix* bias_output; // do we need it? + //Matrix* output; as local variable given to function + + double learning_rate; + +} Neural_Network; + +Neural_Network* new_network(int input_size, int hidden_size, int output_size, double learning_rate); +//void print_network(Neural_Network* network); +void free_network(Neural_Network* network); + +void save_network(Neural_Network* network); +Neural_Network* load_network(char* file); + +double predict_images(Neural_Network* network, Image** images, int amount); +Matrix* predict_image(Neural_Network* network, Image*); +Matrix* predict(Neural_Network* network, Matrix* image_data); + +void train_network(Neural_Network* network, Matrix* input, Matrix* output); +void batch_train_network(Neural_Network* network, Image** images, int size); \ No newline at end of file