2014-06-22 2 views
0

J'ai essayé d'apprendre le réseautage neuronal et tous les exemples que j'ai vus sur Internet ont donné des exemples d'émulation de portes logiques dites portes XOR. Mais ce que je veux faire est de créer un réseau qui peut être formé pour émuler des fonctions dites le x^2 ou e^x. Est-ce possible? Quels changements dois-je faire dans le réseau? Voici mon code pour un réseau de neurones constitué de 1 noeud d'entrée, d'un calque caché composé de 3 noeuds et d'un noeud de sortie.Création d'un réseau de neurones pour évaluer une fonction logique

#include <iostream.h> 
    #include <fstream.h> 
    #include <math.h> 
    #include <time.h> 
    const double eeta=0.9; 
    const int n=5; 
    struct Net_elem 
    { 
     double weights1[3]; 
     double weights2[3]; 
     double bias1,bias2; 
    };//structure to store network paramenters 
    Net_elem net_elem; 
    double sigma(double input) 
    { 
     return 1/(1+exp(-input)); 
     } 
    void show_net_elem() 
    { 
       cout.precision(15); 
       for(int i=0;i<3;i++) 
       { 
         cout<<"weights1["<<i<<"]="<<net_elem.weights1[i]; 
         cout<<endl; 
       } 
       for(int i=0;i<3;i++) 
       { 
         cout<<"weights2["<<i<<"]="<<net_elem.weights2[i]; 
         cout<<endl; 
       } 
       cout<<"bias1="<<net_elem.bias1<<" bias2="<<net_elem.bias2<<endl; 
       system("pause"); 
       system("cls"); 
    } 
    //function to train the network 
    void train(double input,double expected) 
    { 
    double Output,output[3],Delta,delta[3],delta_bias1,delta_bias2; 

    //Propogate forward 
    double sum=0; 
    for(int i=0;i<3;i++) 
     output[i]=sigma(input*net_elem.weights1[i]+net_elem.bias1); 
    sum=0; 
    for(int i=0;i<3;i++) 
     sum=sum+output[i]*net_elem.weights2[i]; 
    Output=sigma(sum+net_elem.bias2); 
    cout<<"Output="<<Output<<endl; 

    //Backpropogate 

    Delta=expected-Output; 
    for(int i=0;i<3;i++) 
     delta[i]=net_elem.weights2[i]*Delta; 
     delta_bias2=net_elem.bias2*Delta; 

    //Update weights 

    for(int i=0;i<3;i++) 
     net_elem.weights1[i]=net_elem.weights1[i]+eeta*delta[i]*output[i]*(1-output[i])*input; 
    for(int i=0;i<3;i++) 
     net_elem.weights2[i]=net_elem.weights2[i]+eeta*Delta*Output*(1-Output)*output[i]; 
    net_elem.bias2=net_elem.bias2+eeta*delta_bias2; 
    double sum1=0; 
    for(int i=0;i<3;i++) 
     sum1=sum1+net_elem.weights1[i]*delta[i]; 
    net_elem.bias1=net_elem.bias1+eeta*sum1; 
    show_net_elem(); 
} 
void test() 
{ 
    cout.precision(15); 
    double input,Output,output[3]; 
    cout<<"Enter Input:"; 
    cin>>input; 
    //Propogate forward 
    double sum=0; 
    for(int i=0;i<3;i++) 
     output[i]=sigma(input*net_elem.weights1[i]+net_elem.bias1); 
    for(int i=0;i<3;i++) 
     sum=sum+output[i]*net_elem.weights2[i]; 
    Output=sigma(sum+net_elem.bias2); 
    cout<<"Output="<<Output<<endl;  
} 

J'ai essayé de l'exécuter pour émuler la fonction racine carrée. Mais la sortie saute simplement entre 0 et 1, en alternance.

principal:

int main() 
{ 
    net_elem.weights1[0]=(double)(rand()%100+0)/10; 
    net_elem.weights1[1]=(double)(rand()%100+0)/10; 
    net_elem.weights1[2]=(double)(rand()%100+0)/10; 
    net_elem.weights2[0]=(double)(rand()%100+0)/10; 
    net_elem.weights2[1]=(double)(rand()%100+0)/10; 
    net_elem.weights2[2]=(double)(rand()%100+0)/10;; 
    net_elem.bias1=(double)(rand()%100+0)/10; 
    net_elem.bias2=(double)(rand()%100+0)/10; 
    double output[n],input[n]; 
    int ch; 
    for(int i=1;i<n;i++) 
    { 
      input[i]=100; 
      output[i]=sqrt(input[i]); 
    } 
    do 
    { 
      cout<<endl<<"1. Train"<<endl; 
      cout<<"2. Test"<<endl; 
      cout<<"3. Exit"<<endl; 
      cin>>ch; 
      switch(ch) 
      { 
         case 1:for(int i=1;i<n;i++) 
         { 
          train(input[i],output[i]); 
         } 
          break; 
         case 2:test();break; 
         case 3:break; 
         default:cout<<"Enter Proper Choice"<<endl; 
      } 
    }while(ch!=3); 
} 
+1

