mirror of
https://github.com/augustin64/projet-tipe
synced 2025-01-24 07:36:24 +01:00
Modification of the backward
This commit is contained in:
parent
52999331f9
commit
d36d295e80
@ -6,8 +6,13 @@
|
|||||||
|
|
||||||
#include "struct/neuron.h"
|
#include "struct/neuron.h"
|
||||||
|
|
||||||
#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)
|
// Définit le taux d'apprentissage du réseau neuronal, donc la rapidité d'adaptation du modèle (compris entre 0 et 1)
|
||||||
|
//Cette valeur peut évoluer au fur et à mesure des époques (linéaire c'est mieux)
|
||||||
|
#define TAUX_APPRENTISSAGE 0.1
|
||||||
|
//Retourne un nombre aléatoire entre 0 et 1
|
||||||
#define RAND_DOUBLE() ((double)rand())/((double)RAND_MAX)
|
#define RAND_DOUBLE() ((double)rand())/((double)RAND_MAX)
|
||||||
|
//Coefficient leaking ReLU
|
||||||
|
#define COEFF_LEAKY_RELU 0.2
|
||||||
|
|
||||||
|
|
||||||
float max(float a, float b){
|
float max(float a, float b){
|
||||||
@ -19,12 +24,20 @@ float sigmoid(float x){
|
|||||||
}
|
}
|
||||||
|
|
||||||
float sigmoid_derivee(float x){
|
float sigmoid_derivee(float x){
|
||||||
float tmp = exp(-x);
|
float tmp = sigmoid(x);
|
||||||
return tmp/((1 + tmp)*(1+tmp));
|
return tmp*(1-tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
float ReLU(float x){
|
float leaky_ReLU(float x){
|
||||||
return max(x, 0);
|
if (x>0)
|
||||||
|
return x;
|
||||||
|
return x*COEFF_LEAKY_RELU;
|
||||||
|
}
|
||||||
|
|
||||||
|
float leaky_ReLU_derivee(float x){
|
||||||
|
if (x>0)
|
||||||
|
return 1;
|
||||||
|
return COEFF_LEAKY_RELU;
|
||||||
}
|
}
|
||||||
|
|
||||||
void creation_du_reseau_neuronal(Reseau* reseau, int* neurones_par_couche, int nb_couches) {
|
void creation_du_reseau_neuronal(Reseau* reseau, int* neurones_par_couche, int nb_couches) {
|
||||||
@ -78,7 +91,7 @@ void forward_propagation(Reseau* reseau) {
|
|||||||
on été insérées dans la première couche. Le résultat de la propagation se
|
on été insérées dans la première couche. Le résultat de la propagation se
|
||||||
trouve dans la dernière couche */
|
trouve dans la dernière couche */
|
||||||
Couche* couche; // Couche actuelle
|
Couche* couche; // Couche actuelle
|
||||||
Couche* pre_couche; // Couche précédante
|
Couche* pre_couche; // Couche précédente
|
||||||
|
|
||||||
for (int i=1; i < reseau->nb_couches; i++) { // La première couche contient déjà des valeurs
|
for (int i=1; i < reseau->nb_couches; i++) { // La première couche contient déjà des valeurs
|
||||||
couche = reseau->couches[i];
|
couche = reseau->couches[i];
|
||||||
@ -88,11 +101,11 @@ void forward_propagation(Reseau* reseau) {
|
|||||||
couche->neurones[j]->z = couche->neurones[j]->biais;
|
couche->neurones[j]->z = couche->neurones[j]->biais;
|
||||||
|
|
||||||
for (int k=0; k < pre_couche->nb_neurones; k++) {
|
for (int k=0; k < pre_couche->nb_neurones; k++) {
|
||||||
couche->neurones[j]->z += pre_couche->neurones[k]->z * pre_couche->neurones[k]->poids_sortants[j] * pre_couche->neurones[k]->activation;
|
couche->neurones[j]->z += pre_couche->neurones[k]->z * pre_couche->neurones[k]->poids_sortants[j];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i < reseau->nb_couches-1) { // Pour toutes les couches sauf la dernière on utilise la fonction ReLU (0 si z<0, z sinon)
|
if (i < reseau->nb_couches-1) { // Pour toutes les couches sauf la dernière on utilise la fonction leaky_ReLU (a*z si z<0, z sinon)
|
||||||
couche->neurones[j]->z = ReLU(couche->neurones[j]->z);
|
couche->neurones[j]->z = leaky_ReLU(couche->neurones[j]->z);
|
||||||
}
|
}
|
||||||
else { // Pour la dernière couche on utilise la fonction sigmoid permettant d'obtenir un résultat entre 0 et 1 à savoir une probabilité
|
else { // Pour la dernière couche on utilise la fonction sigmoid permettant d'obtenir un résultat entre 0 et 1 à savoir une probabilité
|
||||||
couche->neurones[j]->z = sigmoid(couche->neurones[j]->z);
|
couche->neurones[j]->z = sigmoid(couche->neurones[j]->z);
|
||||||
@ -121,49 +134,54 @@ int* creation_de_la_sortie_voulue(Reseau* reseau, int pos_nombre_voulu) {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void mise_a_jour_parametres(Reseau* reseau){
|
||||||
|
/* Met à jour le réseau neuronal à partir des données de la backpropagation */
|
||||||
|
for (int i=0; i<reseau->nb_couches-1; i++) {
|
||||||
|
for (int j=0; j<reseau->couches[i]->nb_neurones; j++) {
|
||||||
|
if (i!=0) {
|
||||||
|
reseau->couches[i]->neurones[j]->biais -= reseau->couches[i]->neurones[j]->d_biais;
|
||||||
|
}
|
||||||
|
for (int k=0; k<reseau->couches[i+1]->nb_neurones; k++) {
|
||||||
|
reseau->couches[i]->neurones[j]->poids_sortants[k] -= reseau->couches[i]->neurones[j]->d_poids_sortants[k];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void backward_propagation(Reseau* reseau, int* sortie_voulue) {
|
void backward_propagation(Reseau* reseau, int* sortie_voulue) {
|
||||||
/* Effectue une propagation en arrière du réseau neuronal */
|
/* Effectue une propagation en arrière du réseau neuronal */
|
||||||
Neurone* neurone;
|
Neurone* neurone;
|
||||||
Neurone* neurone2;
|
Neurone* neurone2;
|
||||||
|
float changes;
|
||||||
|
|
||||||
// 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 < reseau->couches[reseau->nb_couches-1]->nb_neurones; i++) {
|
for (int i=reseau->nb_couches-2; i>=0; i--) {
|
||||||
// On calcule l'erreur de la sortie
|
if (i==reseau->nb_couches-2){
|
||||||
neurone = reseau->couches[reseau->nb_couches-1]->neurones[i];
|
for (int j=0; j<reseau->couches[i]->nb_neurones; j++) {
|
||||||
|
neurone = reseau->couches[reseau->nb_couches-1]->neurones[i];
|
||||||
neurone->d_z = (neurone->z - sortie_voulue[i])*(neurone->z - sortie_voulue[i]);
|
changes = sigmoid_derivee(neurone->z)*2*(neurone->z - sortie_voulue[i]);
|
||||||
|
//neurone->biais = neurone->biais - TAUX_APPRENTISSAGE*changes;
|
||||||
for(int k=0; k<reseau->couches[reseau->nb_couches-2]->nb_neurones; k++) { // Pour chaque neurone de l'avant dernière couche
|
for (int k=0; k<reseau->couches[i+1]->nb_neurones; k++) {
|
||||||
neurone2 = reseau->couches[reseau->nb_couches-2]->neurones[k];
|
reseau->couches[i]->neurones[j]->d_poids_sortants[k] = TAUX_APPRENTISSAGE*reseau->couches[i-1]->neurones[k]->poids_sortants[j]*changes;
|
||||||
|
}
|
||||||
neurone2->d_poids_sortants[i] = neurone->d_z;
|
}
|
||||||
neurone2->d_activation = neurone2->poids_sortants[i] * neurone->d_z;
|
}
|
||||||
}
|
else {
|
||||||
// ???
|
for (int j=0; j<reseau->couches[i+1]->nb_neurones; j++) {
|
||||||
neurone->d_biais = neurone->d_z;
|
float changes = 0;
|
||||||
}
|
for (int k=0; k<reseau->couches[i+2]->nb_neurones; k++) {
|
||||||
|
changes += reseau->couches[i+1]->neurones[j]->poids_sortants[k]*reseau->couches[i+1]->neurones[j]->d_poids_sortants[k];
|
||||||
for(int i=reseau->nb_couches-2; i > 0; i--) { // On remonte les couche de l'avant dernière jusqu'à la première
|
}
|
||||||
for(int j=0; j<reseau->couches[i]->nb_neurones; j++) {
|
changes = changes*leaky_ReLU_derivee(reseau->couches[i+1]->neurones[j]->z);
|
||||||
neurone = reseau->couches[i]->neurones[j];
|
reseau->couches[i+1]->neurones[j]->d_biais = TAUX_APPRENTISSAGE*changes;
|
||||||
|
for (int k=0; k<reseau->couches[i]->nb_neurones; k++){
|
||||||
if(neurone->z >= 0) // ??? ...
|
reseau->couches[i]->neurones[k]->d_poids_sortants[j] = TAUX_APPRENTISSAGE*reseau->couches[i]->neurones[k]->poids_sortants[j]*changes;
|
||||||
neurone->d_z = neurone->d_activation;
|
}
|
||||||
else // ??? ...
|
|
||||||
neurone->d_z = 0;
|
|
||||||
|
|
||||||
for(int k=0; k<reseau->couches[i-1]->nb_neurones; k++) {
|
|
||||||
neurone2 = reseau->couches[i-1]->neurones[k];
|
|
||||||
|
|
||||||
neurone2->d_poids_sortants[j] = neurone->d_z;
|
|
||||||
if(i>1) // ??? ...
|
|
||||||
neurone2->d_activation = neurone2->poids_sortants[j] * neurone->d_z;
|
|
||||||
}
|
}
|
||||||
neurone->d_biais = neurone->d_z; // ??? ...
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
mise_a_jour_parametres(reseau);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -204,7 +222,7 @@ void initialisation_du_reseau_neuronal(Reseau* reseau) {
|
|||||||
neurone = reseau->couches[i]->neurones[j];
|
neurone = reseau->couches[i]->neurones[j];
|
||||||
// Initialisation des bornes supérieure et inférieure
|
// Initialisation des bornes supérieure et inférieure
|
||||||
borne_superieure = 1/sqrt(reseau->couches[i]->nb_neurones);
|
borne_superieure = 1/sqrt(reseau->couches[i]->nb_neurones);
|
||||||
borne_inferieure = - borne_superieure;
|
borne_inferieure = 0;
|
||||||
ecart_bornes = borne_superieure - borne_inferieure;
|
ecart_bornes = borne_superieure - borne_inferieure;
|
||||||
|
|
||||||
neurone->activation = borne_inferieure + RAND_DOUBLE()*ecart_bornes;
|
neurone->activation = borne_inferieure + RAND_DOUBLE()*ecart_bornes;
|
||||||
@ -218,13 +236,14 @@ void initialisation_du_reseau_neuronal(Reseau* reseau) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
borne_superieure = 1/sqrt(reseau->couches[reseau->nb_couches-1]->nb_neurones);
|
borne_superieure = 1/sqrt(reseau->couches[reseau->nb_couches-1]->nb_neurones);
|
||||||
borne_inferieure = - borne_superieure;
|
borne_inferieure = 0;
|
||||||
ecart_bornes = borne_superieure - borne_inferieure;;
|
ecart_bornes = borne_superieure - borne_inferieure;;
|
||||||
|
|
||||||
for (int j=0; j < reseau->couches[reseau->nb_couches-1]->nb_neurones; j++) {// Intialisation de la dernière couche exclue ci-dessus
|
for (int j=0; j < reseau->couches[reseau->nb_couches-1]->nb_neurones; j++) {// Intialisation de la dernière couche exclue ci-dessus
|
||||||
neurone = reseau->couches[reseau->nb_couches-1]->neurones[j];
|
neurone = reseau->couches[reseau->nb_couches-1]->neurones[j];
|
||||||
neurone->activation = borne_inferieure + RAND_DOUBLE()*ecart_bornes;
|
//Il y a pas de biais et activation variables pour la dernière couche
|
||||||
neurone->biais = borne_inferieure + RAND_DOUBLE()*ecart_bornes; // On initialise le biais aléatoirement
|
neurone->activation = 1;
|
||||||
|
neurone->biais = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,14 +12,16 @@
|
|||||||
float max(float a, float b);
|
float max(float a, float b);
|
||||||
float sigmoid(float x);
|
float sigmoid(float x);
|
||||||
float sigmoid_derivee(float x);
|
float sigmoid_derivee(float x);
|
||||||
float ReLU(float x);
|
float leaky_ReLU(float x);
|
||||||
|
float leaky_ReLU_derivee(float x);
|
||||||
void creation_du_reseau_neuronal(Reseau* reseau_neuronal, int* neurones_par_couche, int nb_couches);
|
void creation_du_reseau_neuronal(Reseau* reseau_neuronal, int* neurones_par_couche, int nb_couches);
|
||||||
void suppression_du_reseau_neuronal(Reseau* reseau_neuronal);
|
void suppression_du_reseau_neuronal(Reseau* reseau_neuronal);
|
||||||
void forward_propagation(Reseau* reseau_neuronal);
|
void forward_propagation(Reseau* reseau_neuronal);
|
||||||
int* creation_de_la_sortie_voulue(Reseau* reseau_neuronal, int pos_nombre_voulu);
|
int* creation_de_la_sortie_voulue(Reseau* reseau_neuronal, int pos_nombre_voulu);
|
||||||
|
void mise_a_jour_parametres(Reseau* reseau);
|
||||||
void backward_propagation(Reseau* reseau_neuronal, int* sortie_voulue);
|
void backward_propagation(Reseau* reseau_neuronal, int* sortie_voulue);
|
||||||
void modification_du_reseau_neuronal(Reseau* reseau_neuronal);
|
void modification_du_reseau_neuronal(Reseau* reseau_neuronal);
|
||||||
void initialisation_du_reseau_neuronal(Reseau* reseau_neuronal);
|
void initialisation_du_reseau_neuronal(Reseau* reseau_neuronal);
|
||||||
|
float erreur_sortie(Reseau* reseau, int numero_voulu);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user