summaryrefslogtreecommitdiff
path: root/Neurone
diff options
context:
space:
mode:
Diffstat (limited to 'Neurone')
-rw-r--r--Neurone/FonctionActivation.cpp107
-rw-r--r--Neurone/FonctionActivation.h34
-rw-r--r--Neurone/Neurone.cpp131
-rw-r--r--Neurone/Neurone.h28
-rw-r--r--Neurone/NeuroneB.cpp85
-rw-r--r--Neurone/NeuroneB.h35
6 files changed, 420 insertions, 0 deletions
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 <stdlib.h>
+/**
+ * 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<math.h>
+/**
+ * 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<double> * 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<double> 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<double> x)const{
+ double res=0;
+ for(int i=0; i<n; i++){
+ res += (x[i]) * (*w)[i];
+ }
+ return res;
+}
+
+/**
+ * Méthode d'activation
+ * @method Neurone::fw_activate
+ * @param sum Valeur de la somme du vecteur (cf Neurone::fw_sum)
+ * @param k Valeur du biais
+ * @return Valeur d'activation
+ */
+double Neurone::fw_activate(double sum, double k)const{
+ return fonctionActivation.getValeurActivation(sum,k);
+}
+/**
+ * Méthode de dérivation
+ * @method Neurone::derive_activate
+ * @param sum Valeur de la somme du vecteur (cf Neurone::fw_sum)
+ * @param k Valeur du coefficient de sigmoid k
+ * @return Valeur de dérivation
+ */
+double Neurone::derive_activate(double sum, double k)const{
+ return fonctionActivation.getValeurDerivee(sum,k);
+}
+
+/**
+ * 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 de l'hyperparamètre
+ * @param mu Taux d'apprentissage | Learning rate
+ */
+void Neurone::learn(std::vector<double> 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<n; i++){
+ (*w)[i]= (*w)[i]- mu * (x[i]*derive*((o-res)*(-2)));
+ }
+}
+
+/**
+ * Affichage des poids
+ * @method Neurone::printWeight
+ */
+void Neurone::printWeight(){
+ for(int i=0; i<n; i++){
+ std::cout << "w" << i << " = " << (*w)[i] << std::endl;
+ }
+}
+
+/**
+ * Méthode de génération de poids aléatoire selon une loi normale centrée réduite
+ * @method Neurone::aleaWeights
+ */
+void Neurone::aleaWeights(){
+ w = new std::vector<double> (n,0.8);
+ std::default_random_engine generator(std::random_device{}());
+ std::normal_distribution<double> distribution(0,1);
+ for (int i=0; i<n; i++) {
+ (*w)[i] = distribution(generator);
+ }
+}
+/**
+ * @method Neurone::getWeight
+ * @return Vecteur de poids
+ */
+std::vector<double> * Neurone::getWeight(){
+ return w;
+}
+/**
+ * @method Neurone::getNbPoids
+ * @return Nombre de poids
+ */
+int Neurone::getNbPoids(){
+ return n;
+}
diff --git a/Neurone/Neurone.h b/Neurone/Neurone.h
new file mode 100644
index 0000000..3fc6dd5
--- /dev/null
+++ b/Neurone/Neurone.h
@@ -0,0 +1,28 @@
+#ifndef _NEURONE_H_
+#define _NEURONE_H_
+#include<iostream>
+#include<math.h>
+#include<vector>
+#include<random>
+#include "FonctionActivation.h"
+
+class Neurone {
+protected:
+ std::vector<double> * w;
+ int n;
+ FonctionActivation fonctionActivation;
+public:
+ Neurone();
+ Neurone(int taille,FonctionActivation::EnumFonctionActivation fct);
+ Neurone(int taille, std::vector<double> * x,FonctionActivation::EnumFonctionActivation fct);
+ virtual double fw_sum(std::vector<double> x)const;
+ double fw_activate(double sum, double k)const;
+ double derive_activate(double sum, double k)const;
+ virtual double fire(std::vector<double> x, double k) const;
+ virtual void learn(std::vector<double> x,double o,double k, double mu);
+ virtual void printWeight();
+ virtual void aleaWeights();
+ std::vector<double> * 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<double> * 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<double> (n,0.8);
+ std::default_random_engine generator(std::random_device{}());
+ std::normal_distribution<double> distribution(0,1);
+ for (int i=0; i<n; i++) {
+ (*w)[i] = distribution(generator);
+ }
+ w->push_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<double> 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<n; i++){
+ (*w)[i]= (*w)[i]- mu * (x[i]*derive*((o-res)*(-2)));
+ }
+ (*w)[n] = (*w)[n]- mu * (1*derive*((o-res)*(-2)));
+}
+
+/**
+ * Méthode de somme du vecteur de poids
+ * @method NeuroneB::fw_sum
+ * @param x Vecteur de poids
+ * @return Somme des poids
+ */
+double NeuroneB::fw_sum(std::vector<double> 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<double> * x,double biais_w);
+ void printWeight();
+ void aleaWeights();
+ void learn(std::vector<double> x,double o,double k, double mu);
+ double fw_sum(std::vector<double> 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<Neurone*> et on pourra ensuite travailler de la meme maniere, qu'
+ * s'agisse de NeuroneB ou non.
+ */