Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

  1. #1
    Futur Membre du Club
    Besoin d'aide pour finire ou même commencer (Si j'ai fait n'importe quoi) mon IA [Python]
    Bonjour,
    J'ai essayer de coder une IA a apprentissage par renforcement qui apprend a jouer au morpion elle s'appelle Amna (Car Amna = A.Mna. (En Xhosa) = AI (En Anglais) = IA (En francais) OUI je suis parti loin), pas si compliquer dans l'idée, mais comme c'est la première IA par renforcement que je code, j'ai surement fait un peut n'importe quoi...
    J'ai coder assez clairement, j'ai mis des commentaires partout, c'est pas si dure a comprendre ce que j'ai fait.
    Donc le problème c'est que mon IA est pas très I, même au bout de 100 000 partie, ce qui me parait très bizarre pour apprendre le morpion...
    Donc j'ai surement fait des erreurs de logiques...
    Il y a surement des erreur dans :
    - Ma façon de récompenser
    - Si c'est pas dans ma façon de récompenser c'est dans ma BackPropagation
    - Si c'est pas dans la BackPropagation c'est dans la façon dont l'IA fait ses choix (Elle les fait par rapport a ce que l'adversaire viens de jouer et pas par rapport a ce qu'il a jouer au long de la partie)
    - C'est peut être dans tout a la fois...
    - Et elle a un bug que je ne comprend pas, le plateau ce rempli dans des moment ou il ne devrai pas être remplis

    Donc c'est surement n'importe quoi mon code mais le voici pour m'aider a le corriger et pour que j’apprenne de mes erreurs :
    Code Python :Sélectionner tout -Visualiser dans une fenêtre à part
    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
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    ###############################################################################
    # Amna
    ###############################################################################
     
    """
    N = Niveau (Répondre à N) (De l'état N à ...)
    xp = Experience (Data / Données / Cerveau)
    P = player (La personne qui jou en ce momant)
     
    """
     
    ### INI ###
    terrain = list([0,0,0,0,0,0,0,0,0]) #Map morpion
    # Experience / Cerveau
    xp = list([])
    for a in range(10):
        xp.append([])
        for b in range(9):
            xp[a].append([(b+1),0])
     
    """
    Map morpion :
    |1|2|3|
    |4|5|6|
    |7|8|9|
     
    Plan de la base de donnée de l'IA / Cerveau :
    [
    Si le joueur adverse choisi 0 (Tu jou en premier) : [[1, 0], [2, 0], [3, 0], [4, 0], [5, 0], [6, 0], [7, 0], [8, 0], [9, 0]],
    Si le joueur adverse choisi 1 : [[(Alors jouer 1)>1, (Niveau d'envie de jouer 1)>0], [(Alors jouer 2)>2, (Niveau d'envie de jouer 2)>0], [3, 0], [4, 0], [5, 0], [6, 0], [7, 0], [8, 0], [9, 0]],
    Si le joueur adverse choisi 2 : [[1, 0], [2, 0], [3, 0], [4, 0], [5, 0], [6, 0], [7, 0], [8, 0], [9, 0]],
    [[1, 0], [2, 0], [3, 0], [4, 0], [5, 0], [6, 0], [7, 0], [8, 0], [9, 0]],
    [[1, 0], [2, 0], [3, 0], [4, 0], [5, 0], [6, 0], [7, 0], [8, 0], [9, 0]],
    [[1, 0], [2, 0], [3, 0], [4, 0], [5, 0], [6, 0], [7, 0], [8, 0], [9, 0]],
    [[1, 0], [2, 0], [3, 0], [4, 0], [5, 0], [6, 0], [7, 0], [8, 0], [9, 0]],
    [[1, 0], [2, 0], [3, 0], [4, 0], [5, 0], [6, 0], [7, 0], [8, 0], [9, 0]],
    [[1, 0], [2, 0], [3, 0], [4, 0], [5, 0], [6, 0], [7, 0], [8, 0], [9, 0]],
    [[1, 0], [2, 0], [3, 0], [4, 0], [5, 0], [6, 0], [7, 0], [8, 0], [9, 0]]
    ]
    """
    ### IMP ###
    import random
    import os #Pour la commande cls de system pour clear l'affichage pour le chargement
     
    ### DEF ###
    def choisir(N):
        randomlist = list([]) #Liste pour tout les choix qui ont la même valleurs qu'il faudra départager grance a l'aleatoire
        best = list([0,0])
        choix = xp[N].copy() #Copie de la base de donnée pour ne pas la modifier
        for i in range(9): # Tri des choix possible
            if terrain[8-i] == 1 or terrain[8-i] == 2:
                choix.remove(choix[8-i]) #Suppretion des choix impossible
        # Recherche du meilleur choix
        for i in range(len(choix)):
            if choix[i][1] > best[1]:
                best = choix[i]
                randomlist = list([])
            if choix[i][1] == best[1]:
                randomlist.append(choix[i])
        # Si il y a confrontation alors place au random
        if len(randomlist) > 0:
            best = randomlist[random.randint(0,(len(randomlist)-1))]
        # Return le nom de la case (entre 1 et 9)
        return best[0]
     
    def choisirALL(): #Pour choisir premier tour
        most = list([])
        for N in range(10):
            randomlist = list([])
            best = list([0,0])
            choix = xp[N].copy()
            for i in range(9): # Tri des choix possible
                if terrain[8-i] == 1 or terrain[8-i] == 2:
                    choix.remove(choix[8-i])
            # Recherche du meilleur choix
            for i in range(len(choix)):
                if choix[i][1] > best[1]:
                    best = choix[i]
                    randomlist = list([])
                if choix[i][1] == best[1]:
                    randomlist.append(choix[i])
            # Si il y a confrontation alors place au random
            if len(randomlist) > 0:
                best = randomlist[random.randint(0,(len(randomlist)-1))]
            # Ajoute a la liste des meilleur
            most.append(best)
        choix = most
        for i in range(len(choix)):
            if choix[i][1] > best[1]:
                best = choix[i]
                randomlist = list([])
            if choix[i][1] == best[1]:
                randomlist.append(choix[i])
        # Si il y a confrontation alors place au random
        if len(randomlist) > 0:
            best = randomlist[random.randint(0,(len(randomlist)-1))]
        # Return le nom de la case (entre 1 et 9)
        return best[0]
     
     
    def Gagner():
        global terrain
        if ((terrain[0]==1 and terrain[1]==1 and terrain[2]==1) or
            (terrain[0]==1 and terrain[4]==1 and terrain[8]==1) or
            (terrain[0]==1 and terrain[3]==1 and terrain[6]==1) or
            (terrain[1]==1 and terrain[4]==1 and terrain[7]==1) or
            (terrain[2]==1 and terrain[5]==1 and terrain[8]==1) or
            (terrain[2]==1 and terrain[4]==1 and terrain[6]==1) or
            (terrain[3]==1 and terrain[4]==1 and terrain[5]==1) or
            (terrain[6]==1 and terrain[7]==1 and terrain[8]==1)):
            return True
        elif ((terrain[0]==2 and terrain[1]==2 and terrain[2]==2) or
             (terrain[0]==2 and terrain[4]==2 and terrain[8]==2) or
             (terrain[0]==2 and terrain[3]==2 and terrain[6]==2) or
             (terrain[1]==2 and terrain[4]==2 and terrain[7]==2) or
             (terrain[2]==2 and terrain[5]==2 and terrain[8]==2) or
             (terrain[2]==2 and terrain[4]==2 and terrain[6]==2) or
             (terrain[3]==2 and terrain[4]==2 and terrain[5]==2) or
             (terrain[6]==2 and terrain[7]==2 and terrain[8]==2)):
             return True
        else:
            return False
    #############
    # Algorytme #
    #####################################
     
    learningRate = 0.01 #Learning rate pété
    long = 1000000 #Nombre de partie d'apprentissage
    barre = list([]) #Barre de chargement
     
    for app in range(long):
        if (app/long)*100 == int((app/long)*100):
            os.system("cls")
            barre.append("|")
            print("Apprentisage :",int((app/long)*100),"% /",app,"parties jouées")
            print("---------------------------------------------------------------------------------------------") #Top la classe XD
            print(''.join(barre))
            print("---------------------------------------------------------------------------------------------")
            print("")
            print("Learning rate :", learningRate)
            print("")
            print(terrain[0],terrain[1],terrain[2])
            print(terrain[3],terrain[4],terrain[5])
            print(terrain[6],terrain[7],terrain[8])
            print("")
            for i in range(9): #Montre les données
                print(xp[i])
        """
        #Fonction d'avencement du learning rate durant la partie
        if learningRate < 1:
            learningRate += learningRate/(100000)
        elif learningRate > 1:
            learningRate = 1
        """
        historique = list([]) #Historique de la partie pour la backpropagation
        terrain = list([0,0,0,0,0,0,0,0,0]) #Nettoyage du terrain
        P = 1 #Joueur 1 commence
        ### Démarage de la partie ###
        for i in range(10):
            if sum(terrain) > 12: #Anti bug du terrain remplis
                """
                print("BUG : Terrain rempli (Non resolu)")
                print(terrain[0],terrain[1],terrain[2])
                print(terrain[3],terrain[4],terrain[5])
                print(terrain[6],terrain[7],terrain[8])
                """
                break
            if random.random() > learningRate: #Esay de faire quelque chose avec le learning rate
                choix = xp[0].copy()
                for i in range(9): # Tri des choix possible
                    if terrain[8-i] == 1 or terrain[8-i] == 2:
                        choix.remove(choix[8-i])
                choix = choix[random.randint(0,(len(choix)-1))][0] #Choix aléatoire pour cartographier le jeu
            else:
                if len(historique) > 0: #Savoir si on jou en premier ou pas
                    choix = choisir(historique[-1])
                else:
                    choix = choisirALL()
            historique.append(choix) #Sauvegarde dans l'historique
            if P == 1: #Switch entre joueur 1 et 2
                terrain[choix-1] = 1
            elif P == -1:
                terrain[choix-1] = 2
            P *= -1
            # System de reward surement foireux
            if Gagner():
                xp[historique[-2]-1][historique[-1]-1][1] = xp[historique[-2]-1][historique[-1]-1][1]+learningRate*(5)
                xp[historique[-3]-1][historique[-2]-1][1] = xp[historique[-3]-1][historique[-2]-1][1]+learningRate*(-5)
                xp[historique[-4]-1][historique[-3]-1][1] = xp[historique[-4]-1][historique[-3]-1][1]+learningRate*(xp[historique[-2]-1][historique[-1]-1][1]-xp[historique[-4]-1][historique[-3]-1][1])
                xp[historique[-5]-1][historique[-4]-1][1] = xp[historique[-5]-1][historique[-4]-1][1]+learningRate*(xp[historique[-3]-1][historique[-2]-1][1]-xp[historique[-5]-1][historique[-4]-1][1])
                if not len(historique) > 5: break
                xp[historique[-6]-1][historique[-5]-1][1] = xp[historique[-6]-1][historique[-5]-1][1]+learningRate*(xp[historique[-4]-1][historique[-3]-1][1]-xp[historique[-6]-1][historique[-5]-1][1])
                if not len(historique) > 6: break
                xp[historique[-7]-1][historique[-6]-1][1] = xp[historique[-7]-1][historique[-6]-1][1]+learningRate*(xp[historique[-5]-1][historique[-4]-1][1]-xp[historique[-7]-1][historique[-6]-1][1])
                if not len(historique) > 7: break
                xp[historique[-8]-1][historique[-7]-1][1] = xp[historique[-8]-1][historique[-7]-1][1]+learningRate*(xp[historique[-6]-1][historique[-5]-1][1]-xp[historique[-8]-1][historique[-7]-1][1])
                if not len(historique) > 8: break
                xp[historique[-9]-1][historique[-8]-1][1] = xp[historique[-9]-1][historique[-8]-1][1]+learningRate*(xp[historique[-7]-1][historique[-6]-1][1]-xp[historique[-9]-1][historique[-8]-1][1])
                if not len(historique) > 9: break
                xp[historique[-10]-1][historique[-9]-1][1] = xp[historique[-10]-1][historique[-9]-1][1]+learningRate*(xp[historique[-8]-1][historique[-7]-1][1]-xp[historique[-10]-1][historique[-9]-1][1])
                break
            if i == 9: #Egalité
                xp[historique[-2]-1][historique[-1]-1][1] += learningRate*(0)
                xp[historique[-3]-1][historique[-2]-1][1] += learningRate*(0)
                xp[historique[-4]-1][historique[-3]-1][1] = xp[historique[-4]-1][historique[-3]-1][1]+learningRate*(xp[historique[-2]-1][historique[-1]-1][1]-xp[historique[-4]-1][historique[-3]-1][1])
                xp[historique[-5]-1][historique[-4]-1][1] = xp[historique[-5]-1][historique[-4]-1][1]+learningRate*(xp[historique[-3]-1][historique[-2]-1][1]-xp[historique[-5]-1][historique[-4]-1][1])
                xp[historique[-6]-1][historique[-5]-1][1] = xp[historique[-6]-1][historique[-5]-1][1]+learningRate*(xp[historique[-4]-1][historique[-3]-1][1]-xp[historique[-6]-1][historique[-5]-1][1])
                xp[historique[-7]-1][historique[-6]-1][1] = xp[historique[-7]-1][historique[-6]-1][1]+learningRate*(xp[historique[-5]-1][historique[-4]-1][1]-xp[historique[-7]-1][historique[-6]-1][1])
                xp[historique[-8]-1][historique[-7]-1][1] = xp[historique[-8]-1][historique[-7]-1][1]+learningRate*(xp[historique[-6]-1][historique[-5]-1][1]-xp[historique[-8]-1][historique[-7]-1][1])
                xp[historique[-9]-1][historique[-8]-1][1] = xp[historique[-9]-1][historique[-8]-1][1]+learningRate*(xp[historique[-7]-1][historique[-6]-1][1]-xp[historique[-9]-1][historique[-8]-1][1])
                xp[historique[-10]-1][historique[-9]-1][1] = xp[historique[-10]-1][historique[-9]-1][1]+learningRate*(xp[historique[-8]-1][historique[-7]-1][1]-xp[historique[-10]-1][historique[-9]-1][1])
                break
    print("")
    print("A vous de jouer")
    print("")
    print("0 1 2")
    print("3 4 5")
    print("6 7 8")
    print("")
    while True:
        terrain = list([0,0,0,0,0,0,0,0,0])
        for i in range(9):
            print("Etat du jeu :")
            print(terrain[0],terrain[1],terrain[2])
            print(terrain[3],terrain[4],terrain[5])
            print(terrain[6],terrain[7],terrain[8])
            print("")
            ch = int(input("Choix : "))
            terrain[ch] = 1
            if Gagner():
                print("Vous avez gagner :")
                print(terrain[0],terrain[1],terrain[2])
                print(terrain[3],terrain[4],terrain[5])
                print(terrain[6],terrain[7],terrain[8])
                break
            terrain[choisir(ch)-1] = 2
            if Gagner():
                print("Vous avez perdu :")
                print(terrain[0],terrain[1],terrain[2])
                print(terrain[3],terrain[4],terrain[5])
                print(terrain[6],terrain[7],terrain[8])
                break
            print("")
        print("-------------------------")

    Il y a surement des fautes de français partout, je m'en excuse

    Si vous ne comprenez pas quelque lignes, dite le moi je vous expliquerais, si vous ne comprenez rien manger votre chapeau (Attention l’abus de chapeau est dangereux pour la santé)

    Merci de votre aide

  2. #2
    Membre expert
    Citation Envoyé par Personne3443 Voir le message

    Il y a surement des fautes de français partout
    Je ne connais rien au python, mais, ça, je confirme
    Il vaut mieux viser la perfection et la manquer que viser l'imperfection et l'atteindre. - Bertrand Russell

  3. #3
    Responsable Qt & Livres



    Les algorithmes d'apprentissage par renforcement sont notoirement difficiles à bien faire fonctionner, même pour les experts du domaine…

    Tu mets un gros paquet de code, mais peu de détails de haut niveau sur ce que tu fais, difficile de te donner un avis rapidement (par exemple, sur ta manière de déterminer les récompenses).

    Je suis tombé sur random.random() > learningRate, une ligne qui me paraît assez douteuse. Surtout que tu sembles considérer un taux d'apprentissage qui peut dépasser 1 (je n'ai pas souvent vu ça, c'est une valeur souvent très haute…) : dans ce cas, le test aléatoire échouera toujours. Que cherches-tu à faire, ici ?

    Tu fais un jeu à deux joueurs, un seul des deux étant contrôlé par ton algo. Or, si j'ai bien compris ton code, tu mets à jour tes poids pour chaque action, peu importe le joueur : idéalement, tu considères que le deuxième joueur n'existe pas vraiment, il est plutôt inclus dans les transitions d'état que tu vois à la suite de tes actions.
    Vous souhaitez participer aux rubriques Qt ou PyQt (tutoriels, FAQ, traductions), 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 !

  4. #4
    Futur Membre du Club
    Bonjour et merci de votre réponse,

    Citation Envoyé par dourouc05 Voir le message

    Je suis tombé sur random.random() > learningRate, une ligne qui me paraît assez douteuse. Surtout que tu sembles considérer un taux d'apprentissage qui peut dépasser 1 (je n'ai pas souvent vu ça, c'est une valeur souvent très haute…) : dans ce cas, le test aléatoire échouera toujours. Que cherches-tu à faire, ici ?
    Oui c'est très très douteux, en fait si je met pas ça l'IA joue que ce qu'elle a trouver bien au premier tour, et se bloque dans une boucle infinie, car pour contrer ça l'autre partie de son cerveau qui joue contre elle fluctue entre ses deux réponses préféré qui sont mauvaises (Enfin déjà ça c'est pas normal ). En fait je veut que l'IA joue complétement aléatoirement pour noter toutes les possibilités qu'elle croise et ce construire un plan de jeu. En fait ce que j'ai pas fait et ce que je doit faire a la place de ça c'est que si le choix sont jouer en [1,5] [2,-1] [3,1] [4,-2] [5,0] [6,3] [7,2] [8,4] [9,-1] avec
    [Numéro de la case,Envie de l'IA] il faut que l'IA choisisse aléatoirement mais pas tout a fait :
    Pour toutes les valeurs d'envie ajouter 5 (Pour qu'il n'y ais aucun nombre en dessous de 0, car normalement avent le nombre min été -5 et max 5 (Même si c'était pas vraiment le cas car j'ai mal fait mon truc)) (Donc le minimum est maintenant 0 et le max est 10)
    LearningRate = 1
    S = somme de toutes les envies (Min 0 Max 10) = 10+4+6+3+5+8+7+9+4 = 56
    Probabilité de choisir la solution :
    1 => 10/S*100/(10/LearningRate) = 17.8571428571 %
    2 => 4/S*100/(4/LearningRate) = 7.14285714286 %
    3 => 6/S*100/(6/LearningRate) = 10.7142857143 %
    4 => 3/S*100/(3/LearningRate) = 5.35714285714 %
    5 => 5/S*100/(5/LearningRate) = 8.92857142857 %
    6 => 8/S*100/(8/LearningRate) = 14.2857142857%
    7 => 7/S*100/(7/LearningRate) = 12.5 %
    8 => 9/S*100/(9/LearningRate) = 16.0714285714 %
    9 => 4/S*100/(4/LearningRate) = 7.14285714286 %

    Voila ce serait plutôt ça que j’aurais envi de faire, du coup maintenant je sait a peut près comment le faire ^^

    Mais mon système de reward est toujours pourri...

    Citation Envoyé par dourouc05 Voir le message

    Tu fais un jeu à deux joueurs, un seul des deux étant contrôlé par ton algo. Or, si j'ai bien compris ton code, tu mets à jour tes poids pour chaque action, peu importe le joueur : idéalement, tu considères que le deuxième joueur n'existe pas vraiment, il est plutôt inclus dans les transitions d'état que tu vois à la suite de tes actions.
    En réfléchissant sur la question, j'ai eu un bug car oui, c'est vrais mais c'est a cause de moi qui me suis embrouiller quand je l'ai coder . Mon but été de dire a l'IA ce que l'autre vient de jouer mais j'ai perdu le fil et je me suis mit a coder comme si l'info qu'on donner a l'IA c'était quel était l'étape de la partie (Tour 1, 2 ...)
    En fait j'ai trop d'erreur a cause de ça, je pence que je vais la recommencer a 0, ce sera mieux...

    Le truc que j'arrive pas a bien faire c'est la BackPropagation, si vous avez une idée dite le moi

    Merci pour votre réponse, je vous tiendrais au courent de l’avancement de ce projet ici si vous le voulez

###raw>template_hook.ano_emploi###