This commit is contained in:
augustin64 2022-03-25 14:26:46 +01:00
parent 9a9d50ef40
commit e91d1d3dbe

View File

@ -1,56 +1,35 @@
/*---------------------------------------------------
------------------------TO Do------------------------
---------------------------------------------------*/
//Creation des structures :::::::::::::::::::::::::::
//Creation des variables pour le réseaux neuronal :::
//Initialisation des variables
//Froward propagation
//Bakcward propagation
//Entrainement à partir de données
//Sauvegarde des poids dans un fichier binaire
//Free tout le réseau neuronal ::::::::::::::::::::::
/*---------------------------------------------------
--------------------Bibliothèques--------------------
---------------------------------------------------*/
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <math.h> #include <math.h>
#include <time.h> #include <time.h>
#define TAUX_APPRENTISSAGE 0.15 //Définit le taux d'apprentissage du réseau neuronal, donc la rapadité d'adaptation du modèle (comprit ent 0 et 1) #define TAUX_APPRENTISSAGE 0.15 // Définit le taux d'apprentissage du réseau neuronal, donc la rapidité d'adaptation du modèle (compris entre 0 et 1)
//<> Le nombre de couche doit être supérieur à 2 //<> Le nombre de couches doit être supérieur à 2
/*--------------------------------------------------- /*---------------------------------------------------
-----------------------Macros---------------------- ----------------------Structures---------------------
---------------------------------------------------*/
/*---------------------------------------------------
----------------------Structure----------------------
---------------------------------------------------*/ ---------------------------------------------------*/
typedef struct neurone_struct{ typedef struct neurone_struct{
float activation; //Caractérise l'activation du neurone float activation; // Caractérise l'activation du neurone
float* poids_sortants; //Liste de tous les poids des arêtes sortants du neurone float* poids_sortants; // Liste de tous les poids des arêtes sortants du neurone
float biais; //Caractérise le biais du neurone float biais; // Caractérise le biais du neurone
float z; //Sauvegarde des calculs faits sur le neurone (programmation dynamique) float z; // Sauvegarde des calculs faits sur le neurone (programmation dynamique)
float dactivation; float dactivation;
float *dw; float *dw;
float dbiais; float dbiais;
float dz; float dz;
} neurone_struct; } neurone_struct;
typedef struct couche_struct{ typedef struct couche_struct{
int nb_neurone; //Nombre de neurones dans la couche (longueur de la liste ci-dessous) int nb_neurone; // Nombre de neurones dans la couche (longueur de la liste ci-dessous)
neurone_struct* neurone; //Liste des neurones dans la couche neurone_struct* neurone; // Liste des neurones dans la couche
} couche_struct; } couche_struct;
/*--------------------------------------------------- /*---------------------------------------------------
----------------------Fonctions---------------------- ----------------------Fonctions----------------------
---------------------------------------------------*/ ---------------------------------------------------*/
@ -69,17 +48,17 @@ void initialisation_du_reseau_neuronal(int nb_couches, int* neurones_par_couche)
void creation_du_reseau_neuronal(int nb_couches, int* neurones_par_couche) { void creation_du_reseau_neuronal(int nb_couches, int* neurones_par_couche) {
/* Créé les différentes variables dans la variable du réseau neuronal à /* Créé les différentes variables dans la variable du réseau neuronal à
partir du nombre de couche et de la liste du nombre de neurone par couche */ partir du nombre de couches et de la liste du nombre de neurones par couche */
reseau_neuronal = (couche_struct*)malloc(sizeof(couche_struct)*nb_couches); //Création des différentes couches reseau_neuronal = (couche_struct*)malloc(sizeof(couche_struct)*nb_couches); // Création des différentes couches
for (int i=0; i<nb_couches; i++) { // Pour chaque couche du réseau neuronal for (int i=0; i<nb_couches; i++) {
reseau_neuronal[i].nb_neurone = neurones_par_couche[i]; //Ajout du nombre de neurone dans la couche à partir des variables en arguments reseau_neuronal[i].nb_neurone = neurones_par_couche[i]; // nombre de neurones pour la couche
reseau_neuronal[i].neurone = (neurone_struct*)malloc(sizeof(neurone_struct)*neurones_par_couche[i]); //Création des différents neurones dans la couche reseau_neuronal[i].neurone = (neurone_struct*)malloc(sizeof(neurone_struct)*neurones_par_couche[i]); // Création des différents neurones dans la couche
if (i!=nb_couches-1) { // On exclut la dernière couche dont les neurones ne contiennent pas de poids sortants if (i!=nb_couches-1) { // On exclut la dernière couche dont les neurones ne contiennent pas de poids sortants
for (int j=0; j<neurones_par_couche[i]; j++) { // Pour chaque neurone de la couche for (int j=0; j<neurones_par_couche[i]; j++) {
reseau_neuronal[i].neurone[j].poids_sortants = (float*)malloc(sizeof(float)*neurones_par_couche[i+1]) ;//Création des poids sortants du neurone reseau_neuronal[i].neurone[j].poids_sortants = (float*)malloc(sizeof(float)*neurones_par_couche[i+1]) ;// Création des poids sortants du neurone
} }
} }
} }
@ -93,9 +72,9 @@ void suppression_du_reseau_neuronal(int nb_couches, int* neurones_par_couche) {
'creation_du_reseau_neuronal' à partir du nombre de couche et de la liste du 'creation_du_reseau_neuronal' à partir du nombre de couche et de la liste du
nombre de neurone par couche */ nombre de neurone par couche */
for (int i=0; i<nb_couches; i++) { // Pour chaque couche du réseau neuronal for (int i=0; i<nb_couches; i++) {
if (i!=nb_couches-1) { // On exclut la dernière couche dont les neurones ne contiennent pas de poids sortants if (i!=nb_couches-1) { // On exclut la dernière couche dont les neurones ne contiennent pas de poids sortants
for (int j=0; j<neurones_par_couche[i]; j++) { // Pour chaque neurone de la couche for (int j=0; j<neurones_par_couche[i]; j++) {
free(reseau_neuronal[i].neurone[j].poids_sortants); // On libère la variables des poids sortants free(reseau_neuronal[i].neurone[j].poids_sortants); // On libère la variables des poids sortants
} }
} }
@ -109,9 +88,9 @@ void suppression_du_reseau_neuronal(int nb_couches, int* neurones_par_couche) {
void forward_propagation(int nb_couches, int* neurones_par_couche) { void forward_propagation(int nb_couches, int* neurones_par_couche) {
/* Effectue une propagation en avant du réseau neuronal à partir du nombre /* Effectue une propagation en avant du réseau neuronal à partir du nombre
de couche et de la liste du nombre de neurone par couche */ de couches et de la liste du nombre de neurones par couche */
for (int i=1; i<nb_couches; i++) { // Pour chaque couche du réseau neuronal (sauf la première qui possède déjà des valeurs) for (int i=1; i<nb_couches; i++) { // La première couche contient déjà des valeurs
for (int j=0; j<neurones_par_couche[i];j++) { // Pour chaque neurone de la couche for (int j=0; j<neurones_par_couche[i];j++) { // Pour chaque neurone de la couche
reseau_neuronal[i].neurone[j].z = reseau_neuronal[i].neurone[j].biais; // On réinitialise l'utilisation actuelle du neurone à son biais reseau_neuronal[i].neurone[j].z = reseau_neuronal[i].neurone[j].biais; // On réinitialise l'utilisation actuelle du neurone à son biais
@ -136,8 +115,8 @@ void forward_propagation(int nb_couches, int* neurones_par_couche) {
int* creation_de_la_sortie_voulue(int nb_couches, int* neurones_par_couche, int pos_nombre_voulu) { int* creation_de_la_sortie_voulue(int nb_couches, int* neurones_par_couche, int pos_nombre_voulu) {
/* Renvoie la liste des sorties voulues sachant à partir du nombre /* Renvoie la liste des sorties voulues à partir du nombre
de couches, de la liste du nombre de neurone par couche et de la de couches, de la liste du nombre de neurones par couche et de la
position du résultat voulue, */ position du résultat voulue, */
int* sortie_voulue = (int*)malloc(sizeof(int)); int* sortie_voulue = (int*)malloc(sizeof(int));
@ -152,11 +131,11 @@ int* creation_de_la_sortie_voulue(int nb_couches, int* neurones_par_couche, int
void backward_propagation(int nb_couches, int* neurones_par_couche, int* sortie_voulue) { void backward_propagation(int nb_couches, int* neurones_par_couche, int* sortie_voulue) {
/* Effectue une propagation en arrière du réseau neuronal à partir du /* Effectue une propagation en arrière du réseau neuronal à partir du
nombre de couche, de la liste du nombre de neurone par couche et de nombre de couches, de la liste du nombre de neurone par couche et de
la liste des sorties voulues*/ la liste des sorties voulues*/
// On commence par parcourir tous les neurones de la couche finale // On commence par parcourir tous les neurones de la couche finale
for (int i=0; i<neurones_par_couche[nb_couches-1]; i++) { // Pour chaque neurone de la dernière couche for (int i=0; i<neurones_par_couche[nb_couches-1]; i++) {
// On applique la formule de propagation en arrière // On applique la formule de propagation en arrière
reseau_neuronal[nb_couches-1].neurone[i].dz = (reseau_neuronal[nb_couches-1].neurone[i].activation - sortie_voulue[i]) * (reseau_neuronal[nb_couches-1].neurone[i].activation) * (1- reseau_neuronal[nb_couches-1].neurone[i].activation); reseau_neuronal[nb_couches-1].neurone[i].dz = (reseau_neuronal[nb_couches-1].neurone[i].activation - sortie_voulue[i]) * (reseau_neuronal[nb_couches-1].neurone[i].activation) * (1- reseau_neuronal[nb_couches-1].neurone[i].activation);
@ -169,13 +148,13 @@ void backward_propagation(int nb_couches, int* neurones_par_couche, int* sortie_
} }
for(int i=nb_couches-2; i>0; i--) { // On remonte les couche de l'avant dernière jusqu'à la première for(int i=nb_couches-2; i>0; i--) { // On remonte les couche de l'avant dernière jusqu'à la première
for(int j=0; j<neurones_par_couche[i]; j++) { // Pour chaque neurone de la couche for(int j=0; j<neurones_par_couche[i]; j++) {
if(reseau_neuronal[i].neurone[j].z >= 0) // ??? ... if(reseau_neuronal[i].neurone[j].z >= 0) // ??? ...
reseau_neuronal[i].neurone[j].dz = reseau_neuronal[i].neurone[j].dactivation; reseau_neuronal[i].neurone[j].dz = reseau_neuronal[i].neurone[j].dactivation;
else // ??? ... else // ??? ...
reseau_neuronal[i].neurone[j].dz = 0; reseau_neuronal[i].neurone[j].dz = 0;
for(int k=0; k<neurones_par_couche[i-1]; k++) { // Pour chaque neurone de la couche précédente for(int k=0; k<neurones_par_couche[i-1]; k++) {
reseau_neuronal[i-1].neurone[k].dw[j] = reseau_neuronal[i].neurone[j].dz * reseau_neuronal[i-1].neurone[k].activation; reseau_neuronal[i-1].neurone[k].dw[j] = reseau_neuronal[i].neurone[j].dz * reseau_neuronal[i-1].neurone[k].activation;
if(i>1) // ??? ... if(i>1) // ??? ...
reseau_neuronal[i-1].neurone[k].dactivation = reseau_neuronal[i-1].neurone[k].poids_sortants[j] * reseau_neuronal[i].neurone[j].dz; reseau_neuronal[i-1].neurone[k].dactivation = reseau_neuronal[i-1].neurone[k].poids_sortants[j] * reseau_neuronal[i].neurone[j].dz;
@ -193,10 +172,10 @@ void modification_du_reseau_neuronal(int nb_couches, int* neurones_par_couche) {
/* Modifie les poids et le biais des neurones du réseau neuronal à partir /* Modifie les poids et le biais des neurones du réseau neuronal à partir
du nombre de couches et de la liste du nombre de neurone par couche */ du nombre de couches et de la liste du nombre de neurone par couche */
for (int i=0; i<nb_couches-1; i++) { // Pour chaque couche possédant des neurones reliés à une couche suivante (on exclut donc la dernière couche) for (int i=0; i<nb_couches-1; i++) { // on exclut la dernière couche
for (int j=0; i<neurones_par_couche[i]; j++) { // Pour chaque neurone de la couche for (int j=0; i<neurones_par_couche[i]; j++) {
reseau_neuronal[i].neurone[j].biais = reseau_neuronal[i].neurone[j].biais - (TAUX_APPRENTISSAGE * reseau_neuronal[i].neurone[j].dbiais); // On modifie le biais du neurone à partir des données de la propagation en arrière reseau_neuronal[i].neurone[j].biais = reseau_neuronal[i].neurone[j].biais - (TAUX_APPRENTISSAGE * reseau_neuronal[i].neurone[j].dbiais); // On modifie le biais du neurone à partir des données de la propagation en arrière
for (int k=0; k<neurones_par_couche[i+1]; k++) { // Pour chaque arête sortant du neurone for (int k=0; k<neurones_par_couche[i+1]; k++) {
reseau_neuronal[i].neurone[j].poids_sortants[k] = reseau_neuronal[i].neurone[j].poids_sortants[k] - (TAUX_APPRENTISSAGE * reseau_neuronal[i].neurone[j].dw[k]); // On modifie le poids du neurone à partir des données de la propagation en arrière reseau_neuronal[i].neurone[j].poids_sortants[k] = reseau_neuronal[i].neurone[j].poids_sortants[k] - (TAUX_APPRENTISSAGE * reseau_neuronal[i].neurone[j].dw[k]); // On modifie le poids du neurone à partir des données de la propagation en arrière
} }
} }
@ -210,9 +189,9 @@ void initialisation_du_reseau_neuronal(int nb_couches, int* neurones_par_couche)
/* Initialise les variables du réseau neuronal (activation, biais, poids, ...) /* Initialise les variables du réseau neuronal (activation, biais, poids, ...)
en suivant de la méthode de Xavier ...... à partir du nombre de couches et de la liste du nombre de neurone par couche */ en suivant de la méthode de Xavier ...... à partir du nombre de couches et de la liste du nombre de neurone par couche */
srand(time(0)); srand(time(0));
for (int i=0; i<nb_couches-1; i++) { // Pour chaque couche reliée à une suivante (donc on exclut la dernière) for (int i=0; i<nb_couches-1; i++) { // on exclut la dernière couche
for (int j=0; j<neurones_par_couche[i]-1; j++) { // Pour chaque neurone de la couche for (int j=0; j<neurones_par_couche[i]-1; j++) {
// Initialisation des bornées supérieure et inférieure // Initialisation des bornes supérieure et inférieure
double borne_superieure = 1/sqrt(neurones_par_couche[i]); double borne_superieure = 1/sqrt(neurones_par_couche[i]);
double borne_inferieure = - borne_superieure; double borne_inferieure = - borne_superieure;
for (int k=0; k<neurones_par_couche[i+1]-1; k++) { // Pour chaque neurone de la couche suivante auquel le neurone est relié for (int k=0; k<neurones_par_couche[i+1]-1; k++) { // Pour chaque neurone de la couche suivante auquel le neurone est relié