From b4c345e6a5fa929ba20eac19183b9c777055f52d Mon Sep 17 00:00:00 2001 From: Gaspard Coulet Date: Wed, 28 Apr 2021 23:12:36 +0200 Subject: Initial commit --- Neurone/FonctionActivation.cpp | 107 +++++++++++++++++++++++++++++++++ Neurone/FonctionActivation.h | 34 +++++++++++ Neurone/Neurone.cpp | 131 +++++++++++++++++++++++++++++++++++++++++ Neurone/Neurone.h | 28 +++++++++ Neurone/NeuroneB.cpp | 85 ++++++++++++++++++++++++++ Neurone/NeuroneB.h | 35 +++++++++++ 6 files changed, 420 insertions(+) create mode 100644 Neurone/FonctionActivation.cpp create mode 100644 Neurone/FonctionActivation.h create mode 100644 Neurone/Neurone.cpp create mode 100644 Neurone/Neurone.h create mode 100644 Neurone/NeuroneB.cpp create mode 100644 Neurone/NeuroneB.h (limited to 'Neurone') diff --git a/Neurone/FonctionActivation.cpp b/Neurone/FonctionActivation.cpp new file mode 100644 index 0000000..4697ca2 --- /dev/null +++ b/Neurone/FonctionActivation.cpp @@ -0,0 +1,107 @@ +#include"./FonctionActivation.h" +#include +/** + * Constructeur par défauts + * @method FonctionActivation + * @param fonctionActivation Fonction activation à utiliser parmis l'enumération + */ +FonctionActivation::FonctionActivation(){ + this->fonctionActivation = SIGMOID; +} +/** + * @method FonctionActivation::setFonctionActivation + * @param fonctionActivation Fonction activation à utiliser parmis l'enumération + */ +void FonctionActivation::setFonctionActivation(EnumFonctionActivation fonctionActivation){ + this->fonctionActivation = fonctionActivation; +} + +/** + * Constructeur + * @method FonctionActivation + * @param fonctionActivation Fonction activation à utiliser parmis l'enumération + */ +FonctionActivation::FonctionActivation(EnumFonctionActivation fonctionActivation){ + this->fonctionActivation = fonctionActivation; +} + +/** + * @method getValeurActivation + * @param x Valeur de la variable + * @param k Constante de changement + * @return Valeur d'activation + */ +double FonctionActivation::getValeurActivation(double x, double k) const{ + switch (fonctionActivation) { + case IDENTITY: + return x; + break; + case BINARYSTEP: + return x>=0; + break; + case SIGMOID: + return (1/(1+exp(-k*x))); + break; + case TAN: + return ( (exp(x)-exp(-x)) / (exp(x)+exp(-x))); + break; + case SIN: + return sin(x); + break; + case RELU: + return x<0? 0 : x; + break; + case LRELU: + return x<0? 0.01*x : x; + break; + case PRELU: + return x<0? k*x : x; + break; + case ELU: + return x<0? (k*(exp(x)-1)) : x;; + break; + default: + return 0; + break; + } +} +/** + * @method getValeurDerive + * @param x Valeur de la variable + * @param k Constante de changement + * @return Valeur de la derivée + */ +double FonctionActivation::getValeurDerivee(double x, double k) const{ + switch (fonctionActivation) { + case IDENTITY: + return 1; + break; + case BINARYSTEP: + return 0; + break; + case SIGMOID: + return (k*exp(-k*x))* (1/(1+exp(-k*x)*(1+exp(-k*x)))); + break; + case TAN: + return 1 - pow(((exp(x)-exp(-x))/(exp(x)+exp(-x))),2); + break; + case SIN: + return cos(x); + break; + case RELU: + return x<0? 0 : 1; + break; + case LRELU: + return x<0? 0.01 : 1; + break; + case PRELU: + return x<0? k : 1; + break; + case ELU: + return x<0? (k*(exp(x)-1)) + k : 1; + break; + default: + return 0; + break; + } +} diff --git a/Neurone/FonctionActivation.h b/Neurone/FonctionActivation.h new file mode 100644 index 0000000..ccd1119 --- /dev/null +++ b/Neurone/FonctionActivation.h @@ -0,0 +1,34 @@ +#ifndef _FONCTIONACTIVATION_H_ +#define _FONCTIONACTIVATION_H_ +#include +/** + * L'objectif ce cette classe et d'être appeller pour l'activation + * et donc changer plus facilement la fonction d'activation pour le test. + */ +class FonctionActivation { +public: + typedef enum { + IDENTITY, + BINARYSTEP, + SIGMOID, // : Hyperparameter k + TAN, + SIN, + /* Rectifier */ + RELU, // Basic : ramp function + LRELU, // Leaky function : 0.01 + PRELU, // Hyperparameter : Hyperparameter k + ELU // Exponential and ramp + } EnumFonctionActivation; + +private: + EnumFonctionActivation fonctionActivation; + +public: + FonctionActivation(); + FonctionActivation(EnumFonctionActivation fonctionActivation); + + void setFonctionActivation(EnumFonctionActivation fonctionActivation); + double getValeurActivation(double sum, double k = 0) const; + double getValeurDerivee(double sum, double k = 0) const; +}; +#endif diff --git a/Neurone/Neurone.cpp b/Neurone/Neurone.cpp new file mode 100644 index 0000000..0f08602 --- /dev/null +++ b/Neurone/Neurone.cpp @@ -0,0 +1,131 @@ +#include"./Neurone.h" + +/** +* Constructeur par defauts +* @method Neurone::Neurone +*/ +Neurone::Neurone(){ + n = 0; +} +/** + * Constructeur par nombre d'entrées + * @method Neurone::Neurone + * @param n Nombre d'entrées + * @param n Fonction d'Activation + */ +Neurone::Neurone(int n,FonctionActivation::EnumFonctionActivation fct){ + this->n = n; + fonctionActivation.setFonctionActivation(fct); + aleaWeights(); +} +/** + * Constructeur par arguments + * @method Neurone::Neurone + * @param taille Nombre d'entrées + * @param x Vecteur de poids + */ +Neurone::Neurone(int n, std::vector * x,FonctionActivation::EnumFonctionActivation fct){ + w = x; + fonctionActivation.setFonctionActivation(fct); + this->n = n; +} + +/** + * Méthode de propagation en avant + * @method Neurone::fire + * @param in Vecteur d'entrées + * @param k Coefficient de sigmoid k + * @return Valeur d'activation + */ +double Neurone::fire(std::vector in, double k)const{ + return fw_activate(fw_sum(in),k); +} + +/** + * Méthode de somme des valeurs du vecteur + * @method Neurone::fw_sum + * @param x Vecteur + * @return Somme + */ +double Neurone::fw_sum(std::vector x)const{ + double res=0; + for(int i=0; i x,double o,double k, double mu){ + double sum = fw_sum(x); + double res = fw_activate(sum,k); + double derive = derive_activate(sum,k); + for(int i=0; i * w; + int n; + FonctionActivation fonctionActivation; +public: + Neurone(); + Neurone(int taille,FonctionActivation::EnumFonctionActivation fct); + Neurone(int taille, std::vector * x,FonctionActivation::EnumFonctionActivation fct); + virtual double fw_sum(std::vector x)const; + double fw_activate(double sum, double k)const; + double derive_activate(double sum, double k)const; + virtual double fire(std::vector x, double k) const; + virtual void learn(std::vector x,double o,double k, double mu); + virtual void printWeight(); + virtual void aleaWeights(); + std::vector * getWeight(); + virtual int getNbPoids(); +}; +#endif diff --git a/Neurone/NeuroneB.cpp b/Neurone/NeuroneB.cpp new file mode 100644 index 0000000..4556f8e --- /dev/null +++ b/Neurone/NeuroneB.cpp @@ -0,0 +1,85 @@ +#include"./NeuroneB.h" +/** + * Constructeur du Neurone avec biais + * @method NeuroneB::NeuroneB + * @param taille Taille du neurone + * @param x Vecteur de poids + * @param biais_w Valeur du biais + */ +NeuroneB::NeuroneB(int taille,std::vector * x, double biais_w){ + n = taille; + w = x; + w->push_back(biais_w); +} + +/** + * Constructeur du Neurone avec biais + * @method NeuroneB::NeuroneB + * @param taille Taille du neurone + */ +NeuroneB::NeuroneB(int taille,FonctionActivation::EnumFonctionActivation fct) { + n = taille; + fonctionActivation.setFonctionActivation(fct); + aleaWeights(); +} + +/** + * Affichage des poids + * @method NeuroneB::printWeight + */ +void NeuroneB::printWeight(){ + Neurone::printWeight(); + std::cout << "biais = " << (*w)[n] << std::endl; +} + +/** + * Génération aléatoire des poids + * @method NeuroneB::aleaWeights + */ +void NeuroneB::aleaWeights(){ + w = new std::vector (n,0.8); + std::default_random_engine generator(std::random_device{}()); + std::normal_distribution distribution(0,1); + for (int i=0; ipush_back(distribution(generator)); +} + +/** + * Méthode d'apprentissage (cf Neurone::fw_sum, cf Neurone::fw_activate, cf Neurone::derive_activate) + * @method Neurone::learn + * @param x Vecteur de poids + * @param o Valeur attendue + * @param k Valeur du biais + * @param mu Taux d'apprentissage | Learning rate + */ +void NeuroneB::learn(std::vector x,double o,double k, double mu){ + double sum = fw_sum(x); + double res = fw_activate(sum,k); + double derive = derive_activate(sum,k); + for(int i=0; i x)const{ + double res = Neurone::fw_sum(x); + res += (*w)[n]; + return res; +} + +/** + * @method NeuroneB::getNbPoids + * @return Nombre de poids + */ +int NeuroneB::getNbPoids(){ + return n+1; +} diff --git a/Neurone/NeuroneB.h b/Neurone/NeuroneB.h new file mode 100644 index 0000000..fb54ccd --- /dev/null +++ b/Neurone/NeuroneB.h @@ -0,0 +1,35 @@ +#ifndef _NEURONEB_H_ +#define _NEURONEB_H_ +#include"./Neurone.h" + +class NeuroneB : public Neurone { +public: + NeuroneB(int taille,FonctionActivation::EnumFonctionActivation fct); // Poids et biais random + NeuroneB(int taille,std::vector * x,double biais_w); + void printWeight(); + void aleaWeights(); + void learn(std::vector x,double o,double k, double mu); + double fw_sum(std::vector x)const; + int getNbPoids(); +}; +#endif + +/** + * La classe NeuroneB est represente des neurones particuliers + * dotés d'un biais, elle redefinie les fonctions ou le comportement + * est different a cause du biais, + * petit point sur les methodes "virtual" dans Neurone.h : + * Le mot clé virtual permet de declarer une fonction virtuelle + * en clair, quand on fait un heritage, on peut faire rentrer un Pointeur + * sur un objt fils dans un pointeur sur un objet pere, or, en faisant + * cela, on perd la vrai nature de l'objet, exemple si on cree un + * NeuroneB dans un pointeur Neurone, et que l'on appelle sa methode getWeight + * ce sera la methode de Neurone qui sera appellé, car pour le compilateur, on a un objet + * En mentionant que la methode de l'ojet pere est virtuelle, on dit au + * "Hey poto, je risque d'appeller cette methode depuis un objet qui semble etre + * Neurone, mais qui sera ptet un NeuroneB, donc attend de voir, et appelle la methode de la classe correspondante + * A terme ce sera super pratique : exemple + * On est dans Layer, on cree un pack de Neurone, a la creation, on choisit si ce sont des Neurone, ou des + * on les stocke quoi qu'il arrive dans un vector et on pourra ensuite travailler de la meme maniere, qu' + * s'agisse de NeuroneB ou non. + */ -- cgit v1.2.3