Je te passerais les sources si tu veux.... Mais tu risques d'être déçu (voire un peu perdu). Mon code est vraiment en bordel.
Par contre, dans ton calcul, n correspond à quoi exactement ? Le nombre de neurones ?
Je te passerais les sources si tu veux.... Mais tu risques d'être déçu (voire un peu perdu). Mon code est vraiment en bordel.
Par contre, dans ton calcul, n correspond à quoi exactement ? Le nombre de neurones ?
n correspond au nombre de neurones sur ta couche, en gros si tu as 1000 neurones et que les poids sont tous à 1, ça fait 1000 en entré du neurone de la couche suivante et ça va mettre du temps à diminuer alors que avec du 1/sqrt(n) tu n'as que au maximum une valeur total de sqrt(1000) soit 31. Même si en vrai tout les poids ne sont jamais à 1 mais c'est pour donner une idée.
Alors ? Tu m'as pas dit ce que ça avait donné ?
Je n'ai finalement pas laissé tourné toute la nuit (j'aurais probablement dû)... J'ai toujours l'impression de rester bloquer dans certains minima locaux.
Après, je suis certainement trop impatient, j'attends rarement plus de 200 itérations.
J'i essayé de changer un peu l'architecture pour voir si ça ne réglerais pas le problème. J'ai donc transformé la première couche RELU en SIGMOID et la seconde couche de SIGMOID à HTAN. La couche de sortie est toujours en SIGMOID.
Ca tourne, je passe vite de 90% à ~30% (en 2 ou trois itérations, parfois plus, parfois moins) et à partir de là, ça oscille autour de ce point.
Maintenant que j'en parle, je me dit que le principal problème doit venir de mon impatience ! Je vais laisser tourner quelques heure encore voir ce que ça donne.
Tu ne dois pas faire ça je pense, laisse tanh(x) sur toute les couches car utiliser sigmoïde et tanh(x) ça ne fonctionnera pas car tanh(x) te retourne une valeur entre -1 et 1 alors que sigmoïde entre 0 et 1 du coup en passant de tanh(x) à sigmoïde tu perds la moitié de ton information. Si tu as lu ça quelque part, j'aimerais beaucoup que tu me donnes le lien de l'article car ça ne me paraît pas logique du tout.
On ne perd pas vraiment d'information : on passe plutôt d'un x (entre 0 et 1) à 2 (x - 0,5) (entre -1 et 1). Avec une ReLU, par contre, on perd plus d'informations : cette fonction écrase tout ce qui est négatif. Par contre, elle fonctionne nettement mieux que les autres, dirait-on.
Vous souhaitez participer aux rubriques Qt (tutoriels, FAQ, traductions) ou HPC ? Contactez-moi par MP.
Créer des applications graphiques en Python avec PyQt5
Créer des applications avec Qt 5.
Pas de question d'ordre technique par MP !
C'est pas faux, enfin je pense quand même que c'est mieux de garder la même fonction d'activation sur tous les couches mais à près c'est plus personnel. J'ai pas quand il y a trop de paramètres à modifier sur un réseau de neurones.
Bonjour,
Je ne m'y connais pas encore suffisamment pour détailler mathématiquement le fond de ma pensé, mais, si j'en avais les compétences (en développement), je choisirais même un réseau entièrement aléatoire. Uniquement un sac de neurones dont les fonctions d'activation sont affectées aléatoirement et dont les liens sont créés aléatoirement aussi. Seules les entrées et sorties seraient définies clairement.
Mais bon. Ça, c'est pour plus tard, il faudrait déjà que j'arrive à faire un MLP de 300 neurones qui me donne un vrai résultat..... Et visiblement, je n'y suis pas encore. Toujours l'impression de bloquer sur un minimum local (n'est-ce qu'une impression ?).
@Matthieu76 : ce n'est pas une mauvaise stratégie, je pense, au moins en première approximation. Maintenant, si les réseaux neuronaux ont tellement de succès, c'est justement parce qu'il y a un énorme paquet de paramètres… Par contre, prépare-toi à faire varier la fonction d'activation au niveau de la couche de sortie : une sigmoïde pour une régression, ça ne le fera pas trop (sauf si la plage de valeurs en sortie correspond à celle de la sigmoïde).
Vous souhaitez participer aux rubriques Qt (tutoriels, FAQ, traductions) ou HPC ? Contactez-moi par MP.
Créer des applications graphiques en Python avec PyQt5
Créer des applications avec Qt 5.
Pas de question d'ordre technique par MP !
Bonjour à tous,
Je suis actuellement en train de refaire au propre tout mon code, et, je souhaite y ajouter la fonction "batch".
Jusque là pas de soucis, mais, une incohérence dans mon code m'a amené à me requestionné sur l'algorithme du batch.
Dans le batch, nous sommes d'accord que les poids du réseau ne sont mis à jour qu'à l'issue d'une boucle sur un certain nombre d'exemples d'apprentissage, mais dans ce cas, comment dois-je intégrer les x_i issus des sorties relatives à un exemple ?
J'ai donc revue le tuto de alp pour mieux comprendre comment implémenter le batch, mais il y a certaines choses que je ne comprends pas :
Le code ci-dessus est à répéter pour chaque neurone.
Entrée : n poids reliant les n informations à notre neurone ayant des valeurs quelconques
N exemples (X_k, yk) où X_k est un vecteur à n composantes x_i,
chacune représentant une information de cet exemple
Sortie : les n poids modifiés
POUR 1 <= i <= n
dw_i = 0
FIN POUR
POUR TOUT exemple e = (Xk, yk)
Calculer la sortie sk du neurone
POUR 1 <= i <= n
di = dw_i + alpha*(yk - sk)*x_i
FIN POUR
FIN POUR
POUR 1 <= i <= n
w_i = w_i + dw_i
FIN POUR
j'ai bien compris que le terme "di" correspond en fait au delta, et j'imagine que les w_i correspondent aux poids des synapses du neurone . De même, les x_i correspondent aux valeurs des dendrites des neurones de la couche précédente.
Ce dont je souhaite être sur, c'est la relation entre "di" et "dw_i" en fait. Est-ce que la ligne "di = dw_i + alfa*(yk - sk)*x_i" est égale à "di += alfa*(yk - sk)*x_i" en considérant que "di" est remis à 0 une fois les poids mis à jour ?
J'imagine que oui, mais j'aimerais en être certain avant de refondre ma partie de code correspondante...
Merci d'avance !
Ça existe déjà, ça s'appelle le reservoir computing, regarde de ce côté pour voir comment ça fonction. Apparement ça fonctionne bien même si je suis un peu sceptique.
Oui évidement mais c'est pas trop compliqué ça, j'ai des tanh(x) dans mes couches cachées mais une sigmoïde en sortie car je trouve cela c'est plus simple d'avoir des sortie entre 0 et 1. À part ça je ne fais pas de régression et ne compte pas en faire pour le moment donc bon ... et puis ça reste juste un re-scale de ma sigmoïde pour la faire varier entre ma valeur min et ma valeur max ?
Pas exactement, en faite c'est beaucoup plus simple que ça. Juste tu prends tes x entrée (x étant la taille de ton batch) puis tu fais la moyen de chaque input puis de chaque sortie et tu entraînes dessus. Si ton entrée 1 c'est {5, -1, 3} avec une sortir de {0, 0, 1} et ton entrée 2 c'est {0, 5, 8} avec une sortir de {1, 0, 1}, si tu prends un batch de 2, tu entraineras ton réseaux sur un nouvelle exemple qui sera : {2.5, 2, 5.5} en entrée et {0.5, 0, 1} en sortir. Tu comprends mieux ?
Sinon autre point, à mon stage de M2 j'ai bossé sur des réseaux de neurones à spikes (théoriquement moins bon que des neurones classiques) et sur la MNIST, en apprentissage non-supervisé, avec seulement 5 itérations de la base de donnée, sans batch, sans rien, sans momentum, sans calcul d'erreur, avec un code un peu pourrie, avec juste 1 seul couche de 100 neurones, j'ai réussi à obtenir 84% de classification soit 16% d'erreur. Fait des tests avec seulement 1 couche caché de 100 neurones et 5 itérations de la base et si tu n'arrive pas à avoir au moins aussi bien, c'est qu'il y a une c****** quelque part !!!!! Comment peut-on avoir une meilleure reconnaissance en non-supervise ???? Ça m'intrigue beaucoup, de mon côté aussi je fais des testes sur la MNIST avec mon propre code mais je n'arrive pas à passer les 60% de classification. Si je n'y arrive pas au 80%, je vais tester avec tensorflow en récupérant un projet github déjà tout fait... Et si là non plus je n'arrive pas minimum 85% avec 100 neurones .......
Du coup je fais continuer mes tests sur 100 neurones et 5 itérations de la base comme ça je peux faire beaucoup de tests (environ 10 min par simulation).
PS : Pour l'instant fait tes test avec seulement 100 n et une chouche cachée ça ira beaucoup plus vite, et tu verras pour augmenter quand tu aura déjà 80% avec ça. Et aussi pas besoin d'aller jusqu'à 100 itérations, 10-20 itération son largement suffisante normalement, si ça ne converge pas après 10 itération, augmente ton pas d'apprentissage.
Bonjour,
Merci pour ces retours ; je vais essayer de faire comme tu me dis, mais atteint déjà les 80% de classifications en une seule itération ; le problème, c'est pour tomber en dessous.
Autre point, j'ai découvert un bug majeur dans mon implémentation initiale ! Les poids de la première couche (entre le vecteur d'entrée et la première couche de neurone) n'étaient pas mis à jour ! J'ai donc corrigé ça, mais malheureusement, ça ne me change pas grand chose... Je reste bloqué entre 12% et 30% d'erreur selon la qualité du réseau initial...
Je continue cependant le nettoyage de mon code ; je vais peut-être trouver d'autres fioritures de ce genre....
Bonjour à tous,
Alors je n'ai pas terminé la remise à neuf de mon code, ni l'implémentation du batch.... Cependant, j'ai implémenté une toute simple linéarisation de mes données d'entrée (je divise toutes les entrées par la valeur maximum de ces dernières).
Résultat : j’atteins moins de 16% d'erreur dès la première itération, et je passe très vite (en moins de 10 itérations) à moins de 10% !!!
J'ai donc laissé tourné un peu, et, bien que je pense ne pas avoir tiré le maximum de mon réseau, je me suis arrêté à moins de 4% d'erreur.
Je suis donc très content de mes résultats, et je remercie grandement la personne qui m'a demandé d'implémenter ça.
En y réfléchissant, cette "linéarisation" tombe sous le sens ; les poids des premiers synapses convergent nécessairement plus vite étant donné la valeur initiale d'affectation de ces derniers....
Finalement, ce petit exercice "simple" (pour quelqu'un de plus averti que moi aux réseaux de neurones) m'aura énormément appris. Ce premier objectif est donc en bonne partie atteint.
Je passe donc ce thread en "résolu", et je remercie tout ceux qui m'ont aider jusque là. Je vais donc réfléchir un peu plus sérieusement à mon prochain projet, et je reviendrais très certainement vers vous.
Au passage, pour ceux qui souhaiteraient en savoir plus sur mon code ou tout autre élément, je répondrais très volontiers à vos questions, et, je peux fournir mon code. malheureusement ce dernier est encore non nettoyé, certainement très peu compréhensible et largement optimisable, mais il a l'avantage d'être relativement court et léger.
Merci encore et à très bientôt !
C'est plutôt une opération de normalisation. Tant qu'à faire, tu peux aussi retrancher la variance de tes données, histoire de tomber avec des données qui ont une moyenne nulle et une variance unitaire : http://scikit-learn.org/stable/modul...StandardScaler.
Vous souhaitez participer aux rubriques Qt (tutoriels, FAQ, traductions) ou HPC ? Contactez-moi par MP.
Créer des applications graphiques en Python avec PyQt5
Créer des applications avec Qt 5.
Pas de question d'ordre technique par MP !
Merci pour cette idée; je verrais si je peux l'implémenter dans la foulée.
Pour information, depuis mon dernier post, j'ai enfin pu remettre un peu plus au propre mon code. Je laisse tourner depuis tout à l'heure avec un très léger momentum, et, à la 50ème itération, j'en suis à 2,56% d'erreur en généralisation sur la population de test, et ça ne demande encore qu'à descendre !
Je verrais en suite ce que ça donne sur la population de validation, donc je ne veux pas me réjouir trop vite, mais je suis déjà très content de cette avancée majeure étant donné mon niveau dans le domaine !!
Merci encore !
Bonjour,
Je suis en train d'écrire ma propre librairie NN sans librairie de calcul matriciel (le calcul se fait via boucles imbriquées... mais c'est ce que fait une librairie matricielle de toute façon, n'est ce pas...)
Je l'ai testé avec succès sur l'émulation du XOR, OR et AND (2 entrées,4 neurones, 3 sorties)
J'ai testé la reconnaissance de caractère Mnist avec la configuration suivante:
384 entrées, une couche de 120 neurones et 10 sorties avec fonction d'activation Sigmoid.
Actuellement, j'obtiens un taux de reconnaissance de 75% seulement.
Pour information, dés que j'ai introduit un facteur de drop_out, j'ai fait un bond important, je ne sais pas si tu l'as déjà fait, mais ça peut être une piste à explorer.
Bonjour,
Tout d'abord, je te souhaite bon courage pour la suite de ton aventure ; la puissance des réseaux de neurones est vraiment fascinante !
En suite, en ce qui concerne ta configuration, je vois que tu as 384 entrée, pourquoi ? Les images font 28 x 28 soit 784 pixels... Dans un premier temps donc, je te suggères de vérifier ton implémentation concernant le chargement des images.
En suite, pour une seule couche de 120 neurones, pour ma part, j'obtiens moins de 8% d'erreur sur la première itération, moins de 3% d'erreur à la 7ème itération et ça descend encore...
Un conseil donc, qui m'a permis de passer de 12% d'erreur mini à 1,7% d'erreur, c'est de t'assurer un bon traitement de tes images en entrée (une simple normalisation est un minimum je pense).
En suite, il faudrait voir quelles valeurs tu as pour tes hyper-paramètres....
Pour le drop-out, jamais essayé encore... Je n'ai pas encore prévu d'implémenter la chose, mais si tu me dis que ça apporte un gain significatif, je commencerais à me pencher sur le sujet.
Non pas exactement, une bonne bibliothèque fera des optimisations que tu ne pourras pas faire de toi même, surtout si tu trouves une bibliothèque qui fait du multi-threading pour le calcul matriciel. Mais même sans multi-threading, avec une bonne bibliothèque tu peux gagner au moins un +50% de vitesse sur ton code si tu l'utilise bien.
Vous avez un bloqueur de publicités installé.
Le Club Developpez.com n'affiche que des publicités IT, discrètes et non intrusives.
Afin que nous puissions continuer à vous fournir gratuitement du contenu de qualité, merci de nous soutenir en désactivant votre bloqueur de publicités sur Developpez.com.
Partager