This commit is contained in:
julienChemillier 2023-01-30 09:39:45 +01:00
parent f4975e8812
commit 46ce52802e
10 changed files with 82 additions and 10 deletions

View File

@ -82,6 +82,7 @@ void backward_linearisation(Kernel_nn* ker, float*** input, float*** input_z, fl
// Weights
int cpt = 0;
int nb_elem = depth_input*dim_input*dim_input*size_output;
for (int i=0; i < depth_input; i++) {
for (int k=0; k < dim_input; k++) {
for (int l=0; l < dim_input; l++) {

View File

@ -76,7 +76,7 @@ void write_image_in_network_260(unsigned char* image, int height, int width, flo
}
void forward_propagation(Network* network) {
int activation, input_depth, input_width, output_depth, output_width;
int activation, pooling, input_depth, input_width, output_depth, output_width;
int n = network->size;
float*** input;
float*** output;
@ -93,6 +93,7 @@ void forward_propagation(Network* network) {
output_depth = network->depth[i+1];
output_width = network->width[i+1];
activation = k_i->activation;
pooling = k_i->pooling;
if (k_i->nn) {
drop_neurones(input, 1, 1, input_width, network->dropout);
@ -119,7 +120,13 @@ void forward_propagation(Network* network) {
printf("Le réseau ne peut pas finir par une pooling layer\n");
return;
} else { // Pooling sur une matrice
make_average_pooling(input, output, activation, output_depth, output_width);
if (pooling==1) {
make_average_pooling(input, output, activation, output_depth, output_width);
} else if (pooling==2) {
make_max_pooling(input, output, activation, output_depth, output_width);
} else {
printf("Erreur dans la reconnaissance de la couche de pooling: %d,%d \n", pooling, i);
}
}
copy_input_to_input_z(output, output_a, output_depth, output_width, output_width);
}

View File

@ -24,6 +24,7 @@ Network* create_network(int max_size, float learning_rate, int dropout, int init
for (int i=0; i < max_size-1; i++) {
network->kernel[i] = (Kernel*)malloc(sizeof(Kernel));
}
network->kernel[0]->linearisation = 0;
network->width[0] = input_dim;
network->depth[0] = input_depth;
network->kernel[0]->nn = NULL;
@ -36,7 +37,6 @@ Network* create_network(int max_size, float learning_rate, int dropout, int init
Network* create_network_lenet5(float learning_rate, int dropout, int activation, int initialisation, int input_dim, int input_depth) {
Network* network = create_network(8, learning_rate, dropout, initialisation, input_dim, input_depth);
network->kernel[0]->activation = activation;
network->kernel[0]->linearisation = 0;
add_convolution(network, 6, 28, activation);
add_2d_average_pooling(network, 14);
add_convolution(network, 16, 10, activation);
@ -50,7 +50,6 @@ Network* create_network_lenet5(float learning_rate, int dropout, int activation,
Network* create_simple_one(float learning_rate, int dropout, int activation, int initialisation, int input_dim, int input_depth) {
Network* network = create_network(3, learning_rate, dropout, initialisation, input_dim, input_depth);
network->kernel[0]->activation = activation;
network->kernel[0]->linearisation = 0;
add_dense_linearisation(network, 80, activation);
add_dense(network, 10, SOFTMAX);
return network;
@ -112,6 +111,29 @@ void add_2d_average_pooling(Network* network, int dim_output) {
network->kernel[k_pos]->nn = NULL;
network->kernel[k_pos]->activation = IDENTITY; // Ne contient pas de fonction d'activation
network->kernel[k_pos]->linearisation = 0;
network->kernel[k_pos]->pooling = 1;
create_a_cube_input_layer(network, n, network->depth[n-1], network->width[n-1]/2);
create_a_cube_input_z_layer(network, n, network->depth[n-1], network->width[n-1]/2); // Will it be used ?
network->size++;
}
void add_2d_max_pooling(Network* network, int dim_output) {
int n = network->size;
int k_pos = n-1;
int dim_input = network->width[k_pos];
if (network->max_size == n) {
printf("Impossible de rajouter une couche de max pooling, le réseau est déjà plein\n");
return;
}
if (dim_input%dim_output != 0) {
printf("Erreur de dimension dans le max pooling\n");
return;
}
network->kernel[k_pos]->cnn = NULL;
network->kernel[k_pos]->nn = NULL;
network->kernel[k_pos]->activation = IDENTITY; // Ne contient pas de fonction d'activation
network->kernel[k_pos]->linearisation = 0;
network->kernel[k_pos]->pooling = 2;
create_a_cube_input_layer(network, n, network->depth[n-1], network->width[n-1]/2);
create_a_cube_input_z_layer(network, n, network->depth[n-1], network->width[n-1]/2); // Will it be used ?
network->size++;
@ -132,6 +154,7 @@ void add_convolution(Network* network, int depth_output, int dim_output, int act
network->kernel[k_pos]->nn = NULL;
network->kernel[k_pos]->activation = activation;
network->kernel[k_pos]->linearisation = 0;
network->kernel[k_pos]->pooling = 0;
network->kernel[k_pos]->cnn = (Kernel_cnn*)malloc(sizeof(Kernel_cnn));
Kernel_cnn* cnn = network->kernel[k_pos]->cnn;
@ -190,6 +213,7 @@ void add_dense(Network* network, int output_units, int activation) {
Kernel_nn* nn = network->kernel[k_pos]->nn;
network->kernel[k_pos]->activation = activation;
network->kernel[k_pos]->linearisation = 0;
network->kernel[k_pos]->pooling = 0;
nn->input_units = input_units;
nn->output_units = output_units;
nn->bias = (float*)malloc(sizeof(float)*output_units);
@ -228,6 +252,7 @@ void add_dense_linearisation(Network* network, int output_units, int activation)
Kernel_nn* nn = network->kernel[k_pos]->nn;
network->kernel[k_pos]->activation = activation;
network->kernel[k_pos]->linearisation = 1;
network->kernel[k_pos]->pooling = 0;
nn->input_units = input_units;
nn->output_units = output_units;

View File

@ -25,7 +25,7 @@ void free_a_line_input_layer(Network* network, int pos) {
free(network->input_z[pos]);
}
void free_2d_average_pooling(Network* network, int pos) {
void free_2d_pooling(Network* network, int pos) {
free_a_cube_input_layer(network, pos+1, network->depth[pos+1], network->width[pos+1]);
}
@ -123,7 +123,7 @@ void free_network(Network* network) {
free_dense_linearisation(network, i);
}
} else { // Pooling
free_2d_average_pooling(network, i);
free_2d_pooling(network, i);
}
}
free_network_creation(network);

View File

@ -39,6 +39,11 @@ void create_a_line_input_layer(Network* network, int pos, int dim);
*/
void add_2d_average_pooling(Network* network, int dim_output);
/*
* Ajoute au réseau une couche de max pooling valide de dimension dim*dim
*/
void add_2d_max_pooling(Network* network, int dim_output);
/*
* Ajoute au réseau une couche de convolution dim*dim et initialise les kernels
*/

View File

@ -16,9 +16,9 @@ void free_a_cube_input_layer(Network* network, int pos, int depth, int dim);
void free_a_line_input_layer(Network* network, int pos);
/*
* Libère l'espace mémoire alloué dans 'add_2d_average_pooling' (creation.c)
* Libère l'espace mémoire alloué dans 'add_2d_average_pooling' ou 'add_2d_max_pooling' (creation.c)
*/
void free_2d_average_pooling(Network* network, int pos);
void free_2d_pooling(Network* network, int pos);
/*
* Libère l'espace mémoire dans 'add_convolution' (creation.c)

View File

@ -12,11 +12,17 @@ void make_convolution_cpu(Kernel_cnn* kernel, float*** input, float*** output, i
* Effectue la convolution sur le CPU ou GPU
*/
void make_convolution(Kernel_cnn* kernel, float*** input, float*** output, int output_dim);
/*
* Effectue un average pooling avec stride=size
*/
void make_average_pooling(float*** input, float*** output, int size, int output_depth, int output_dim);
/*
* Effectue un max pooling avec stride=size
*/
void make_max_pooling(float*** input, float*** output, int size, int output_depth, int output_dim);
/*
* Effectue une full connection
*/

View File

@ -25,6 +25,7 @@ typedef struct Kernel {
Kernel_nn* nn; // NULL si ce n'est pas un nn
int activation; // Vaut l'identifiant de la fonction d'activation
int linearisation; // Vaut 1 si c'est la linéarisation d'une couche, 0 sinon
int pooling; // 0 si pas pooling, 1 si average_pooling, 2 si max_pooling
} Kernel;

View File

@ -6,8 +6,8 @@
#define EPOCHS 10
#define BATCHES 500
#define USE_MULTITHREADING
#define LEARNING_RATE 0.01
//#define USE_MULTITHREADING
#define LEARNING_RATE 0.05
/*

View File

@ -1,9 +1,17 @@
#include <stdio.h>
#include <float.h>
#include "../include/colors.h"
#include "include/convolution.h"
#include "include/make.h"
float max_flt(float a, float b) {
// Return the max between the two floats
if (a>b) {
return a;
}
return b;
}
void make_average_pooling(float*** input, float*** output, int size, int output_depth, int output_dim) {
// input[output_depth][output_dim+size-1][output_dim+size-1]
@ -25,6 +33,25 @@ void make_average_pooling(float*** input, float*** output, int size, int output_
}
}
void make_max_pooling(float*** input, float*** output, int size, int output_depth, int output_dim) {
// input[output_depth][output_dim+size-1][output_dim+size-1]
// output[output_depth][output_dim][output_dim]
float m;
for (int i=0; i < output_depth; i++) {
for (int j=0; j < output_dim; j++) {
for (int k=0; k < output_dim; k++) {
m = FLT_MIN;
for (int a=0; a < size; a++) {
for (int b=0; b < size; b++) {
m = max_flt(m, input[i][size*j +a][size*k +b]);
}
}
output[i][j][k] = m;
}
}
}
}
void make_dense(Kernel_nn* kernel, float* input, float* output, int size_input, int size_output) {
// input[size_input]
// output[size_output]