Aller au contenu


Photo
- - - - -

[Aide] Expliquation reseau neuronal

IA reseau neuronal

47 réponses à ce sujet

#1 R2D21995

R2D21995

    Membre passionné

  • Membres
  • PipPipPip
  • 385 messages

Posté 19 juillet 2015 - 08:03

Bonsoir,

j'ai une petite question sur les reseaux neuronaux. Comment faire pour créer un neurone en c ou en cpp ? Je n'ai pas trouvé d'exemple clair qui puisse vraiment répondre à ma question. Mon but serai de faire des petits robots qui puisses apprendre à se déplacer tout seul avec les reseaux neuronaux.

Cordialement et bonne soirée

 


Il faut toujours viser la lune, car même en cas d’échec, on atterrit dans les étoiles


#2 R1D1

R1D1

    Modérateur et Membre passionné

  • Modérateur
  • PipPipPipPipPip
  • 1 211 messages
  • Gender:Male
  • Location:Autriche

Posté 19 juillet 2015 - 10:49

Salut !

Tu peux créer un réseau neuronal comme n'importe quel programme informatique : en écrivant le code correspondant, ou en utilisant une librairie qui le fait pour toi.
Dans le premier cas, il faut bien évidemment comprendre les algorithmes (quel modèle de neurone, quel type d'apprentissage, quel type de mise à jour).
Dans le second, tu peux chercher sur Github, il y a plein d'implémentation (sûrement de qualité variable). Si tu fais du python, tu peux chercher du côté de scikit-learn qui est une référence pour le machine learning en python. Je ne lui connais pas d'équivalent en cpp.

Tu peux aussi regarder le travail d'Andrej Karpathy sur les Deep Neural Network, plutôt à la mode en ce moment : https://github.com/karpathy
R1D1 - Calculo Sed Ergo Sum -- en ce moment, M.A.R.C.E.L.
Avatar tiré du site bottlebot

#3 R2D21995

R2D21995

    Membre passionné

  • Membres
  • PipPipPip
  • 385 messages

Posté 20 juillet 2015 - 12:07

Je te remerci beaucoup je vais aller voir.


Il faut toujours viser la lune, car même en cas d’échec, on atterrit dans les étoiles


#4 R1D1

R1D1

    Modérateur et Membre passionné

  • Modérateur
  • PipPipPipPipPip
  • 1 211 messages
  • Gender:Male
  • Location:Autriche

Posté 20 juillet 2015 - 10:50

Je te remerci beaucoup je vais aller voir.


N'hésite pas à poser des questions ici-même si tu ne comprends pas certaines choses. J'ai utilisé un réseau à poids fixés dans mon robot Froggy (ce qui en fait un véhicule de Braitenberg - voir démo en fin de post) qui ne fonctionne pas trop mal, cependant, une seul capteur de distance est à mon avis insuffisant. Tu as déjà un robot pour le faire tourner ? Ou tu comptes travailler en simulation ?

Bon courage en tout cas !

Démo de Froggy (et post de blog correspondant) :

R1D1 - Calculo Sed Ergo Sum -- en ce moment, M.A.R.C.E.L.
Avatar tiré du site bottlebot

#5 R2D21995

R2D21995

    Membre passionné

  • Membres
  • PipPipPip
  • 385 messages

Posté 20 juillet 2015 - 12:13

J'ai un petit robot que j'ai fais à l'école. Il faut que je le retape mais la carte et tout marche. Merci de ton aide mais pour l'instant je vais déjà voir tout ce que tu m'a dis.


Il faut toujours viser la lune, car même en cas d’échec, on atterrit dans les étoiles


#6 R2D21995

R2D21995

    Membre passionné

  • Membres
  • PipPipPip
  • 385 messages

Posté 25 juillet 2015 - 09:14

pour les réseaux neuronaux j'aimerai les utiliser pour créer une petite intelligence artificiel qui est ça propre "personnalité". cad qu'il puisse avoir un semblent de personnalité. Comment définir les réseau neuronaux. c'est quelque chose comme ça que je veux faire https://www.youtube....h?v=qZqqdqiKw3o à 25 minutes en moins complexes bien sûr. 


Il faut toujours viser la lune, car même en cas d’échec, on atterrit dans les étoiles


#7 R1D1

R1D1

    Modérateur et Membre passionné

  • Modérateur
  • PipPipPipPipPip
  • 1 211 messages
  • Gender:Male
  • Location:Autriche

Posté 27 juillet 2015 - 12:51

pour les réseaux neuronaux j'aimerai les utiliser pour créer une petite intelligence artificiel qui est ça propre "personnalité". cad qu'il puisse avoir un semblent de personnalité. Comment définir les réseau neuronaux. c'est quelque chose comme ça que je veux faire https://www.youtube....h?v=qZqqdqiKw3o à 25 minutes en moins complexes bien sûr.


Je ne comprends pas ta question. Qu'appelles-tu "définir les réseaux neuronaux" ?
Ce qu'il faut déterminer, ce sont les entrées et sorties que tu vas donner à ton réseau, et le nombre de couches de neurones, la taille de chaque couche, la règle d'apprentissage si tu en mets une.

Avant de parler de "personnalité", il faut penser aux comportements que ton robot doit avoir. Mieux vaut commencer par des choses simples, des comportements attirés par la lumière ou repoussés par les obstacles (on peut faire le parallèle avec des émotions comme le désir ou la peur).
Ça peut se faire sans apprentissage. Pour faire des choses plus compliquées, il y aura besoin d'apprentissage, mais ça risque d'être assez long.
R1D1 - Calculo Sed Ergo Sum -- en ce moment, M.A.R.C.E.L.
Avatar tiré du site bottlebot

#8 R2D21995

R2D21995

    Membre passionné

  • Membres
  • PipPipPip
  • 385 messages

Posté 27 juillet 2015 - 07:05

oui je me suis apperçu. Je veux dire qu'est-ce qu'on prends en parametre pour savoir combiens d'entrées il faut ... Je pense que je ne comprends pas suffisament tout ça. est-ce que vous connaissez des bouquin ou des tuto avec des exemple  là dessus pour démarer svp ? 


Il faut toujours viser la lune, car même en cas d’échec, on atterrit dans les étoiles


#9 R1D1

R1D1

    Modérateur et Membre passionné

  • Modérateur
  • PipPipPipPipPip
  • 1 211 messages
  • Gender:Male
  • Location:Autriche

Posté 28 juillet 2015 - 03:32

Tu peux regarder le tuto de Alp sur developpez.com pour les généralités : http://alp.developpez.com/tutoriels/intelligence-artificielle/reseaux-de-neurones/

Combien d'entrées ? Ça dépend de ton problème : pour de la reconnaissance de caractères (OCR), l'entrée du réseau est une image contenant le caractère, il y a donc autant (ou moins) de neurones d'entrée que de pixels. Pour un robot, ça dépend beaucoup de ses capteurs : si tu as deux capteurs de distance, tu peux avoir deux neurones dont l'activation est fonction de la donnée de distance mesurée, ou tu peux discrétiser la distance mesurée en "court, moyen, long" et affecter un neurone pour chaque catégorie (donc 6 neurones d'entrées).
Plus tu mets d'information en entrée (image de grande dimension, plusieurs capteurs de distance, vitesse mesurée des roues, ...), plus tu augmentes la dimension de l'espace d'entrée. Tu as donc une information plus riche, mais ça rend potentiellement l'apprentissage plus long.
À toi donc de choisir quelles mesures tu veux donner à ton robot. Il faut savoir aussi que plus tu fais de pré-traitements sur ces entrées (extraire des contours d'une image), plus tu rends l'information accessible au réseau, mais plus tu as de chances de biaiser son apprentissage et son comportement (donc de le pousser à faire des choses que tu lui as imposé, et pas de les découvrir lui-même, ce qui est le but de l'apprentissage automatique).
En sortie, tu dois décider des grandeurs que tu veux contrôler. Pour un robot, ça peut être les vitesses motrices, les angles des articulations, etc ... pour l'OCR, les neurones de sortie peuvent être les classes que tu veux reconnaître (ici, une classe est un caractère - "1", par exemple).

Le nombre de couches détermine le niveau d'abstraction que tu peux extraire de tes données. Un exemple classique est celui de la détection de contours par réseau de neurones : dans la première couche, tu as la valeur (0 ou 1) des pixels de l'image. Dans la couche suivante, tu peux apprendre/fixer des poids pour que tes neurones réagissent à une variation de la valeur des pixels (un contour donc). Mieux vaut commencer par une seule couche pour bien comprendre ce qu'il se passe.
Pour t'entraîner, tu peux essayer de faire un petit réseau qui apprend à se comporter comme des fonctions logiques ET/OU ... Et quand tu testeras le OU EXCLUSIF, tu devrais te rendre compte d'un problème (voir l'article d'Alp qui explique ce cas et pourquoi une deuxième couche est nécessaire).
R1D1 - Calculo Sed Ergo Sum -- en ce moment, M.A.R.C.E.L.
Avatar tiré du site bottlebot

#10 R2D21995

R2D21995

    Membre passionné

  • Membres
  • PipPipPip
  • 385 messages

Posté 28 juillet 2015 - 08:12

merci beaucoup.


Il faut toujours viser la lune, car même en cas d’échec, on atterrit dans les étoiles


#11 R2D21995

R2D21995

    Membre passionné

  • Membres
  • PipPipPip
  • 385 messages

Posté 29 juillet 2015 - 08:05

J'ai une petite question: est-ce que il y a une limite d'entrée ou pas.


Il faut toujours viser la lune, car même en cas d’échec, on atterrit dans les étoiles


#12 R1D1

R1D1

    Modérateur et Membre passionné

  • Modérateur
  • PipPipPipPipPip
  • 1 211 messages
  • Gender:Male
  • Location:Autriche

Posté 31 juillet 2015 - 12:14

J'ai une petite question: est-ce que il y a une limite d'entrée ou pas.


Dans le nombre que tu peux en mettre ? Oui et non.
- Non, parce que le principe reste le même indépendamment du nomibre d'entrées. Une entrée de plus rajoute simplement des poids de connexion en plus vers la sortie. Ça dépend du modèle, mais la sortie du neurone est calculée en faisant le produit scalaire entrée/poids, et ça s'accomode plutôt bien d'une taille variable.
- Oui, parce que plus tu augmentes la taille de ton entrée, plus tu augmentes le nombre de poids nécessaires, et plus tu vas mettre d'information en mémoire. On prend en général des variables de type "float" en C++, si tu as N neurones sur ta couche d'entrée et M sur ta couche de sortie, tu auras NxM float à garder en mémoire (soit NxMx4 octets). Tu multiplies également le nombre d'opérations à faire pour les mettre à jour.

Après, les gens qui travaillent sur des images envoient souvent 320x240 = 76800 pixels en entrée, ce qui est quand même pas mal comparé à un réseau à une dizaine d'entrées qui pourrait contrôler un robot.

N'hésite pas à nous montrer ce que tu fais, ça permet de donner un contexte aux questions et d'être plus précis dans la réponse.
R1D1 - Calculo Sed Ergo Sum -- en ce moment, M.A.R.C.E.L.
Avatar tiré du site bottlebot

#13 R2D21995

R2D21995

    Membre passionné

  • Membres
  • PipPipPip
  • 385 messages

Posté 01 août 2015 - 07:36

OK merci pour ta réponse. Pour l'instant j'essaye de comprendre le tuto d'alp.


Il faut toujours viser la lune, car même en cas d’échec, on atterrit dans les étoiles


#14 R2D21995

R2D21995

    Membre passionné

  • Membres
  • PipPipPip
  • 385 messages

Posté 01 août 2015 - 08:50

je vais essayer de coder un neurone pour la fonction ou mais j'ai une petite question.

dans le tuto il est marqué

 

 

1*0,1+1*0,8 = 0,9 >= 0,5

pour que mon neurone apprenne il faut que je modifie de manière aléatoire 0,1 et 0,8 et les valeurs devront être compris entre 0 et 0,9 non ?


Il faut toujours viser la lune, car même en cas d’échec, on atterrit dans les étoiles


#15 R2D21995

R2D21995

    Membre passionné

  • Membres
  • PipPipPip
  • 385 messages

Posté 02 août 2015 - 10:15

j'ai fais ça:

#include <stdlib.h>
#include <stdio.h>

int             apprendre()
{
  double        MAX;
  double        MIN;
  double        poid;
  double        poid1;
  int           reseau;

  reseau = 0;
  MIN = 0.01;
  MAX = 0.9;
  srand(time(NULL));
  while ((poid  = rand() / (RAND_MAX + (MAX / MIN))) >= 0.25 && (poid1  = rand() / (RAND_MAX + (MAX / MIN))) >= 0.25);
  printf("poid: %f\npoid1: %f\n",poid, poid1);
  reseau = 1 * poid  + 1 * poid1;
  printf("reseau: %i\n",reseau);
  return (reseau);
}

int             main(int argc, char *argv[])
{
  int   seuil;
  int   reseau;

  reseau = 0;
  seuil = 0.5;
  //printf("%i\n", apprendre());                                                                                                                                                                                                              
  while ((reseau = apprendre()) <= seuil)
    printf("Le neurone n'a pas encore bien appris\n");
  printf("Le neurone a bien appris. %i\n", apprendre());
  return 0;
}

qu'est-ce que vous en pensez ? C'est ça qu'il fallais faire ?


Il faut toujours viser la lune, car même en cas d’échec, on atterrit dans les étoiles


#16 R1D1

R1D1

    Modérateur et Membre passionné

  • Modérateur
  • PipPipPipPipPip
  • 1 211 messages
  • Gender:Male
  • Location:Autriche

Posté 03 août 2015 - 08:19

Euh, je ne comprends pas vraiment ce que tu fais.

Le principe de fonctionnement d'un réseau de neurones, c'est d'apprendre à partir d'un ensemble de données. Pour cela, on a généralement une ĥase d'apprentissage, et une phase d'utilisation du réseau ayant appris.
Avant d'aller plus loin, précisons quelque chose : il y a 3 manières d'apprendre.
- apprentissage supervisé : on dit au réseau ce qu'il doit apprendre. On lui donne des couples (entrée, sortie) pour qu'il apprenne par coeur quoi répondre à une certaine entrée. Par exemple, dans le cas du ET logique, on lui donne (entre autres) le couple ((1, 1), 1) qui signifie"si mes deux entrées sont à 1, ma sortie doit valoir 1.
- apprentissage non-supervisé : c'est un peu plus compliqué, on laisse le réseau trouver tout seul la structure des données. En général, on va donner au réseau une entrée, sa couche de sortie va être activée, et on ne garde que le neurone le plus activé. On apprend ensuite à répondre avec ce neurone pour la même entrée (ou des entrées similaires).
- apprentissage par renforcement : celui-là est entre supervisé et non-supervisé. On ne donne plus au réseau ce qu'il doit apprendre, mais on lui indique si ce qu'il a répondu est "bien ou pas bien". Pour une entrée, on renvoie au réseau un signal de renforcement qui est une valeur positive ou négative. Dans le premier cas, on incite le réseau à répondre la même chose pour des entrées similaires, ou au contraire, à ne pas répondre ça du tout.
Dans les deux premiers cas, on se base en général sur une information d'erreur entre la sortie désirée et la sortie obtenue, qu'on utilise pour corriger les poids.

Pour en revenir à ton code : faisons de l'apprentissage supervisé. Pour cela, il faut créer un ensemble de données à donner au réseau. Pour la fonction logique ET, ce seront des couples de valeurs d'entrée flottantes et la sortie binaire associée. Les quatre cas (0,0) (0,1) (1,0) (1,1) plus une dizaine de valeurs d'entrées intermédiaires, ça devrait suffire.
À chacune de ces entrées, tu vas ajouter la réponse attendue. À la fin, tu dois avoir une variable qui contient tout ça :

dataset = {((0,0), 0) ; ((0,1), 0) ; ((1,1), 1) ; ((0.2, 0.7), 0) ; ... } // Dataset sur lequel apprendre (pseudo-code).

Ensuite, tu as ton réseau. Si tu sais faire de la POO, je te conseille de créer une classe, c'est assez pratique. Dans tous les cas, il y a trois éléments principaux à ce réseau :
- ses poids (Nb d'entrée * Nb sortie = 2 * 1 dans notre cas).
- sa règle de calcul de l'activité de sortie (l'activité de chaque neurone de sortie est la somme pondérée des entrées par les poids, passée par une fonction non-linéaire ou seuillée - dans notre exemple, on seuille à 0.5)
- sa règle d'apprentissage. On peut se contenter de Widrow-Hoff, qui nous donne comment on modifie chaque poids w_i en fonction de l'erreur de prédiction (valeur de sortie désirée - valeur obtenue). C'est la partie V du tuto d'Alp.

Donc pour définir ton réseau, il te faut un tableau N*M de poids, une fonction qui l'utilise pour calculer la sortie, une fonction qui le modifie pour tenir compte de l'erreur (ou un attribut et deeux méthodes dans une classe).
Au début, on initialise les poids à des valeurs aléatoires (on peut aussi les initialiser à zéro). Cela représente le fait qu'on ne sait pas quelle fonction on va devoir apprendre. C'est normal, c'est la beauté d'un tel système : il peut apprendre à peu près tout ce qu'on veut, tant qu'on lui donne des exemples (et que le réseau est capable d'approximer la fonction, voir l'exemple du XOR du tuto de Alp).

On a donc un dataset, un réseau, on peut commencer à apprendre. Pour cela, on va tirer au hasard un exemple du dataset, et voir ce qu'il donne dans notre réseau. On appelle donc la fonction de calcul de la sortie avec l'entrée de l'exemple, et on obtient une valeur de sortie.
Au début, comme on a initialisé les poids aléatoirement, il y a de fortes chances que la sortie obtenue soit différente de la sortie désirée. Ça n'est pas grave, puisqu'on va de toute façon appeler la fonction d'apprentissage.
On calcule l'erreur, on modifie les poids, et la prochaine fois qu'on aura la même entrée, il est plus probable que le réseau réponde la bonne valeur.
Et hop, on peut recommencer ces deux étapes en tirant un nouvel exemple et en répétant les étapes précédentes.

Et quand est-ce qu'on s'arrête ? Pour ça, on va définir une valeur de convergence : tant que cette valeur est différente de zéro, on apprend (puisque ça veut dire qu'il y a e une modification à faire, et qu'on n'avait pas approximé correctement la fonction). Cette valeur, c'est simplement la somme des modifications sur les poids.
En pratique, on ne vérifie pas qu'elle vaille zéro, mais qu'elle soit inférieure à une valeur très faible "epsilon".

Maintenant qu'on a finit d'apprendre, on ne va pas arrêter notre programme tout de suite, ça serait dommage d'avoir faire apprendre notre réseau pour ne pas l'utiliser.
Ici, on va donner des entrées à notre réseau, et voir ce qu'il répond. Dans notre cas, on peut demander à l'utilisateur de saisir deux valeurs au clavier, et afficher la sortie. Si tout se passe bien, on devrait avoir une sortie qui reproduit la fonction ET.
R1D1 - Calculo Sed Ergo Sum -- en ce moment, M.A.R.C.E.L.
Avatar tiré du site bottlebot

#17 R2D21995

R2D21995

    Membre passionné

  • Membres
  • PipPipPip
  • 385 messages

Posté 04 août 2015 - 07:49

Que signifie N et M et que faire des poids ?

EDIT: c'est bon pour N et M mais si j'ai 0.2,0.2 c'est égal à 0 ou pas ?


Il faut toujours viser la lune, car même en cas d’échec, on atterrit dans les étoiles


#18 R1D1

R1D1

    Modérateur et Membre passionné

  • Modérateur
  • PipPipPipPipPip
  • 1 211 messages
  • Gender:Male
  • Location:Autriche

Posté 05 août 2015 - 10:06

Que signifie N et M et que faire des poids ?
EDIT: c'est bon pour N et M mais si j'ai 0.2,0.2 c'est égal à 0 ou pas ?


Est-ce que tu as bien compris en quoi consiste un réseau de neurones ? Si non, essaie d'expliquer ce que tu as compris pour que je puisse savoir quelles informations te manquent / sont inexactes.

N et M sont les tailles en nombre de neurone de tes entrée et sortie. Comme les poids connectent chaque entrée à chaque sortie, il y a donc N*M poids. Ce sont les poids qui permettent l'apprentissage en faisant des associations entre entrée et sortie.
Pour l'entrée (0.2, 0.2), ... c'est toi qui voit. Si tu veux que ton réseau apprenne à répondre 1 pour cette entrée, tu peux le donner en exemple dans ta base d'apprentissage. Si on veut faire apprendre la fonction ET, on peut décider (mais c'est vraiment TON choix) que le réseau de neurones doit considérer que ses entrées valent un 1 logique si leur valeur est supérieure à 0.5 (comme on fait souvent pour passer d'un signal analogique à un signal numérique en électronique : on place un seuil pour rendre binaire des valeurs continues).
Donc pour l'entrée (0.2, 0.2), la sortie désirée sera 0. Ce qui est puissant dans les réseaux de neurones (et les méthodes d'apprentissage automatique en général), c'est que ça n'est pas à toi de te casser la tête pour trouver comment le réseau doit réagir : c'est les données d'exemple qui vont déterminer ce comportement. Si tes données sont des exemples de fonctionnement de la fonction logique ET ou OU, le réseau trouvera lui-même les bons poids (aussi appelés paramètres) pour réagir comme ces fonctions.
R1D1 - Calculo Sed Ergo Sum -- en ce moment, M.A.R.C.E.L.
Avatar tiré du site bottlebot

#19 R2D21995

R2D21995

    Membre passionné

  • Membres
  • PipPipPip
  • 385 messages

Posté 05 août 2015 - 10:44

un réseau de neurones c'est des neurones qui sont connectés entre eux par les sorties.


Il faut toujours viser la lune, car même en cas d’échec, on atterrit dans les étoiles


#20 R2D21995

R2D21995

    Membre passionné

  • Membres
  • PipPipPip
  • 385 messages

Posté 05 août 2015 - 02:15

j'ai réessayé et voilà ce que ça donne:

float           dataset[10][3] = {
  {0.0 , 0.0 , 0.0},
  {0.0 , 1.0 , 0.0},
  {1.0 , 0.0 , 0.0},
  {1.0 , 1.0 , 1.0},
  {0.2 , 0.4 , 0.0},
  {0.2 , 0.2 , 0.0},
  {0.5 , 0.5 , 1.0},
  {0.5 , 0.7 , 0.0},
  {0.3 , 0.8 , 0.0},
  {0.7 , 0.7 , 1.0},
};

float           poids[10][3];

void    init()
{
  int   i;
  int   j;

  i = 0;
  j = 0;
  srand(time(NULL));
  for(j = 0; j < 10;j++)
    for(i = 0;i < 30;i++)
      poids[j][i]=(float)(rand() / (RAND_MAX + (0.9 / 0.01)));
}

int     calcul(int num, int num2)
{
  int i;
  int   j = 0;
  float total=0;
  for(i=0;i<30;i++)
    {
      if(dataset[num][j]==1)
        {
          total+=poids[num2][j];
          j++;
        }
    }
  return (total>0?1:0);
}

float calcule_poids(float valeur,int valeur_desiree,int valeur_obtenue,int valeur_entree)
{
  float result;

  result = (valeur + (valeur_desiree - valeur_obtenue) * valeur_entree * 10.0);
  return result;
}

void            apprendre(int num, int num2)
{
  int   i;
  int   j;
  int result;

  result = calcul(num,num2);
  while(i < 30)
    {
      poids[num2][0] = calcule_poids((float)poids[num2][0],num==num2,result, dataset[num][0]);
      i++;
      j++;
    }
}

int             main(int argc, char *argv[])
{
  init();
  int   i;
  int   j;

  i = 0;
  j = 0;
  for(j = 0; j <7;j++)
    {
      for(i=0;i<7;i++)
        {
          printf("t: %i ",calcul(i,j));
        }
      printf("\n");
    }
  /*on fait relier tous les poids avec tous les caractères*/
  for(j=0;j<7;j++)
    {
      for(i=0;i<7;i++)
        apprendre(i,j);
    }
  return (0);
}


c'est bon ? Si ce n'ai pas bon j'ai rien pigé de tout ça


Il faut toujours viser la lune, car même en cas d’échec, on atterrit dans les étoiles




Répondre à ce sujet



  


0 utilisateur(s) li(sen)t ce sujet

0 members, 0 guests, 0 anonymous users