Partage
  • Partager sur Facebook
  • Partager sur Twitter

NeuralNetwork remplacer sigmoid par softmax

Sujet résolu
    15 septembre 2017 à 7:40:40

    Salut à vous,

    Honnêtement, je ne sais même pas comment décrire le problème.

    Je veux que tout soit par NUMPY. Pas de tensorflow, pymlp, pybrain, ... (TROP Facile, et on voit rien de ce qui se passe à l'arrière)

    Il y a quelques années, j'avais créé un petit neural network, avec 1 output. Il y a beaucoup d'exemple sur internet, qui fonctionne très bien.

    Ce qui rendait les équations, assez simple, à visualiser.. puisque c'était un problème binaire. 

    Depuis environs 6 mois facile, j'essaye de convertir le logit (y_hat) (output activation), vers softmax.


    À la place d'un problème binaire, je veux une classification. Mais comment, sans tout modifier ?

    Si je prends (admettons): cet exemple, puisque je sais qu'il fonctionne et en ligne pour tout le monde.. Comment convertir et utiliser softmax?

    Je me retrouve toujours avec un problème d'alignement, entre le delta_l2(z3) et l'observation (X), dans le dC_dw1.

    Ce qui est normal, puisque en ayant 3 outputs, je me retrouve avec le nombre de batch(episodes) * 3

    Donc, impossible de calculer le delta du weight 1 (Input), puisque j'ai 3x le nombre demander par delta 1.

    Dois-je multiplier tous les prédictions dans un, avant de calculer le delta 1?

    Quelqu'un aurait un bon exemple, comment utiliser softmax, à la place de sigmoid?

    Dois-je remplacer sigmoid, ou utiliser softmax après avoir sigmoid?

    J'ai essayé de créer un petit exemple, avec de fausse donnée, mais j'avais plus de 150 lignes.

    Si personne comprend le problème. (Avec le même exemple  (site)), je vous le donnerai.

    • J'ai essayé avec un onehot-line encoded (labels)
    • J'ai essayé avec Sigmoid, mais le coût avec loglikelilhood.
    • J'ai essayé avec un cross-entropy.

    J'ai tellement lus de documentations et essayés d'exemples, que là je suis complètement perdu! Rien est standard ! (j'ai 20 pages googles, 100% surlignés, donc lus)

    • Personne utilise la même initialisation de weights. (np.random.randn, np.random.unitform, np.random.random)

    Ce qui est normal, tout dépend de la fonction d'Activation. Sigmoid (-1, 1), Softmax(0, 1), ReLU(0, 1)

    • Personne utilise la même façon de feed forward. (Ils utilisent outer, multiply, dot, einsum...)
    • Personne utilise la même façon de back propagation (Compute Gradient).

    Même que, la plupart utilise deux fonctions d'activations pour forward, mais n'utilise qu'une seule fonction dans le back propagation.

    Disons, que c'est mélangeant.

    Pour en ajouter, certains utilise des batchs, d'autre calcule le gradient directement à chaque itération.

    Les batchs sont 100x plus rapides, lorsque le nombre de hidden et output augmente.

    Dans l'exemple, tout est par batch (fin de la partie)

    Je cherche simplement à comprendre comment utiliser le softmax, à la place de sigmoid.

    Si vous voulez un exemple, je le posterai prochainenement. (Il est déjà fait, mais j'essaye de simplifié les lignes, entre sigmoid et softmax)

    PS: Je parle de classification, parce que j'aimerais que chaque ACTIONS, soit indépendant. (Avoir la probabilité que tel touche soit appuyé)

    Dans l'exemple du site, il y a 6 actions (Jeu de Pong, module gym)

    C'est peut-être pas le bon exemple, pour une classification, mais tant qu'à créer de fausse données.


    Pour finir, je demande de l'aide parce que cela fait très longtemps, que j'essaye et laisse rouler le script (24/h), pour voir si il y a amélioration... mais je crois que je perd du temps, puisque je comprend pas la logique.

    Merci à vous, de m'éclairer.

    A+

    -
    Edité par nolimitech 15 septembre 2017 à 8:00:55

    • Partager sur Facebook
    • Partager sur Twitter
      15 septembre 2017 à 12:12:51

      Bonjour,

      Alors je vais essayer de ne rien rater en reponse :)

      Quelqu'un aurait un bon exemple, comment utiliser softmax, à la place de sigmoid?

      Alors La sigmoid permet de te fournir un % de prediction. Dans un exercice de classification a 2 classes (disons hot-dog ou non hot-dog sur des images google). Quand tu auras fini de train ton NN, a la vu d'une image la sortie de ton NN sera un entier entre -inf et +inf. en le passant au travers de la sigmoid, tu aura un %

      • Si ton NN sort 0, alors il n'est pas sur (50% de change de hot dog et 50% de non hot dog). 
      • S'il sort 1000, alors la sigmoid vaut presque 1 donc c'est un hot dog a 99.999 ...  %
      • INversemenet s'il sort -1000, il est sur a 99.999... % que ce n'est pas un hot dog

      Concernant le softmax, ca fait pareil mais en multiclass. Si tu prends le MNIST, ta sortie doit etre 0,1,2,3,4,5,6,7,8,9. Du coup tu ne peux pas utiliser la sigmoid. tu auras pas exemple [150,150,0,40,12,0,0,0.1,8]. Si tu passes tous dans la sigmoid alors il y a 99% de chance que ce soit 0 ou 1 (autrement dit ca n'a absolument aucun sens). En remplacement tu passes ca dans un softmax qui fait le ratio de chaque valeur par la somme du tableau (dans ce cas 360). Du coup il y aura 150/360 % de chance que ce soit 0 ou 1. C'est tout de suite plus logique. 

      Dois-je remplacer sigmoid, ou utiliser softmax après avoir sigmoid?

      Aucun des deux, c'est soit l'un si tu est en bi-classe soit l'autre en N-classe (par ex sur gym le reverse pendulum, c'est la sigmoid a utiliser et dans ton cas le softmax)

      Personne utilise la même initialisation de weights. (np.random.randn, np.random.unitform, np.random.random)

      Alors la je ne vais pas te passer toute la théorie mais l'initialisation de doit pas etre fait avec juste une loi uniforme. C'est lié au problème du vanishing/exploding gradient. La meilleure initialisation a l'heure actuelle s'appelle la He-Initialisation (celle par defaut dans Tensorflow il me semble). TU aura plus d'info ici mais attention c'est pas simple :D

      Personne utilise la même façon de feed forward

      Alors ca je ne sais pas trop, le principe du feed forward est de faire la multiplication matricielle c'est tout (pas terme a terme attention).

      Personne utilise la même façon de back propagation

       La pareil je ne suis pas un expert mais la backpropagation etant TRES couteuse en calcul, je sais que tensorflow a crée/mis en place un moyen de calculer le gradient à la volée et ainsi eviter pas mal de calcul/utilisation mémoire. Par contre le pourquoi du comment... Pareil dans ton cas tu ne cherches pas vraiment a faire un DNN standard mais bel et bien du reinforced learning ou tu applique le gradient sur ton reward. C'est plus compliqué et je n'arrive pas moi meme a faire certains exos simple sur gym donc pour t'aider :s

      Même que, la plupart utilise deux fonctions d'activations pour forward, mais n'utilise qu'une seule fonction dans le back propagation.

      Ca il me semble que ca peut arriver si tu utilise le RELU/Leaky-RELU en activation. Dans ton cas tu travailles aussi sur de l'image (CNN), dans ce cas je ne sais pas comment ca marche avec le maxpool...

      Pour en ajouter, certains utilise des batchs, d'autre calcule le gradient directement à chaque itération.

      La je crois que tu te melange les pinceaux. Le principe du batch est d'alléger la memoire. Imagine tu as 1 000 000 000 de données sur 32 features en float32, Il te faudra 1M * 32 * 4octets (4 octets = 32 bits) = 128 go de ram ! Du coup ce qui se passe c'est que tu envoies des batchs de par exemple 150 (19ko) que tu calcule en feedforward pour backpropagation pour regler legerement les weight, ensuite 150 autres etc ... En parrallele tu peux calculer le gradient a la fin puis back-propager l'erreur ou le faire a la volée (je ne sais pas comment, cf au dessus).

      Dernier point, le OneHot Encoder ne sert pas a decomposer la sortie mais bel et bien rendre "logique les inputs". Je sais pas si tu as fais l'exercice avec le cout des maison sur OC mais tu as 'lexercice type pour ca. En gros tu as des surfaces et un arrondissement et tu dois estimer le prix. Si tu pars betement tu vas laisser les arrondissements en entier et tu aura un modele du genre :

      Loyer = A * Surface + B * Arrondissement + Bias

      Ce qui n'a aucun sens car le prix certe varie par rapport a l'arrondissement mais ce n'est pas lineaire, qui te dit que l'arrodissement 10 sera n fois plus cherc que le 9 qui lui meme sera n fois plus cher que le 8 etc ...

      Dasn ce cas le OHE est parfait car tu auras :

      Loyer = Somme(Surface * Arrondissement_i * h(i)) + bias

      Avec h(i) = 1 si et seulement si i est le bon arrondissement. Cela equivaut a faire n-regression linéaires en 1. Par contre attention au fleau de la dimension !

      En esperant que ca aide

      • Partager sur Facebook
      • Partager sur Twitter
        17 septembre 2017 à 17:49:06

        Salut,

        Tout d'abord, merci beaucoup pour votre réponse. Vraiment c'est très complète.

        (Pour tout ce qui est écrit, j'ai encore pris le même exemple, du post précédent (Avec gym). C'était plus simple, que de copiés mon exemple à 310 lignes. De plus, c'est le seul qui fonctionne avec plus de 1000 neurones, sans que l'update prenne 1 heure. (C'est le seul qui calcul pas un deuxième forward dans le back-propagation, puisqu'il prend ceux du episode_hidden_layer_values (a2 x nb_épisodes) ))

        Tous les autres, recalcule un forward dans le back-propagation, donc parcourir tous les weights et calcul le loss gradient, ce qui est complètement fou, avec un poids de 2,000,000 en weights.ravel()

        Je trouve seulement, qu'il n'y à pas d'exemple softmax, qui fonctionne sur des NN de 1000 - 10,000 neurones.

        Pour votre dernière réponse, non je connais pas cet exercices, si vous pouviez me donner le lien, ce serait très agréable, merci d'avance :)

        Pour la question de batch, ouf, j'en avait aucune idée, pour la mémoire vive. C'est quelque chose que j'avais jamais pensés. Haha. C'est très logique effectivement. Moi, je mets tout dans une classe ou liste, mais j'avoue que ça doit manger la mémoire, ouch.)

        Pour la première réponse, c'est exactement là où je bloque. C'est-à-dire que, je sais pourquoi je dois utiliser le softmax, mais je sais pas quoi je fais avec. (Peut-être que l'exercice, dont vous parlez m'éclairera).

        Admettons que j'ai :

        TARGETS_CLASS = ['Left', 'Right'] # Bon, c'est presque binaire, comme problème, mais bon.
        LABELS = [i for i in range(len(TARGETS_CLASS))]
        ONEHOT = np.eye(np.max(LABELS) + 1)[LABELS] ## import numpy as np
        
        Input, Hidden, Output = 10, 5, 2
        
        batch_size = 33 #(gym, donne environs 1020 épisodes, en moyenne, donc pour ici c'est 33 :))
        
        weights_input = np.random.randn((Input, Hidden)) / np.sqrt(Input)
        
        weights_output = np.random.randn((Hidden, Output)) / np.sqrt(Hidden)

        FORMULES:

        LÉGENDE:
        X   W1    z2(a2)  W2    z3(y_hat ou a3 ou logit)
        O---->------H------>------O
        FORMULES:
        def forward(X, W1, W2):
            """
            z2 = (X * W1) + b1
            a2 = f(z2) ## ReLU
            z3 = (a2 * W2) + b2
            logit = y_hat = a3 = f(z3) ## Softmax
            """
        def backward(W1, W2): 
            """
            ∂J / ∂W2 = Σ * ( (∂ ½ (y - y_yat)**2) / ∂W2 )
            ∂J / ∂W2 = (y - y_hat)
            Donc:
             y = labels
             y_hat = f(z3) = logit
            Traduit:
            ∂J / ∂W2 = -(y - y_hat) (∂y_hat / ∂W2)
            ∂J / ∂W2 = -(y - y_hat) (∂y_hat / ∂z3) (∂z3 / ∂W2)
            Si on remplace (∂y_hat / ∂z3) par fprime(z3):
            ∂J / ∂W2 = -(y - y_hat) * fprime(z3) (∂z3 / ∂W2)
            #Ensuite:
            ∂J / ∂W1 = g * W2.T * fprime(z2) (∂z2 / ∂W1)
            """

        ## POUR LE SIGMOID:

        logit = array([ 0.9764 ])

        Normalement, en sigmoid, cela retournerait qu'un seul output, donc une seule probabilitée (pour le binaire, 0 ou 1). Il suffisait de prendre la probabilité et d'y retourner la prédiction voulue.

        def predict(proba):
            random_value = np.random.uniform() ## Pour le mélanger un peu 
            if random_value < proba:
                return 2
            else:
                return 3
        
        action = predict(logit)

        Admettons, pour gym c'étais 2 pour gauche, 3 pour droite (ou vice,versa). Ensuite, en sachant que les LABELS, pouvait être que 0 ou 1, suffisais de convertir le 2 en 1 et le 3 en 0.

        Pour calculer le gradient, c'est y - y_hat. (logit - labels_binaire)

        ## POUR LE SOFTMAX:

        Puisque, je fais 33 épisodes (une batch de 33), et que j'ai 2 outputs. Le forward me donnera ceci: (le softmax)

        logit = array([ 0.463, 0.536]) # maximum 1
        Donc, pour prédire dans le softmax, je prends np.argmax():
        def predict(proba):
            return np.argmax(proba, axis=0) ## Si je mets 1 j'ai une erreur, pourtant cela devrait être le cas 
        C'est la probabilités, entre les deux outputs. Donc, ici ce sera le 0.536, qui est le label 1. 
        Mais je fais quoi, avec tout cela. ? :)
        En résumé:
        (En fait, je crois que tous mes erreurs découlent de ce principe que je comprend pas. Je sauvegarde les deux gradients (les 2 outputs), mais je crois que le gradient devrait être qu'un nombre float. Pas 2 float dans un array. C'est surment pour cela que rien fonctionne après. Je me retrouve avec 2x gradient)

        J'ai 2 résultats (2 outputs) dans l'array, mais je ne peux pas multiplier (2, 33) avec (66, 10). (Le 66 viens de 2ouputs x 33episodes et 10 viens du Input weights).

        Il faut que je fasse quelque chose, avec ce (2, 33), avant d'Exécuter la fonction d'activation entre input et hidden.

        En reprenant votre exemple, qu'es-ce que je fais avec le 150/360% de chance que ce soit 0 ou 1 ? Si c'est y - y_hat, je calcul le gradient à partir de quoi?

        De celui que j'aurais choisit ? Donc, le plus haut pourcentage? 

        Je reçois (2, 33), parce que je sauvegarde les 2 gradients (chaque output).

        Il faudrait donc, que le gradient soit qu'un float?

        Donc, soit je prends le logit et je trouve le gradient par y - y_hat, soit je calcul le loglikelilhood cost.

        #SOIT:    #0  1  (LABELS)
        ONEHOT = [[1. 0.]
                  [0  1.]]
        gradient_cost = logit - ONEHOT[action]
        >>> gradient_cost
        [[-0.222222 0.777777]]
        
        ##SOIT:
        gradient_cost = compute_LogLikelilhood_cost(
            logit, action, weights, regularization=0) ## soit ONEHOT ou LABELS ou y (predicted action)
        1.777777777777

        En fait, j'ai tous les équations, j'essaye simplement avec les exemples que j'ai. Les variances entre le softmax et sigmoid sont minimes.

        Je veux surtout comprendre quoi faire avec le softmax. Puisque certains exemple, il calcul par batch et d'autre non.

        Les exemples sur internet, utilisent différentes combinaisons. La plupart, calcul le forward deux fois.

        • Un forward avec l'observation.
        • Un forward dans le back-propagation, avec tout la batch d'observations. Il calcul le loss entre les deux forwards.

        Ce qui me mélange, c'est que dans certains exemple, les équations sont utlisé complètement ou, d'autre son coupé et utilisé dans la batch et le reste à l'ensemble de la batch.. (Ce que je croyais pas possible, malgré qu'en décortiquant l'équation, il y a probablement un moyen)

        Ce que vous dites, c'est que la seule différence, ce trouverait lors de la sortie du softmax. Lorsque je prend la prédiction, c'est là qu'il me manque quelque chose.. il faut simplement "rendre logique" les inputs. Donc, le onehot encoding?


        De plus, ils fonctionne tous, lorsqu'il y a maximum 50 neurones totales. Dépassé cela, ils prennent jusqu'à 1 heure par update. (Le seule qui fonctionne très bien, est celui avec Gym (le post précédent). C'est pour cela que j'essaye de comprendre au maximum son exemple, en décortiquant tout.)

        Sauf que, c'est bien le seule, qui fonctionne comme cela. (Dans l'exemple, c'est un jeu, mais pour moi, ce sera des datasets)

        Hônnement, comme je disais, je sais pas trop quoi je cherches. Je regarde tous les exemples softmax (il n'y en a pas gros. ce sont surtout les équations que je vois partout), et je print tous les résultats. J'essaye de comparez/trouvez ce que je comprends pas. Le pourquoi du pourquoi.

        J'ai utilisé tensorflow, pendant quelque mois, mais j'ai vite réalisé, que je comprennais rien de plus, que ce qu'il fallait que je donne en arguments.

        (Admettons, comment préparer les données, les targets, et sauvegarder le model..., appart cela, tout ce faisait tout seul. Suffisait de choisir quel type de classification ou type de NN. Je serais surpris de savoir le nombre de personne qui comprend le convolution (CNN), par rapport à ceux qui l'utilisent :D )

        Je me suis répété souvent, j'ai tellement hésitez avant d'écrire le premier post, j'aime pas ne pas comprendre, mais j'ai tellement lus et essayés d'équations, que là c'est trop..

        Même dans ce post, je crois que je me suis répété souvent. J'espère que vous allez comprendre. Sinon n'hésitez à raccourcir mes phrases.

        Bref, merci pour vos réponses. Je vais essayé d'avancer avec cela. (Surtout, avec le lien que vous m'avez donné, je vois que les équations ne sont pas identiques aux mienne.)

        Malgré que, vous semblez intéressés, sur ce sujet. Si vous voulez essayé l'exemple du post précédent, je pourrais vous envoyez un fichier weights , que j'ai entrainé pendant environs 3-5 mois 24/24. Il commençait à avoir un score égal à son adversaire (20-20) et une moyenne de -6. Il est 10.2Mo (fichier pickle .p )

        (J'ai arrêté, parce que cet ordinateur à rendu l'âme, disons que c'était un courageux et vaillant guerrier, haha. Disons, que c'est là que je comprends pourquoi les BATCH sont utilisés, si la mémoire était pleine à chaque fois, en le bourrant d'observations, cela n'a pas dû aider. Surtout, avec les algorithmes de path finding que j'ai essayé de combiner avec un réseau neuronal, en plus de l'afficher par tkinter)

        Merci beaucoup, encore une fois. Hakuna matata

        A+

        -
        Edité par nolimitech 17 septembre 2017 à 17:57:11

        • Partager sur Facebook
        • Partager sur Twitter
          18 septembre 2017 à 16:15:02

          nolimitech a écrit:

          Pour votre dernière réponse, non je connais pas cet exercices, si vous pouviez me donner le lien, ce serait très agréable, merci d'avance :)

          C'est l'exercice de ce cours : https://openclassrooms.com/courses/initiez-vous-au-machine-learning. Attention l'exercice est bien pour utiliser le OneHotEncoder mais pas pour le softmax car c'est une Regression que l'on veut faire et non une classification.

          nolimitech a écrit:

          Je trouve seulement, qu'il n'y à pas d'exemple softmax, qui fonctionne sur des NN de 1000 - 10,000 neurones.

           C'est assez rare des gros softmax sauf peut etre sur des programmes propriétaires dont tu ne verras pas le code. Cela s'explique car majoritairement ce sont des tutoriels ou il ne faut pas 10000 neuronnes car tout le monde n'a pas 2 GTX1080 Ti pour entrainer le network. Cependant si tu prend des modèle pré-trained comme le VGG19, tu as un softmax de taille 1000 pour detecter des objets dans des images

          https://gist.github.com/baraldilorenzo/8d096f48a1be4a2d660d

          Notament tu trouveras d'autant moins de modèle de grande taille code sur Numpy car la majorité préfère aller sur tensorflow/Keras pour profiter des perf du GPU...

          Sur la partie Softmax tu m'as un peu perdu :). Dans ton cas avec gym, tu fais du reinforced Learning du coup il ne faut pas back-propager à chaque tour, Il faut attendre d'avoir un set d'action, tu calcul le reward à chaque tour mais tu back-propage qu'après plusieurs run. Je ne suis pas très a l'aise avec le RL odnc je vais te citer une partie du livre que j'utilise pour apprendre:

          "

          First, let the NN policy play the game several times and at each step compute the gradients taht would make the chosen action even more likely, but don't apply these gradients yet.

          Once you have run several episodes, compute each action's score using the discounting reward function presented previously.

          [...]

          Finally, compute the mean of all the resulting gradient vectors and use it to perform a Gradient Step

          "

          nolimitech a écrit:

          En reprenant votre exemple, qu'es-ce que je fais avec le 150/360% de chance que ce soit 0 ou 1 ? Si c'est y - y_hat, je calcul le gradient à partir de quoi?

          De celui que j'aurais choisit ? Donc, le plus haut pourcentage? 

          Comment pick l'element dans un softmax, bonne question :) Tu peux surement en savoir plus en recherchant le fonctionnement de tf.nn.in_top_k(logits, y, 1). Ca renvoie une matrice de True/False selon si le resultat voulu est dans le top_k du softmax. Je ne pense pas qu'il y ait de random dedans. Apres je ne sais pas trop (je debute aussi ^^)

          nolimitech a écrit:

          Il faudrait donc, que le gradient soit qu'un float?

          Donc, soit je prends le logit et je trouve le gradient par y - y_hat, soit je calcul le loglikelilhood cost.

          #SOIT:    #0  1  (LABELS)
          ONEHOT = [[1. 0.]
                    [0  1.]]
          gradient_cost = logit - ONEHOT[action]
          >>> gradient_cost
          [[-0.222222 0.777777]]
          
          ##SOIT:
          gradient_cost = compute_LogLikelilhood_cost(
              logit, action, weights, regularization=0) ## soit ONEHOT ou LABELS ou y (predicted action)
          1.777777777777

          En fait, j'ai tous les équations, j'essaye simplement avec les exemples que j'ai. Les variances entre le softmax et sigmoid sont minimes.

          Je veux surtout comprendre quoi faire avec le softmax. Puisque certains exemple, il calcul par batch et d'autre non.

           Avec le softmax tu peux classifier tout ce qui a plus de 2 classes. Prend un exemple en utilisant MNIST ou il te faut un softmax de taille 10 (pour classifier les chiffres de 0 à 9). Le gradient doit avoir la dimension de la matrice que tu souhaites corriger dans ca peut etre un float ou une matrice nxm

          nolimitech a écrit:

          Les exemples sur internet, utilisent différentes combinaisons. La plupart, calcul le forward deux fois.

          • Un forward avec l'observation.
          • Un forward dans le back-propagation, avec tout la batch d'observations. Il calcul le loss entre les deux forwards.

          Ce qui me mélange, c'est que dans certains exemple, les équations sont utlisé complètement ou, d'autre son coupé et utilisé dans la batch et le reste à l'ensemble de la batch.. (Ce que je croyais pas possible, malgré qu'en décortiquant l'équation, il y a probablement un moyen)

           La, il y a peut etre quelque chose lié au Deep Q-Learning qui utilise un observateur (critic) et un acteur (actor). Dans ce cas tu as 2 modèle, l'observateur est corrigé à chaque run et parfois tu remplace le modèle de l'acteur par celui de l'observateur.

          nolimitech a écrit:

          Ce que vous dites, c'est que la seule différence, ce trouverait lors de la sortie du softmax. Lorsque je prend la prédiction, c'est là qu'il me manque quelque chose.. il faut simplement "rendre logique" les inputs. Donc, le onehot encoding?

          La tu as confonds OHE et Softmax. Un OHE est la pour modifier les données d'ENTREE uniquement. Son objectif est de pouvoir améliorer un modèle en docomposant des données "illogique" (cf l'explication sur les arrondissement). Le OHE te ressord une matrice de N_input * N_classes. Le softmax ressort un vecteur de N_output * 1. Du coup c'est plus light en mémoire. Si tu fait un OHE au lieu d'un softmax de taille N, tu vas avoir N² elements en mémoire au lieu de N.

          nolimitech a écrit:

          J'ai utilisé tensorflow, pendant quelque mois, mais j'ai vite réalisé, que je comprennais rien de plus, que ce qu'il fallait que je donne en arguments.

          (Admettons, comment préparer les données, les targets, et sauvegarder le model..., appart cela, tout ce faisait tout seul. Suffisait de choisir quel type de classification ou type de NN. Je serais surpris de savoir le nombre de personne qui comprend le convolution (CNN), par rapport à ceux qui l'utilisent :D )

          La je suis 100% d'accord avec toi. Mais j'ai laissé tombé l'affaire sur la backpropagation... Autant le forward, le principe du CNN, RNN, LSTM, DQN j'essaye de comprendre le focntionnement, autant la backpropagation j'ai abandonné (sauf sur le perceptron :) )^^

          Entraines-tu te modèle sur GPU ? car 3-5 mois 24/24 pour gym c'est juste qu'il y a qqch qui ne marche pas. J'ai juste testé sur le 1er exemple avec la pendule inversé et je commence a avoir des resultats correcte en une dizaine de minutes. Par contre il me faut 1h20 de training pour maitriser le puzzle. Meme l'IA qui a battu le Champion du monde sur Dota n'a eu que 24h de training (bon peut etre sur une machine ultra performante mais la complexité est bien plus grande). Sur gym, les plus long training devraient etre a 24h je pense.

          Coni

          • Partager sur Facebook
          • Partager sur Twitter
            20 septembre 2017 à 16:28:38

            Salut,

            Pour débuter, je tiens à dire que mon ordinateur de programmation n'avait pas de GPU (Il n'avait même pas de carte graphique). Il avait 2 cores, c'est tout, haha. De plus, j'avais 5 scripts qui fonctionnait en même temps. (3 scripts que j'avais fait moi-même à l'aide de pseudo-code wikipedia et 2 autres, que j'avais trouvé sur internet.) 

            Je regardais l'évolution des scripts à tous les jours, et j'ai pris les meilleurs rendements. :D (Il y avais trop d'hyper-paramètres, gamma, decay, learning_rate, theta, ... en plus des différences de calcul des coûts.)

            Effectivement, tous les autres jeux GYM, dont cartpole, ont des steps de 200, donc des parties d'environs 1 à 2 secondes chaque. Tandis que, pong-v0, est l'un des plus gros et plus long. (Une partie de 1300 steps, minimum, dont beaucoup plus d'observation, par batch(fin de partie)).

            D'ailleurs avec cart-pole, en moins de 2,500 epochs (5 minutes), il est 98.9% précis.

            En résumé, il y a une différence entre (cart-pole, pendule) et (pong-v0, doom)

            En fait, présentement, je fais mes testes sur mon ordinateur portable, j'ai remarqué que, numpy utilise 100% des cpus... ce que je savais pas. Je croyais qu'il fallait le faire manuellement. Numpy utlise les cpus, pour les multiplications matricielles et dans le script, il n'y a que cela :)

            Pour finir sur ce sujet, j'ai fait que suivre le tutoriel et copier le code. J'ai ajouté tous les formules (équations), que j'avais de wikipedia, mais j'ai rien modifié sur ce script. Donc, si c'est long, c'est pas ma faute :-°.

            Pour votre première réponse. Merci pour le lien. Cela m'a beaucoup aider.

            J'ai d'ailleurs trouvé deux nouveaux liens, que j'aurais dû avoir trouvé avant.

            Lien de McGill

            le deuxième Lien

            En plus de ce lien, qui fait un résumé, assez claire :)

            Un lien en anglais

            En fait, je crois avoir compris. Admettons que j'avais 6 ouputs et une batch de 33 épisodes. J'utilisais softmax, ensuite je sauvegardais tous les probabilités, que j'essayais de multiplier par le weights de l'input, dans le feedForward. Ce qui m'affichais une erreur. Puisque je me retrouvais avec tous les probabilitées sauvegardés, donc (6, 33), à la place de (1, 33), la plus haute probabilitée, choisit parmis les 6.

            Par la suite, il fallait trouver le loss gradient cost, donc je prennais tous les probabilitées et je soustraiyais selon l'action (fake_label), choisit.. Ce qui n'avais pas de bon sens. Au bout de deux updates, le AI bougais plus.

            Il fallait simplement que j'utilise le softmax, pour récuprer le maxarg, donc celui qui aura la plus grande probabilité. IL FAUT PAS PRENDRE TOUS LES PROBABILITÉS. Il faut, seulement gardé celui qu'on a choisit, donc la plus grande valeure..

            Ce qui rendais toute ma compréhension, complètement hors jeu.

            En résumé, quand j'avais une sortie, j'avais un gradient. Quand j'avais 6 sorties, j'avais 6 gradients. Donc, lors de la multiplication, c'étais impossible.

            Ensuite, l'autre test, pour le gradient (y - y_hat),  j'utilisais le onehot encoding pour soustraire le logit. Mais toujours, avec les 6 outputs. Donc, encore là j'avais 6x trop de données, pour multiplier avec l'input.

            Présentement, la seule chose qui me manque est: Quoi faire avec le onehot encoding?. il sert simplement, à convertir en binaire les outputs? Je ne calcul donc, rien avec ce onehot-line. Il me sert uniquement de référence, pour choisir le labels, selon la plus haut probabilité choisit par np.argmax().

            C'est ça qui me mélangait. 

            Le pire, c'est que plus je lis, sur le multi-outputs et la classification, plus je me rends compte que ce n'est même pas ce que je cherches. Je crois que je fais tout cela pour rien.

            MON OBJECTIF: Si un jeu, comme un FPS, on peut appuyer sur plein de touche en même temps. Je cherches pas à obtenir la probabilité qu'une touche soit appuyé, mais TOUS LES TOUCHES, qui pourrait être appuyé en même temps.

            Admettons, avancer et tirer, tourner et se baisser (crounch).

            AUTRE EXEMPLE: Vous avez des bactéries, qui voyage selon l'hôte. Comment retourner, tous les bactéries qui se propageront par le rat. Je cherches pas une bactéries, mais plusieurs. (Selon des Datasets)

            Je crois que je me suis tellement mélangé, entre les méthodes. C'est même pour cela que je voulais multiplier le hidden * output, dans le weights du input. Histoire, dans tous les probabilitées, pas uniquement le plus haut.

            La classification, me donne un seul résultat. La probabilité que la touche 'avancer' soit appuyer, ou la touche 'tirer', comme MNIST. Pas les deux en même temps.

            C'est pour cela que, que je comprennais rien. J'essayais d'avoir plusieurs résultat en même temps. Donc, je donnais tout en output.

            Je sais qu'un ordinateur peut faire une touche tellement rapidement, que c'est comme s'il appuyait sur plusieurs touches, mais le principe, que je cherchais n'est pas cela.

            Merci beaucoup, pour votre patience et surtout Merci, pour vos explications.

            Présentement, j'essaye de comparez mes scripts, avec tensorflow et j'essaye vos liens, mais sans tensorflow.

            Merci encore.


            A+

            NLT

            -
            Edité par nolimitech 20 septembre 2017 à 16:33:25

            • Partager sur Facebook
            • Partager sur Twitter
              25 septembre 2017 à 5:08:29

              Salut,

              Merci beaucoup pour votre aide. Je viens de comparez avec tensorflow. La seule erreur, que je faisais, était après le feedForward. J'entrait tout le onehot encoding, et non pas juste l'action prise.

              De plus, je sais pas si c'est bon, mais avec tensorflow, tous les opérations, j'ai faisais en GPU. Ensuite, j'ai créé des threads (entre 3 et 5) pour feeder le X (observation). Puisque, le plus long étais d'attendre la fin d'une partie. 

              Bon ok.. mon load average étais supérieur a 5.0. J'ai donc, tout arrêté, haha :S

              Merci encore

              A+

              • Partager sur Facebook
              • Partager sur Twitter
                25 septembre 2017 à 17:00:18

                Bonjour,

                nolimitech a écrit:

                La seule erreur, que je faisais, était après le feedForward. J'entrait tout le onehot encoding, et non pas juste l'action prise.

                Lorsque vous parlez du OHE, c'est bien le softmax ? Dans ce cas en effet il faut sélectionner par rapport aux poids du softmax une action (pas obligatoirement la meilleure car on veut aussi tester des chemins non explorés), et faire la backpropagation uniquement sur cette valeur (sinon il n'y a rien à corriger car la target = le resultat donc l'erreur vaut 0, non ?). 

                On peut lancer plusieurs script tensorflow sur le GPU avec le threading? :o Je sais que tensorflow parallélise au mieux le travail mais de la à envoyer au GPU plusieurs tâches de graphe différents je ne savais pas :D

                En tout cas good news si ca marche et bonne continuation !

                • Partager sur Facebook
                • Partager sur Twitter
                  26 septembre 2017 à 18:30:28

                  Salut,

                  Oui OHE, c'est le softmax. C'est ça que je comprenais pas. Quoi faire avec ce softmax, une fois reçu..

                  J'utilisais tout les actions encoded, pas juste celui qui sera choisit :)

                  J'utilise le GPU pour le graph, uniquement.

                  J'ai utilisé les threads, pour feeder uniquement le X (l'observation). Je ne mélange pas les tâches.

                  En fait, je crée une batch (une partie complète de Pong-v0) par thread, que j'envoie dans une queue (à la fin).

                  Ensuite, dans la boucle FOR d'epochs, il récupère une batch, par cette queue.. et continue l'epoch..

                  Ex, très grosso-modo, et presque pseudo-code...:

                  queue = queue.Queue()
                  
                  def creer_batch(predicted_tensorflow_function):
                      env = gym.make('Pong-v0')
                      observations, rewards, encoded_actions = [], [], []
                      while True:
                          action = predicted_tensorflow_function(observation)
                          encoded_action = onehot_encoding(action)
                          observation, reward, done, info = env.step(action)
                          
                          observations.append(observation)
                          rewards.append(rewards)
                          encoded_actions.append(encoded_action)
                  
                          if done:
                              queue.put([observations, rewards, encoded_actions])
                              observations, rewards, encoded_actions = [], [], []
                  
                  def feedforward(X):
                      z2 = tf.matmul(X + W1)
                      a2 = tf.nn.relu(z2)
                      z3 = tf.matmul(a2 + W2)
                      return tf.nn.softmax(z3)
                  
                  
                  init = tf.global_variable_initializer()
                  with tf.Session as session:
                      session.run(init)
                  
                      ## UN THREAD:
                      thread = threading.Thread(target=creer_batch,
                                                args=(feedforward,))
                      thread.start()
                  
                      ## EPOCHES:
                      epoch = 0
                      while True: # for epoch in range(1000)
                          try:
                              batch = queue.get()
                          except queue.Empty:
                              pass
                          else:
                              ....
                  
                              epoch += 1



                  En fait, mon vrai code est en POO, tout est par classe. (Donc, ici c'est uniquement pour montrer)

                  Je sais pas si c'est bon. Hônnement, j'aime pas trop le faire, c'étais pour des testes. Comme vous dites, tensorflow parallélise tout, donc je sais pas si c'est correct...

                  J'ai pas de GIL (de RLock), au cas où..

                  Comme je disais mon loading average monte plus haut 5.0.. (uptime), quand je met 5 threads...

                  Donc, présentement je mets que 3 threads MAXIMUMs.

                  Je fais vraiment n'importe quoi :)

                  Merci encore, pour votre aide. Vous m'avez beaucoup aidé

                  A+

                  NLT

                  -
                  Edité par nolimitech 26 septembre 2017 à 18:36:36

                  • Partager sur Facebook
                  • Partager sur Twitter
                    26 septembre 2017 à 21:26:57

                    Pas de soucis :) Merci aussi pour vos retour aussi productifs !

                    Si vous voulez je vous enverrais par MP le seul algo que j'ai de vraiment fonctionnel sur gym, peut être que ca vous donnera d'autres idées :) Mais je n'ai pas encore trop creusé le Reinforced Learning car j'ai du mal a bien saisir (du moins avec gym) comment entraîner un modèle pour avoir le meilleur tuple (state, actions) alors que par exemple pour l'exercice avec le MountainCar-v0, on n'a pas de reward jusqu'a atteindre le haut. Hors dans mon cas, même apres 100 epoch et 10 try par epoch, je n'arrive jamais en haut avec du random donc impossible de monter la policy de l'IA... Bref c'est encore sombre pour moi tout ca ^^ Je comprends le principe mais j'ai du mal a le mettre en oeuvre

                    • Partager sur Facebook
                    • Partager sur Twitter

                    NeuralNetwork remplacer sigmoid par softmax

                    × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                    × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                    • Editeur
                    • Markdown