Clean up (1)
This commit is contained in:
parent
f836c53711
commit
cf8b0a8b94
8 changed files with 312 additions and 302 deletions
|
|
@ -159,7 +159,6 @@ Image** import_images(char* image_file_string, char* label_file_string, int* _nu
|
|||
}
|
||||
|
||||
void img_print (Image* img) {
|
||||
|
||||
//print the image
|
||||
matrix_print(img->pixel_values);
|
||||
//print the number of the image
|
||||
|
|
|
|||
|
|
@ -1,6 +1,3 @@
|
|||
#pragma once
|
||||
#include "../matrix/matrix.h"
|
||||
|
||||
#include "../matrix/matrix.h"
|
||||
|
||||
typedef struct {
|
||||
|
|
@ -14,19 +11,11 @@ typedef struct {
|
|||
} Image_Container;
|
||||
|
||||
static const int MAGIC_NUMBER_LABEL = 2049;
|
||||
|
||||
static const int MAGIC_NUMBER_IMAGES = 2051;
|
||||
|
||||
/**
|
||||
* reads a specified number of images out of the training dataset
|
||||
* @param image_file_string Path to the file containing the image data
|
||||
* @param label_file_string Path to the file containing the image labels
|
||||
* @param ptr via this pointer, the images can be accessed
|
||||
* @param count maximum number of images to be loaded. If it is 0, all available images are loaded.
|
||||
* @return
|
||||
*/
|
||||
Image ** import_images(char* image_file_string, char* label_file_string, int* number_imported, int count);
|
||||
Image * load_pgm_image(char * image_file_string);
|
||||
void img_print (Image* image);
|
||||
void img_visualize(Image*image);
|
||||
void img_free (Image* image);
|
||||
void images_free (Image** images, int quantity);
|
||||
57
main.c
57
main.c
|
|
@ -4,26 +4,61 @@
|
|||
#include "neuronal_network.h"
|
||||
|
||||
int main() {
|
||||
Image** images = import_images("../data/train-images.idx3-ubyte", "../data/train-labels.idx1-ubyte", NULL, 60000);
|
||||
|
||||
const int amount_of_images_to_load = 60000;
|
||||
const int amount_of_images_used_to_train = 30000;
|
||||
const int amount_of_images_used_to_test = 1000;
|
||||
const int input_size = 28*28;
|
||||
const int hidden_layer_size = 50;
|
||||
const int hidden_layer_count = 3;
|
||||
const double learning_rate = 0.1;
|
||||
|
||||
/*
|
||||
* Loading Images from Dataset
|
||||
*/
|
||||
|
||||
Image** images = import_images("../data/train-images.idx3-ubyte", "../data/train-labels.idx1-ubyte", NULL, amount_of_images_to_load);
|
||||
|
||||
// img_visualize(images[0]);
|
||||
// img_visualize(images[1]);
|
||||
// img_print(images[0]);
|
||||
|
||||
// matrix_print(images[0]->pixel_values);
|
||||
// matrix_print(images[1]->pixel_values);
|
||||
/*
|
||||
* Create a new network and randomize the weights
|
||||
*/
|
||||
|
||||
Neural_Network* nn = new_network(28*28, 50, 3, 10, 0.1);
|
||||
randomize_network(nn, 1);
|
||||
// Neural_Network* nn = load_network("../networks/newest_network.txt");
|
||||
Neural_Network* network = new_network(input_size, hidden_layer_size, hidden_layer_count, 10, learning_rate);
|
||||
randomize_network(network, 1);
|
||||
|
||||
for (int i = 0; i < 60000; ++i) {
|
||||
train_network(nn, images[i], images[i]->label);
|
||||
/*
|
||||
* Training
|
||||
*/
|
||||
|
||||
for (int i = 0; i < amount_of_images_used_to_train; i++) {
|
||||
train_network(network, images[i], images[i]->label);
|
||||
}
|
||||
|
||||
// Batch training works if you change the train_network method, but the results are not that good (needs further testing)
|
||||
// batch_train(nn, images, 30000, 2);
|
||||
|
||||
printf("Trinaing Done!\n");
|
||||
|
||||
// save_network(nn);
|
||||
/*
|
||||
* Saving and Loading
|
||||
*/
|
||||
|
||||
printf("%lf\n", measure_network_accuracy(nn, images, 10000));
|
||||
// save_network(network);
|
||||
// Neural_Network* network = load_network("../networks/newest_network.txt");
|
||||
|
||||
/*
|
||||
* Measure Accuracy & predict single images
|
||||
*/
|
||||
|
||||
printf("Accuracy: %lf\n", measure_network_accuracy(network, images, amount_of_images_used_to_test));
|
||||
|
||||
// matrix_print(predict_image(network, images[0]));
|
||||
|
||||
images_free(images, amount_of_images_to_load);
|
||||
free_network(network);
|
||||
|
||||
return 0;
|
||||
}
|
||||
255
matrix/matrix.c
255
matrix/matrix.c
|
|
@ -1,12 +1,9 @@
|
|||
#include "matrix.h"
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include <time.h>
|
||||
|
||||
#define MAX_BYTES 100
|
||||
|
||||
static int RANDOMIZED = 0;
|
||||
// operational functions
|
||||
Matrix* matrix_create(int rows, int columns) {
|
||||
|
||||
// allocate memory for the matrix
|
||||
|
|
@ -80,175 +77,6 @@ Matrix* matrix_copy(Matrix *matrix) {
|
|||
return copy_of_matrix;
|
||||
}
|
||||
|
||||
// mathematical functions
|
||||
|
||||
/*
|
||||
* These methods won't change or free the input matrix.
|
||||
* It creates a new matrix, which is modified and then returned.
|
||||
* If we don't need the original matrix, we should consider just changing the original matrix and changing the method signature to void.
|
||||
*/
|
||||
|
||||
Matrix* multiply(Matrix* matrix1, Matrix* matrix2) {
|
||||
|
||||
// check if the two matrices are of the same size
|
||||
if(matrix1->rows != matrix2->rows || matrix1->columns != matrix2->columns) {
|
||||
printf("ERROR: Size of matrices are not compatible! (Multiply)");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// create result matrix
|
||||
Matrix* result_matrix = matrix_create(matrix1->rows, matrix1->columns);
|
||||
|
||||
// multiply the values and save them into the result matrix
|
||||
for (int i = 0; i < matrix1->rows; i++) {
|
||||
for (int j = 0; j < matrix1->columns; j++) {
|
||||
result_matrix->numbers[i][j] = matrix1->numbers[i][j] * matrix2->numbers[i][j];
|
||||
}
|
||||
}
|
||||
|
||||
// return resulting matrix
|
||||
return result_matrix;
|
||||
}
|
||||
|
||||
Matrix* add(Matrix* matrix1, Matrix* matrix2) {
|
||||
|
||||
// check if the two matrices are of the same size
|
||||
if(matrix1->rows != matrix2->rows || matrix1->columns != matrix2->columns) {
|
||||
printf("ERROR: Size of matrices are not compatible! (Add)");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// create result matrix
|
||||
Matrix* result_matrix = matrix_create(matrix1->rows, matrix1->columns);
|
||||
|
||||
// add the value of the number in matrix 1 to the value of the number in matrix 2
|
||||
for (int i = 0; i < matrix1->rows; i++) {
|
||||
for (int j = 0; j < matrix1->columns; j++) {
|
||||
result_matrix->numbers[i][j] = matrix1->numbers[i][j] + matrix2->numbers[i][j];
|
||||
}
|
||||
}
|
||||
|
||||
// return the result matrix
|
||||
return result_matrix;
|
||||
}
|
||||
|
||||
Matrix* subtract(Matrix* matrix1, Matrix* matrix2) {
|
||||
|
||||
// check if the two matrices are of the same size
|
||||
if(matrix1->rows != matrix2->rows || matrix1->columns != matrix2->columns) {
|
||||
printf("ERROR: Size of matrices are not compatible! (Subtract)");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// create result matrix
|
||||
Matrix* result_matrix = matrix_create(matrix1->rows, matrix1->columns);
|
||||
|
||||
// subtract the value of the number in matrix 2 from the value of the number in matrix 1
|
||||
for (int i = 0; i < matrix1->rows; i++) {
|
||||
for (int j = 0; j < matrix1->columns; j++) {
|
||||
result_matrix->numbers[i][j] = matrix1->numbers[i][j] - matrix2->numbers[i][j];
|
||||
}
|
||||
}
|
||||
|
||||
// return the resulting matrix
|
||||
return result_matrix;
|
||||
}
|
||||
|
||||
Matrix* dot(Matrix* matrix1, Matrix* matrix2) {
|
||||
|
||||
// check if the dimensions of the matrices are compatible to calculate the dot product
|
||||
if(matrix1->columns != matrix2->rows) {
|
||||
printf("ERROR: Size of matrices are not compatible! (Dot-Product)");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// create a new matrix with the dimensions of the dot product;
|
||||
Matrix* result_matrix = matrix_create(matrix1->rows, matrix2->columns);
|
||||
|
||||
// iterate through all rows of matrix 1
|
||||
for (int i = 0; i < matrix1->rows; i++) {
|
||||
|
||||
// iterate though all columns of matrix 2
|
||||
for (int j = 0; j < matrix2->columns; j++) {
|
||||
|
||||
// sum up the products and save them into the result matrix
|
||||
result_matrix->numbers[i][j] = 0;
|
||||
for (int k = 0; k < matrix2->rows; k++) {
|
||||
result_matrix->numbers[i][j] += matrix1->numbers[i][k] * matrix2->numbers[k][j];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// return result
|
||||
return result_matrix;
|
||||
}
|
||||
|
||||
Matrix* apply(double (*function)(double), Matrix* matrix) {
|
||||
|
||||
// create a new matrix used to calculate the result
|
||||
Matrix* result_matrix = matrix_create(matrix->rows, matrix->columns);
|
||||
|
||||
// apply the function to all values in the matrix
|
||||
for (int i = 0; i < matrix->rows; i++) {
|
||||
for (int j = 0; j < matrix->columns; j++) {
|
||||
result_matrix->numbers[i][j] = (*function)(matrix->numbers[i][j]);
|
||||
int k = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// return resulting matrix
|
||||
return result_matrix;
|
||||
}
|
||||
|
||||
Matrix* scale(Matrix* matrix, double value) {
|
||||
|
||||
// create a copy of the original matrix
|
||||
Matrix* result_matrix = matrix_copy(matrix);
|
||||
|
||||
// iterate over all numbers in the matrix and multiply by the scalar value
|
||||
for (int i = 0; i < result_matrix->rows; i++) {
|
||||
for (int j = 0; j < result_matrix->columns; j++) {
|
||||
result_matrix->numbers[i][j] *= value;
|
||||
}
|
||||
}
|
||||
|
||||
// return the copy
|
||||
return result_matrix;
|
||||
}
|
||||
|
||||
Matrix* addScalar(Matrix* matrix, double value) {
|
||||
|
||||
// create a copy of the original matrix
|
||||
Matrix* result_matrix = matrix_copy(matrix);
|
||||
|
||||
// iterate over all numbers in the matrix and add the scalar value
|
||||
for (int i = 0; i < result_matrix->rows; i++) {
|
||||
for (int j = 0; j < result_matrix->columns; j++) {
|
||||
result_matrix->numbers[i][j] += value;
|
||||
}
|
||||
}
|
||||
|
||||
// return the copy
|
||||
return result_matrix;
|
||||
}
|
||||
|
||||
Matrix* transpose(Matrix* matrix) {
|
||||
|
||||
// create a new matrix of the size n-m, based on the original matrix of size m-n
|
||||
Matrix* result_matrix = matrix_create(matrix->columns, matrix->rows);
|
||||
|
||||
// copy the values from the original into the correct place in the copy
|
||||
for (int i = 0; i < matrix->rows; i++) {
|
||||
for (int j = 0; j < matrix->columns; j++) {
|
||||
result_matrix->numbers[j][i] = matrix->numbers[i][j];
|
||||
}
|
||||
}
|
||||
|
||||
// return the result matrix
|
||||
return result_matrix;
|
||||
|
||||
}
|
||||
|
||||
void matrix_save(Matrix* matrix, char* file_string){
|
||||
|
||||
// open the file in append mode
|
||||
|
|
@ -309,84 +137,3 @@ Matrix* load_next_matrix(FILE *save_file){
|
|||
}
|
||||
return matrix;
|
||||
}
|
||||
|
||||
Matrix* matrix_flatten(Matrix* matrix, int axis) {
|
||||
// Axis = 0 -> Column Vector, Axis = 1 -> Row Vector
|
||||
Matrix* result_matrix;
|
||||
// Column Vector
|
||||
if (axis == 0) {
|
||||
result_matrix = matrix_create(matrix -> rows * matrix -> columns, 1);
|
||||
}
|
||||
// Row Vector
|
||||
else if (axis == 1) {
|
||||
result_matrix = matrix_create(1, matrix -> rows * matrix -> columns);
|
||||
} else {
|
||||
printf("ERROR: Argument must be 1 or 0 (matrix_flatten)");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
for (int i = 0; i < matrix->rows; i++) {
|
||||
for (int j = 0; j < matrix->columns; j++) {
|
||||
if (axis == 0) result_matrix->numbers[i * matrix->columns + j][0] = matrix->numbers[i][j];
|
||||
else if (axis == 1) result_matrix->numbers[0][i * matrix->columns + j] = matrix->numbers[i][j];
|
||||
}
|
||||
}
|
||||
return result_matrix;
|
||||
}
|
||||
|
||||
int matrix_argmax(Matrix* matrix) {
|
||||
// Expects a Mx1 matrix
|
||||
if (matrix->columns != 1){
|
||||
printf("ERROR: Matrix is not Mx1 (matrix_argmax)");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
double max_value = 0;
|
||||
int max_index = 0;
|
||||
|
||||
for (int i = 0; i < matrix->rows; i++) {
|
||||
if (matrix->numbers[i][0] > max_value) {
|
||||
max_value = matrix->numbers[i][0];
|
||||
max_index = i;
|
||||
}
|
||||
}
|
||||
return max_index;
|
||||
}
|
||||
|
||||
void matrix_randomize(Matrix* matrix, int n) {
|
||||
|
||||
if(!RANDOMIZED){
|
||||
srand(time(NULL));
|
||||
RANDOMIZED = 1;
|
||||
}
|
||||
//make a min and max
|
||||
double min = -1.0f / sqrt(n);
|
||||
double max = 1.0f / sqrt(n);
|
||||
|
||||
//calculate difference
|
||||
double difference = max - min;
|
||||
|
||||
//move decimal
|
||||
int scaled_difference = (int)(difference * scaling_value);
|
||||
|
||||
for (int i = 0; i < matrix->rows; i++) {
|
||||
for (int j = 0; j < matrix->columns; j++) {
|
||||
matrix->numbers[i][j] = min + (1.0 * (rand() % scaled_difference) / scaling_value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Matrix* matrix_add_bias(Matrix* matrix) {
|
||||
if(matrix->columns != 1) {
|
||||
printf("ERROR: The size of the matrix does not match an input matrix! (matrix_add_bias)");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
Matrix* result = matrix_create(matrix->rows + 1, matrix->columns);
|
||||
|
||||
result->numbers[0][0] = 1.0;
|
||||
for (int i = 0; i < matrix->rows; ++i) {
|
||||
result->numbers[i + 1][0] = matrix->numbers[i][0];
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
|
@ -1,4 +1,3 @@
|
|||
#pragma once
|
||||
#include <stdio.h>
|
||||
|
||||
typedef struct {
|
||||
|
|
@ -6,8 +5,6 @@ typedef struct {
|
|||
double **numbers;
|
||||
} Matrix;
|
||||
|
||||
static const int scaling_value = 10000;
|
||||
|
||||
Matrix* matrix_create(int rows, int columns);
|
||||
void matrix_fill(Matrix* matrix, double value);
|
||||
void matrix_free(Matrix* matrix);
|
||||
|
|
@ -16,17 +13,3 @@ Matrix* matrix_copy(Matrix *matrix);
|
|||
void matrix_save(Matrix* matrix, char* file_string);
|
||||
Matrix* matrix_load(char* file_string);
|
||||
Matrix* load_next_matrix(FILE * save_file);
|
||||
|
||||
void matrix_randomize(Matrix* matrix, int n);
|
||||
int matrix_argmax(Matrix* matrix);
|
||||
Matrix* matrix_flatten(Matrix* matrix, int axis);
|
||||
Matrix* matrix_add_bias(Matrix* matrix);
|
||||
|
||||
Matrix* multiply(Matrix* matrix1, Matrix* matrix2);
|
||||
Matrix* add(Matrix* matrix1, Matrix* matrix2);
|
||||
Matrix* subtract(Matrix* matrix1, Matrix* matrix2);
|
||||
Matrix* dot(Matrix* matrix1, Matrix* matrix2);
|
||||
Matrix* apply(double (*function)(double), Matrix* matrix);
|
||||
Matrix* scale(Matrix* matrix, double value);
|
||||
Matrix* addScalar(Matrix* matrix, double value);
|
||||
Matrix* transpose(Matrix* matrix);
|
||||
|
|
@ -1 +1,233 @@
|
|||
#include <process.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include "math.h"
|
||||
#include "operations.h"
|
||||
|
||||
static int RANDOMIZED = 0;
|
||||
|
||||
Matrix* multiply(Matrix* matrix1, Matrix* matrix2) {
|
||||
|
||||
// check if the two matrices are of the same size
|
||||
if(matrix1->rows != matrix2->rows || matrix1->columns != matrix2->columns) {
|
||||
printf("ERROR: Size of matrices are not compatible! (Multiply)");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// create result matrix
|
||||
Matrix* result_matrix = matrix_create(matrix1->rows, matrix1->columns);
|
||||
|
||||
// multiply the values and save them into the result matrix
|
||||
for (int i = 0; i < matrix1->rows; i++) {
|
||||
for (int j = 0; j < matrix1->columns; j++) {
|
||||
result_matrix->numbers[i][j] = matrix1->numbers[i][j] * matrix2->numbers[i][j];
|
||||
}
|
||||
}
|
||||
|
||||
// return resulting matrix
|
||||
return result_matrix;
|
||||
}
|
||||
|
||||
Matrix* add(Matrix* matrix1, Matrix* matrix2) {
|
||||
|
||||
// check if the two matrices are of the same size
|
||||
if(matrix1->rows != matrix2->rows || matrix1->columns != matrix2->columns) {
|
||||
printf("ERROR: Size of matrices are not compatible! (Add)");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// create result matrix
|
||||
Matrix* result_matrix = matrix_create(matrix1->rows, matrix1->columns);
|
||||
|
||||
// add the value of the number in matrix 1 to the value of the number in matrix 2
|
||||
for (int i = 0; i < matrix1->rows; i++) {
|
||||
for (int j = 0; j < matrix1->columns; j++) {
|
||||
result_matrix->numbers[i][j] = matrix1->numbers[i][j] + matrix2->numbers[i][j];
|
||||
}
|
||||
}
|
||||
|
||||
// return the result matrix
|
||||
return result_matrix;
|
||||
}
|
||||
|
||||
Matrix* subtract(Matrix* matrix1, Matrix* matrix2) {
|
||||
|
||||
// check if the two matrices are of the same size
|
||||
if(matrix1->rows != matrix2->rows || matrix1->columns != matrix2->columns) {
|
||||
printf("ERROR: Size of matrices are not compatible! (Subtract)");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// create result matrix
|
||||
Matrix* result_matrix = matrix_create(matrix1->rows, matrix1->columns);
|
||||
|
||||
// subtract the value of the number in matrix 2 from the value of the number in matrix 1
|
||||
for (int i = 0; i < matrix1->rows; i++) {
|
||||
for (int j = 0; j < matrix1->columns; j++) {
|
||||
result_matrix->numbers[i][j] = matrix1->numbers[i][j] - matrix2->numbers[i][j];
|
||||
}
|
||||
}
|
||||
|
||||
// return the resulting matrix
|
||||
return result_matrix;
|
||||
}
|
||||
|
||||
Matrix* dot(Matrix* matrix1, Matrix* matrix2) {
|
||||
|
||||
// check if the dimensions of the matrices are compatible to calculate the dot product
|
||||
if(matrix1->columns != matrix2->rows) {
|
||||
printf("ERROR: Size of matrices are not compatible! (Dot-Product)");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// create a new matrix with the dimensions of the dot product;
|
||||
Matrix* result_matrix = matrix_create(matrix1->rows, matrix2->columns);
|
||||
|
||||
// iterate through all rows of matrix 1
|
||||
for (int i = 0; i < matrix1->rows; i++) {
|
||||
|
||||
// iterate though all columns of matrix 2
|
||||
for (int j = 0; j < matrix2->columns; j++) {
|
||||
|
||||
// sum up the products and save them into the result matrix
|
||||
result_matrix->numbers[i][j] = 0;
|
||||
for (int k = 0; k < matrix2->rows; k++) {
|
||||
result_matrix->numbers[i][j] += matrix1->numbers[i][k] * matrix2->numbers[k][j];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// return result
|
||||
return result_matrix;
|
||||
}
|
||||
|
||||
Matrix* apply(double (*function)(double), Matrix* matrix) {
|
||||
|
||||
// create a new matrix used to calculate the result
|
||||
Matrix* result_matrix = matrix_create(matrix->rows, matrix->columns);
|
||||
|
||||
// apply the function to all values in the matrix
|
||||
for (int i = 0; i < matrix->rows; i++) {
|
||||
for (int j = 0; j < matrix->columns; j++) {
|
||||
result_matrix->numbers[i][j] = (*function)(matrix->numbers[i][j]);
|
||||
int k = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// return resulting matrix
|
||||
return result_matrix;
|
||||
}
|
||||
|
||||
Matrix* scale(Matrix* matrix, double value) {
|
||||
|
||||
// create a copy of the original matrix
|
||||
Matrix* result_matrix = matrix_copy(matrix);
|
||||
|
||||
// iterate over all numbers in the matrix and multiply by the scalar value
|
||||
for (int i = 0; i < result_matrix->rows; i++) {
|
||||
for (int j = 0; j < result_matrix->columns; j++) {
|
||||
result_matrix->numbers[i][j] *= value;
|
||||
}
|
||||
}
|
||||
|
||||
// return the copy
|
||||
return result_matrix;
|
||||
}
|
||||
|
||||
Matrix* transpose(Matrix* matrix) {
|
||||
|
||||
// create a new matrix of the size n-m, based on the original matrix of size m-n
|
||||
Matrix* result_matrix = matrix_create(matrix->columns, matrix->rows);
|
||||
|
||||
// copy the values from the original into the correct place in the copy
|
||||
for (int i = 0; i < matrix->rows; i++) {
|
||||
for (int j = 0; j < matrix->columns; j++) {
|
||||
result_matrix->numbers[j][i] = matrix->numbers[i][j];
|
||||
}
|
||||
}
|
||||
|
||||
// return the result matrix
|
||||
return result_matrix;
|
||||
|
||||
}
|
||||
|
||||
Matrix* matrix_flatten(Matrix* matrix, int axis) {
|
||||
// Axis = 0 -> Column Vector, Axis = 1 -> Row Vector
|
||||
Matrix* result_matrix;
|
||||
// Column Vector
|
||||
if (axis == 0) {
|
||||
result_matrix = matrix_create(matrix -> rows * matrix -> columns, 1);
|
||||
}
|
||||
// Row Vector
|
||||
else if (axis == 1) {
|
||||
result_matrix = matrix_create(1, matrix -> rows * matrix -> columns);
|
||||
} else {
|
||||
printf("ERROR: Argument must be 1 or 0 (matrix_flatten)");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
for (int i = 0; i < matrix->rows; i++) {
|
||||
for (int j = 0; j < matrix->columns; j++) {
|
||||
if (axis == 0) result_matrix->numbers[i * matrix->columns + j][0] = matrix->numbers[i][j];
|
||||
else if (axis == 1) result_matrix->numbers[0][i * matrix->columns + j] = matrix->numbers[i][j];
|
||||
}
|
||||
}
|
||||
return result_matrix;
|
||||
}
|
||||
|
||||
int argmax(Matrix* matrix) {
|
||||
// Expects a Mx1 matrix
|
||||
if (matrix->columns != 1){
|
||||
printf("ERROR: Matrix is not Mx1 (argmax)");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
double max_value = 0;
|
||||
int max_index = 0;
|
||||
|
||||
for (int i = 0; i < matrix->rows; i++) {
|
||||
if (matrix->numbers[i][0] > max_value) {
|
||||
max_value = matrix->numbers[i][0];
|
||||
max_index = i;
|
||||
}
|
||||
}
|
||||
return max_index;
|
||||
}
|
||||
|
||||
void matrix_randomize(Matrix* matrix, int n) {
|
||||
|
||||
if(!RANDOMIZED){
|
||||
srand(time(NULL));
|
||||
RANDOMIZED = 1;
|
||||
}
|
||||
//make a min and max
|
||||
double min = -1.0f / sqrt(n);
|
||||
double max = 1.0f / sqrt(n);
|
||||
|
||||
//calculate difference
|
||||
double difference = max - min;
|
||||
|
||||
//move decimal
|
||||
int scaled_difference = (int)(difference * scaling_value);
|
||||
|
||||
for (int i = 0; i < matrix->rows; i++) {
|
||||
for (int j = 0; j < matrix->columns; j++) {
|
||||
matrix->numbers[i][j] = min + (1.0 * (rand() % scaled_difference) / scaling_value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Matrix* matrix_add_bias(Matrix* matrix) {
|
||||
if(matrix->columns != 1) {
|
||||
printf("ERROR: The size of the matrix does not match an input matrix! (matrix_add_bias)");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
Matrix* result = matrix_create(matrix->rows + 1, matrix->columns);
|
||||
|
||||
result->numbers[0][0] = 1.0;
|
||||
for (int i = 0; i < matrix->rows; ++i) {
|
||||
result->numbers[i + 1][0] = matrix->numbers[i][0];
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
|
@ -1 +1,25 @@
|
|||
#include "matrix.h"
|
||||
|
||||
static const int scaling_value = 10000;
|
||||
|
||||
Matrix* multiply(Matrix* matrix1, Matrix* matrix2);
|
||||
|
||||
Matrix* add(Matrix* matrix1, Matrix* matrix2); //only used in the batch_training method
|
||||
|
||||
Matrix* subtract(Matrix* matrix1, Matrix* matrix2);
|
||||
|
||||
Matrix* dot(Matrix* matrix1, Matrix* matrix2);
|
||||
|
||||
Matrix* apply(double (*function)(double), Matrix* matrix);
|
||||
|
||||
Matrix* scale(Matrix* matrix, double value);
|
||||
|
||||
Matrix* transpose(Matrix* matrix);
|
||||
|
||||
Matrix* matrix_flatten(Matrix* matrix, int axis);
|
||||
|
||||
int argmax(Matrix* matrix);
|
||||
|
||||
void matrix_randomize(Matrix* matrix, int n);
|
||||
|
||||
Matrix* matrix_add_bias(Matrix* matrix);
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
#include <stdlib.h>
|
||||
#include "neuronal_network.h"
|
||||
#include "matrix\operations.h"
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
|
||||
|
|
@ -120,7 +121,7 @@ double measure_network_accuracy(Neural_Network* network, Image** images, int amo
|
|||
for (int i = 0; i < amount; i++) {
|
||||
Matrix* prediction = predict_image(network, images[i]);
|
||||
|
||||
int guess = matrix_argmax(prediction);
|
||||
int guess = argmax(prediction);
|
||||
int answer = (unsigned char) images[i]->label;
|
||||
|
||||
if (guess == answer) {
|
||||
|
|
|
|||
Reference in a new issue