'poids' d'une information

Le problème exposé dans ce sujet a été résolu.

Bonjour , je lis un cours d’introduction aux reseaux de neurones sur developpez.com. http://alp.developpez.com/tutoriels/intelligence-artificielle/reseaux-de-neurones/

Ma question concerne cette partie :

on note (xi)1 <= i < k les k informations parvenant au neurone. De plus, chacune sera plus ou moins valorisée vis à vis du neurone par le biais d’un poids. Un poids est simplement un coefficient wi lié à l’information xi. La i-ème information qui parviendra au neurone sera donc en fait wi*xi

J’ai eu un peu de mal a comprendre ce qu’etais ’w’ ( ca fait beaucoup de lecture tout ca .. ) , d’ou sort ce ’coefficient lie a xi’ ? Dans un rapport lineaire x/y , est-ce que wi serait yi , donc l’information lie a xi ?

edit :: en continuant en lire je me suis bien rendu compte que non .. on doit attribuer la valeur du poids , mais j<ai toujours pas compris comment attribuer cette valeur

+0 -0

Dans un réseau de neurones on a généralement la sortie exprimé de la forme $y_j = f\left(\sum_i{x_i\times w_i}\right)$. D’un certain côté, le coefficient w sert donc effectivement de poid individuel mais il est difficile d’en donner une signification

mais j’ai toujours pas compris comment attribuer cette valeur

Zérotisme

Alors justement je travaille sur ça en ce moment pour mon TIPE et je pense pouvoir t’éclairer sur ce point. Les poids sont attribués au hasard au début, puis modifiés au cours de l’apprentissage: en gros, tu envoies un exemple dans ton réseau de neurones, s’il le classe correctement, tu laisses les poids inchangés, sinon tu modifies les poids. C’est assez simple dans le cas d’un réseau à une couche (perceptron) mais ça se complique rapidement quand on a un réseau multicouches (avec des couches de neurones cachées). Il faut alors rétro-propager l’erreur pour ajuster les poids dans les couches cachées.

Evidemment, c’est une approche qui prend pas mal de temps: il repasser de nombreuses fois sur chacun des exemples de l’ensemble d’apprentissage pour faire converger les poids. Mais ça marche, avec les résultats que l’on sait :)

+1 -0

en continuant en lire je me suis bien rendu compte que non .. on doit attribuer la valeur du poids , mais j<ai toujours pas compris comment attribuer cette valeur

C’est là tout l’enjeu. :) Pour faire simple, à chaque fois que le programme fait une erreur (par exemple pour de la classification binaire type perceptron il donne la mauvaise classe), on va ajuster le poids de chaque coefficient de façon à ce que la nouvelle réponse soit plus proche de la bonne réponse. La façon exacte d’ajuster (que veut-on dire par "plus proche ?") dépend de pas mal de trucs, il existe plusieurs façons de faire dont le plus courant est la descente de gradient si je ne dis pas de bêtises !

+2 -0

mais j’ai toujours pas compris comment attribuer cette valeur

Zérotisme

Alors justement je travaille sur ça en ce moment pour mon TIPE et je pense pouvoir t’éclairer sur ce point.

Deathekirl

Oh je suis pas seul ^^ !

Il existe plusieurs méthodes dites d’apprentissage qui vont avoir pour but d’ajuster ces poids et/ou de changer la topologie du réseau pour lui permettre de s’améliorer sur un problème donné. Comme l’ont dit mes VDD, la rétropropagation d’erreur, ou encore descente de gradient, mais aussi les algorithmes génétiques par exemple. Mais il n’y a aucun intérêt à les paramétrer soit même. L’intérêt du machine Learning, c’est justement que c’est la machine qui apprend, pas toi ;) Si tu cherches une bonne ressource introductive, notamment sur la méthode de descente de gradient qui est la plus utilisée, je te conseille d’aller voir ceci : https://www.tensorflow.org/get_started/mnist/beginners

Oh je suis pas seul ^^ !

LeB0ucEtMistere

Tu fais un tipe cette année? Sur quel sujet? :ange:

Pour compléter ce que tu dis, je rajouterais qu’en général on combine les deux approches: on entraîne le réseau par rétro-propagation par exemple, et on optimise sa topologie grâce à des algos génétiques ou par validation croisée

+0 -0

Oh je suis pas seul ^^ !

LeB0ucEtMistere

Tu fais un tipe cette année? Sur quel sujet? :ange:

Pour compléter ce que tu dis, je rajouterais qu’en général on combine les deux approches: on entraîne le réseau par rétro-propagation par exemple, et on optimise sa topologie grâce à des algos génétiques ou par validation croisée