Pour savoir quels * changements * doivent être faits, nous devons savoir ce que nous * changeons *. Pouvez-vous nous montrer un exemple de ce que vous avez essayé? – christopher

+0

Vous apprenez à votre réseau que sqrt (100) = 10, n'est-ce pas? La première 'entrée [i]' devrait dépendre de 'i' ou d'une valeur aléatoire. Deuxièmement, je voudrais essayer de l'entraîner massivement. Des milliers de séances d'entraînement au moins. * Alors * vous pouvez vous demander pourquoi il n'apprend rien. Troisièmement, je vois des problèmes de formatage. Est-ce que 'delta_bias2 = net_elem.bias2 * Delta;' supposé être dans la boucle 'for'? Et quatrième ... c'est une question de débogage trop évidente à mon humble avis. – TobiMcNamobi

Répondre

0

Je pense que vous manquez le point d'utiliser un réseau de neurones. Les réseaux de neurones n'imitent pas les fonctions connues. Ils séparent les zones dans un espace vectoriel inconnu. Le problème de XOR est souvent donné comme exemple, parce qu'il est le minimum problème non linéaire séparable: Un perceptron simple, est tout simplement une ligne séparant deux zones vous problème

enter image description here

Dans ce cas, la les points bleus peuvent être séparés des points rouges en utilisant une simple ligne (le problème est séparable linéairement). Cependant, le problème de XOR, les points sont situés comme ceci:

enter image description here

Ici, une seule ligne (un perceptron) ne suffit pas. Cependant, un perceptron multicouche (très probablement le type de réseau de neurones que vous utilisez) peut utiliser plusieurs perceptrons (dans ce cas deux) pour séparer les points bleus et rouges. De la même manière, un réseau de neurones peut séparer n'importe quel espace. Cependant, le problème XOR produit deux types de sortie, et nous utilisons un réseau de neurones pour les séparer. D'un autre côté, x^2 produit des lignes continues de points, il n'y a donc rien à séparer. De plus, gardez à l'esprit que l'imitation de la fonction XOR est donnée à titre d'exemple de tels problèmes. En pratique, personne n'utilise jamais un réseau de neurones pour remplacer la fonction XOR. Si vous voulez utiliser une fonction, utilisez-la, au lieu de construire quelque chose qui la rapproche. PS: Si vous voulez toujours émuler la fonction x^2 pour la pratique, vous avez besoin d'une régression. Qu'est-ce que vous faites est la classification (puisque vous utilisez une fonction sigma dans votre sortie). Cependant, pour la pratique, vous feriez mieux de vous en tenir aux problèmes de classification. Ils sont de loin plus communs. Aussi, pour de tels problèmes, essayez Matlab, ou, si vous voulez écrire en C++, utilisez une bibliothèque d'algèbre linéaire (par exemple EIGEN 3) pour faciliter l'écriture sans un millier de boucles.

+0

_ "Les réseaux neuronaux n'imitent pas les fonctions connues." _ Désolé mais je ne suis pas du tout d'accord, il a été prouvé depuis environ 25 ans que les perceptrons à 2 couches sont des approximateurs universels pour toute fonction continue arbitraire. – Dolma

+0

@Dolma: C'est correct.Cependant, cette capacité permet au réseau lui-même de créer une fonction généralisée de classification ou de régression dans un espace de problème inconnu. Il n'est jamais utilisé en pratique pour émuler une fonction déjà connue de l'utilisateur. L'OP semble se demander pourquoi la fonction XOR est si souvent citée en exemple, et je voulais expliquer comment on peut combiner des classificateurs linéaires pour classer des ensembles de données non linéairement séparables, ce qui est le point de départ pour les nouveaux réseaux neuronaux. –

+0

Oui, vous avez absolument raison! Bien que parfois nous voulons utiliser des fonctions connues. Par exemple, pour tester les capacités de généralisation d'une architecture réseau et/ou algorithme d'apprentissage, nous pouvons utiliser une fonction connue, appliquer des perturbations aléatoires puis utiliser les sorties perturbées pour former le réseau dans l'espoir de l'adapter à la fonction originale non perturbée. En dehors de cela, je suis d'accord avec vous que ce n'est pas quelque chose que vous faites beaucoup dans la pratique;) – Dolma

Questions connexes