summaryrefslogtreecommitdiff
path: root/Reseau/Reseau.cpp
blob: 4507b041ec575b02a94c39a7aefe989497b6bda7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
#include"Reseau.h"

using namespace std;

/**
 * Constructeur
 * @method Reseau::Reseau
 * @param  nbLayers          Nombre de couche
 * @param  layerInformation  Vecteur descriptif de chaque layer
 * @param  k                 constante k dont depends la sigmoide
 * @param  eta               coefficient d'evolution
 */
Reseau::Reseau(int nbLayers, std::vector<int> layerInformation,double k,double eta,FonctionActivation::EnumFonctionActivation fct) {
  this->eta = eta;
  this->k = k;
  input=std::vector<double>(layerInformation[0]);
  output=std::vector<double>(layerInformation[layerInformation.size()-1]);
  this->nbLayers = nbLayers;
  reseau = std::vector<Layer*>(nbLayers);
  cout << "\033[1;33m| Number of layers : \033[0m" << nbLayers << endl;
  cout << "\033[1;33m| Creating Input Layer \033[0m\n";
  reseau[0] = new InputLayer(layerInformation[0],fct);
  cout << "\033[1;33m| Number of Neurone on Layer number \033[0m " << 0 <<" : " << layerInformation[0] << endl;
  cout << "\033[1;33m| Creating Hidden + Output Layers \033[0m\n\n";
  for(unsigned int i = 1; i < layerInformation.size()-1; i++){
    reseau[i] = new Layer(Layer::HIDDEN,layerInformation[i], layerInformation[i-1],fct);	//The others are just the 'Hidden' Layers
    cout << "\033[1;33m| Number of Neurone on Layer number \033[0m " << i <<" : " << layerInformation[i] << endl;
  }
  reseau[layerInformation.size()-1] = new Layer(Layer::OUTPUT,layerInformation[layerInformation.size()-1],layerInformation[layerInformation.size()-2],fct);
  cout << "\033[1;33m| Number of Neurone on Layer number \033[0m " << layerInformation.size()-1 <<" : " << layerInformation[layerInformation.size()-1] << endl;
  derrdact =std::vector<std::vector<std::vector<double> > > (nbLayers-1);
  dsig = std::vector<std::vector<std::vector<double> > >(nbLayers-1);
  dact= std::vector<std::vector<std::vector<double> > > (nbLayers-1);
  for(int l = 1; l<nbLayers; l++){
    derrdact[l-1] = std::vector<std::vector<double> >(reseau[l]->getNbNeurones());
    dsig[l-1] = std::vector<std::vector<double> >(reseau[l]->getNbNeurones());
    dact[l-1] = std::vector<std::vector<double> >(reseau[l]->getNbNeurones());
    for(int i=0; i<reseau[l]->getNbNeurones(); i++){
      derrdact[l-1][i] = std::vector<double>(reseau[l]->getNeurone(0)->getNbPoids());
      dsig[l-1][i] = std::vector<double>(reseau[l]->getNeurone(0)->getNbPoids());
      dact[l-1][i] = std::vector<double>(reseau[l]->getNeurone(0)->getNbPoids());
    }
  }
}
/**
 * Fire général
 * @method Reseau::fire_all
 * @param  input            Vecteur d'entrée
 * @return                  Valeur d'activation
 */
std::vector<double> Reseau::fire_all(std::vector<double> input) {
  for (int i = 0; i< nbLayers; i++){
    input = reseau[i]->fire(input, k);
  }
  for (unsigned int i = 0; i < output.size(); i ++){
    output[i]=input[i];
  }
  return output;
}
/**
 * Affichage des poids
 * @method Reseau::printWeight
 */
void Reseau::printWeight(){
  for (int i = 0; i < nbLayers;i++){
    std::cout<<"\n----------------------------------\nLayer : "<<i<<"\n----------------------------------\n";
    reseau[i]->printWeight();
  }
}
/**
 * Méthode d'apprentissage
 * @method Reseau::learn
 * @param  jeuxTest      Vecteur de vecteur de vecteur : décrivant en jeuxTest[i][0]
 *  le vecteur d'entrée et en jeuxTest[i][1] la sortie attendue
 */
void Reseau::learn(std::vector<std::vector<std::vector<double> > > jeuxTest, unsigned int nbPasDescenteGradient){
    std::vector<double> erreurs(output.size());
    for(unsigned int i = 0; i<jeuxTest.size();i++){
        output=fire_all(jeuxTest[i][0]);

       if(i%nbPasDescenteGradient == 0){
          for(unsigned int j=0; j<erreurs.size(); j++){
              erreurs[j] = 0;
          }
        }
        for(unsigned int j=0; j<erreurs.size(); j++){
            erreurs[j] += (jeuxTest[i][1][j] - output[j]);
        }
        if(i%nbPasDescenteGradient == nbPasDescenteGradient-1){
            for(unsigned int j=0; j<erreurs.size(); j++){
              erreurs[j] /= (double) nbPasDescenteGradient;
            }
            backPropagation(erreurs);
        }
    }
}

/**
 * Méthode de propagation en arriére
 * @method Reseau::backPropagation
 * @param  output                  Sortie
 * @param  k                       Valeur du coefficient
 * @param  eta                     Valeur d'eta
 */
void Reseau::backPropagation(std::vector<double> erreurs){
   /*On initialise dans un premier temps nos trois matrices 3d*/
    for(int l = nbLayers - 1; l>0; l--){
        Layer* layerCourant = reseau[l];
        for(int n = 0; n < layerCourant->getNbNeurones(); n++){
            Neurone* neuroneCourant = (layerCourant->getNeurone(n));
            double s = neuroneCourant->fw_sum(layerCourant->getInput());
            for(int i=0; i < neuroneCourant->getNbPoids(); i++){
                if(i<neuroneCourant->getNbPoids()-1){
                    dsig[l-1][n][i] = (layerCourant->getInput())[i];
                }
                else{
                    dsig[l-1][n][i] = 1;
                }
                dact[l-1][n][i] = neuroneCourant->derive_activate(s,k);
                if(l == nbLayers - 1){
                    derrdact[l-1][n][i] = -2*erreurs[n];
                }
                else{
                    double inter = 0;
                    for(int j = 0; j < reseau[l+1]->getNbNeurones(); j++){
                        double wj = (*((reseau[l+1]->getNeurone(j)))->getWeight())[n];
                        inter += wj * derrdact[l][j][n] * dact[l][j][n];
                    }
                    derrdact[l-1][n][i] = inter;
                }
            }
        }
    }
    for(int l = nbLayers - 1; l>0; l--){
        Layer* layerCourant = (reseau[l]);
        for(int n = 0; n < reseau[l]->getNbNeurones(); n++){
            Neurone* neuroneCourant = (layerCourant->getNeurone(n));
            for(int i=0; i < neuroneCourant->getNbPoids(); i++){
                vector<double> * w = neuroneCourant->getWeight();
                (*w)[i] = (*w)[i] - eta*derrdact[l-1][n][i]*dsig[l-1][n][i]*dact[l-1][n][i];
            }
        }
    }
 }