Deathekirl

Optimisation d’une IA par algo génétiques et réseau de neurones ;) ouais j’ai repiqué ma mp, l’année dernière j’avais fait mon TIPE sur l’algorithme X de D.Knuth et les problèmes de pavement :)

Pour en revenir au sujet, là je bosse avec un système d’AG seul qui évolue poids et topo du réseau :)

Merci a tous pour vos reponse , je comprend mieux maintenant :) !

edit : est-ce que pour l<attribution des poids nous devons penser a un poids qui DEVRAIT etre bon ou bien il n<est pas totallement faux de penser qu<il est possible de commencer avec tous des poids a 1 et d<ajuster au fur et a mesure ?

+0 -0

Tu peux pré attribué des poids si tu as des informations dessus, ça permet d’être plus prêt de la réponse. Normalement, ça aide. Cependant c’est souvent impossible, les modèles sont beaucoup trop gros.

Par contre tous les poids à 1 est une mauvaise idée. Il vaut mieux les fixer aléatoirement. Cela permet d’éviter des symétries : si tous tes poids valent la même chose initialement, ils vont tous évoluer de la même façon et donc être redondant.

Tu peux pré attribué des poids si tu as des informations dessus, ça permet d’être plus prêt de la réponse. Normalement, ça aide. Cependant c’est souvent impossible, les modèles sont beaucoup trop gros.

Par contre tous les poids à 1 est une mauvaise idée. Il vaut mieux les fixer aléatoirement. Cela permet d’éviter des symétries : si tous tes poids valent la même chose initialement, ils vont tous évoluer de la même façon et donc être redondant.

Kje

Et les poids c’est toujours entre 0 et 1 ? Donc le mieux c’est d’initialisé avec des valeurs aleatoire et de corriger selon la sortie.

Non c’est pas qu’entre 0 et 1, ça dépend de ton modèle. Ceci dit il vaut mieux contrôler leur amplitude pour éviter des effets de saturation ou d’instabilité numérique. Mais fondamentalement c’est pas toi qui les met à jour directement, c’est l’algorithme d’apprentissage.

+1 -0

Non c’est pas qu’entre 0 et 1, ça dépend de ton modèle. Ceci dit il vaut mieux contrôler leur amplitude pour éviter des effets de saturation ou d’instabilité numérique. Mais fondamentalement c’est pas toi qui les met à jour directement, c’est l’algorithme d’apprentissage.

Kje

ok donc en gros , le poids n’est qu’une valeur refletant la possibilité que le données analysés par la neurones soit positif ( en haut du seuil ) ou negatif ( sous le sueil )

On peut voir ça comme ça. La seule chose est que cette notion de seuil est assez peu utilisé en vrai. Une sortie binaire comme ça est, éventuellement, utilisé sur la dernière couche mais rarement en interne quand il y en a plusieurs. C’est très limitant. En pratique on utilise presque jamais, même en sortie, un seuillage. On va préférer utiliser un softmax par exemple. En gros au lieu de nous donner 0 ou 1 il va nous donner un nombre entre 0 et 1. C’est bien plus pratique pour pas mal de raisons :

  • Cela peut être interpréter comme une sorte de probabilité : si la valeur est à 0.6, c’est que notre réseau est moins confiant que quand il nous fournit 0.9.
  • Cela permet d’avoir une sortie continue et donc optimisable que la sortie soit correct ou non. Durant l’apprentissage tu peux donc utiliser TOUS les exemples et pas seulement ceux où tu t’es trompé (et c’est plus stable).

Mais en gros oui le poids, en valeur absolue, c’est une valeur qui reflète l’importance que tu donne a une des valeur d’entrée. Un poid de 0 masquera totalement la composante (elle n’aura pas d’influence sur la sortie) et une valeur beaucoup plus grande que les autres avantagera une composante par rapport aux autres.

Oui, ou pour être plus précis c’est une généralisation car une softmax peut être utilisé quand tu a N sorties. Chaque sortie donne donc un autre entre 0 et 1 et la somme de toutes fait 1. Le seuil doux/fonction logistique c’est un softmax avec 2 sorties.

+0 -0

Ok , et quand ils parlent d’utiliser la sortie des neurones est-ce un peu comme dans mon raisonnement ? …

Disons que je veux trier des images selon une couleur uni. Je le fais en 2 couche : 1 couche de 3 neurones qui calcules la probabilite que l’image soit rouge , vert , bleu. 1 couche de 1 neurone qui donne la couleur de l’image.

On aurait donc par exemple .. Couche 1 : neurone_rouge = 0.9 neurone_bleu = 0.6 neurone_vert = 0.1

Couche 2 : Prend en entrer ( 0.9 , 0.6 , 0.1 ) et donne le resultat , qui serait ici d’une maniere ou d’une autre ’mauve’.

En vrai tu dis rarement ce que dois faire les couches internes. C’est l’apprentissage qui va les régler. Toi tu donne des exemples durant l’apprentissage (des photos et le résultat attendu) et c’est l’apprentissage qui va choisir les poids. Ce que vont extraire les couches internes est rarement interprétable facilement.

Ca fait plusieurs jours que ca cogite et je crois avoir saisi l’essentiel … juste un dernier petit detail qui me trotte encore dans la tete … disons que j’ai une donnee X et 2 neuronnes. Est-ce que le poids associee a X est le meme pour les deux neuronnes ou il a un poids par entree ( donc un neurone le concidere plus qu’un autre … ) ???

Oui généralement les poids sont différents par neurones. C’est volontaire et c’est pour ça que je disais qu’il ne faut pas les initialiser égaux. Tu veux que chaque neurones fasse un travail différents (si ils ont des poids identique, un des deux est redondant). Ainsi chacun traite les informations de façon différente et, en les combinant en sortie, tu peux prendre une meilleure décision.

Parfais alors , merci beaucoup de tes explication j’y voit beaucoup plus clair maintenant grace a toi !! Voici un petit exemple .. si tu peut me dire si mes raisonnement etc.. sont bon.

Imaginons simplement un scroller tres simple ou un IA cours vers la gauche et doit : soit sauter par dessus un trou, soit se pencher sous un bloc.

On a donc 2 donnees : soit deux 1 ou 0 selon si les cases respectives ont un bloc ou un trou .. On a 2 neurones : 1 pour se pencher , 1 pour sauter.

ce qui me donne basiquement …

 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
#include <iostream>
#include <vector>

class Neurone{

    private:
        double seuil_;

    public:
        Neurone(double seuil = 0.5) :
            seuil_{seuil}
        {}

        bool activate(std::vector<int> datas_ , std::vector<double> weigths_){
            double sum = 0;
            for(size_t i = 0; i < datas_.size() ; i++){
                sum += (datas_[i]*weigths_[i]);
            }
            std::cout<<sum <<std::endl;
            return sum > seuil_ ? true : false;
        }

};

int main(void){
    std::vector<int> datas_1{1,0}; // soit un bloc en haut mais pas de trou
    std::vector<int> datas_2{0,1}; // soit un trou mais pas de bloc
    std::vector<double> weigths_1{0,1};
    std::vector<double> weigths_2{1,0};
    Neurone n_saut(0.5);
    Neurone n_penche(0.5);

    std::cout<<"Premier test : un bloc mais pas de trou" <<std::endl;

    bool saut = n_saut.activate(datas_1,weigths_1);
    bool penche = n_penche.activate(datas_1,weigths_2);

    if(saut)
        std::cout<<"Pour le premier test , il saute" <<std::endl;
    else
        std::cout<<"Pour le premier test , il ne saute pas" <<std::endl;

    if(penche)
        std::cout<<"Pour le premier test , il se penche" <<std::endl;
    else
        std::cout<<"Pour le premier test , il ne se penche pas" <<std::endl <<std::endl;

    std::cout<<"Deuxieme test : un trou mais pas de bloc" <<std::endl;

    saut = n_saut.activate(datas_2,weigths_1);
    penche = n_penche.activate(datas_2,weigths_2);

    if(saut)
        std::cout<<"Pour le deuxieme test , il saute" <<std::endl;
    else
        std::cout<<"Pour le deuxieme test , il ne saute pas" <<std::endl;

    if(penche)
        std::cout<<"Pour le deuxieme test , il se penche" <<std::endl;
    else
        std::cout<<"Pour le deuxieme test , il ne se penche pas" <<std::endl;


    return 0;
}

`

et avec comme sortie ( je peux pas copier la console … ) , ca me parait bien. Premier test : penche , pas de saut Deuxieme test : saut , se penche pas

+0 -0

L’implémentation du neurones semble correct (même si les poids devraient être une donné interne comme le biais et qu’on fait jamais comme ça en vrai). Le reste j’ai pas spécialement regardé. Le problème est étrange et en réalité tout l’intérêt de ce type d’algorithmes c’est que ce n’est pas toi qui va spécifier les poids et biais, tu les fais apprendre.

Édit : à si il y a un soucis : tu n’a que deux états de sorties (je saute ou je me penche) donc tu ne devrais avoir qu’une sortie (soit je saute, soit je me penche). La ton truc peut décider de sauter et de se pencher en même temps !

+0 -0
Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte