Partage
  • Partager sur Facebook
  • Partager sur Twitter

IA : réseau de neurones

Reconnaissance de chiffres sur grille 7 segments

Sujet résolu
    31 janvier 2023 à 14:14:23

    Bonjour,

    m'intéressant à l'IA, j'ai développé un petit programme de reconnaissance de formes avec un

    réseau de neurones sous tkinter

    Il affiche la fameuse grille de 7 segments, il sont vides au départ, on initialise un chiffre en piquant

    les segments concernés et le programme répond "c'est un trois", par exemple

    Pour plus de commodité, j'ai fait 2 programmes: l'un attaque un fichier texte contenant les

    10 chiffres de 0 à 9 sous forme de listes de 0 et de 1 et une boucle d'apprentissage calcule les

    poids des entrées des neurones, et les sauvegarde dans un fichier pickle, l'autre affiche

    l'interface après avoir lu le fichier pickle, prêt à répondre aux questions

    Mon problème est que la phase d'apprentissage ne fonctionne que pour les chiffres de 0 à 7, avec

    la suite de 0 à 9 elle tombe dans une boucle infinie

    Je cherche en vain depuis un moment, je me demandais donc si quelqu'un pourrait se pencher

    là-dessus (c'est la technique de l'œil neuf, moi, j'ai trop examiné et ré examiné le code)

    Je veux bien afficher mon code, mais les 2 fichiers font respectivement 120 et 150 lignes,

    sans compter le fichier texte de données

    Donc, déjà, comment peut-on faire ?

    -
    Edité par Phil_1857 31 janvier 2023 à 14:23:09

    • Partager sur Facebook
    • Partager sur Twitter
      31 janvier 2023 à 16:36:09

      ça parait énorme (le fichier de données lui ne doit pas être gros, 10 lignes avec les valeurs des 7 segments, c'est l'ordre des segments qu'il nous faut aussi, si tu écris du a au g ou du g au a ou autre ordre)

      après le code, tu peux le mettre sur un pastebin ou équivalent et partager le lien.

      • Partager sur Facebook
      • Partager sur Twitter
        31 janvier 2023 à 17:23:37

        Après tout, il me suffit d'afficher le programme d'apprentissage uniquement:

        # -*- coding:Latin-1 -*-
        # Apprentissage pour reconnaitre des nombres de 0 à 9 sur le canevas des 7 leds
        # 10 neurones, chacun connecté aux 7 segments
        #    _7_
        # 2 |   | 3
        #   |_6_|
        # 1 |   | 4
        #   |_ _|
        #     5 
        
        import os
        import random
        import pickle
        
        def w_init():
        	''' Initialisation des poids '''
        
        	for neuron in range (neurons_nb):
        		for segment in range (segments_nb):
        			weights[neuron][segment] = random.randint(-10.0,10.0)
        
        def get_output(num, neuron):
        	''' Calcule la somme de la grille "num" avec le neurone "neuron"
        	si sum > 0, la sortie est correcte, la grille est econnue par le neurone '''
        
        	e_sum = 0
        
        	for segment in range(segments_nb):
        		e_sum += leds[num][segment]*weights[neuron][segment]
        
        	if(e_sum > threshold):
        		return(1)
        	else:
        		return(0)
        
        def learning_phase(num, neuron):
        	''' Calcule la sortie du neurone et ajuste les poids des entrées '''
        
        	output = get_output(num,neuron)
        	expected_output = (num==neuron)
        	delta = expected_output - output
        
        	for segment in range(segments_nb):
        		weights[neuron][segment] += leds[num][segment] * delta * learning_pitch
        
        
        #Lecture des chiffres
        #Ceci fonctionne:
        #filename = 'chiffres_0_7.txt'
        #Ceci ne fonctionne pas:
        filename = 'chiffres_0_9.txt'
        
        ofi = open(filename, 'r')
        block = ofi.read()
        ofi.close()
        
        sep = block.find('*')
        leds = eval(block[:sep-1])
        data_type = block[sep+2:]
        
        leds_nb = len(leds)
        segments_nb = len(leds[0])
        neurons_nb = leds_nb
        
        threshold = 0
        learning_pitch = 10.0
        data_file = 'neurons_data.dat'
        
        #Lien entre no de neurone et chiffre
        match_data = {}
        for k in range(neurons_nb):
        	match_data[k] = eval(data_type)
        
        #Les poids
        weights = [[0 for j in range(0,segments_nb)] for i in range(0,neurons_nb)]
        
        #Initialisation des poids
        w_init()
        
        #Boucle d'apprentissage
        loop = 0
        while(True):
        	os.system('cls')
        	print('Apprentissage ...')
        
        	#Lorsque l'affichage présente la matrice identité, l'apprentissage est fini
        	total=0
        	diagonal=0
        	for neuron in range(neurons_nb):
        		for n in range (leds_nb):
        			output = get_output(n, neuron)
        			print(output, end = ' ')
        			total += output
        			if(n == neuron): diagonal += output
        		print('\n')
        
        	if(diagonal == neurons_nb and total == neurons_nb): break
        
        	#Liaison des poids avec les grilles
        	for neuron in range(neurons_nb):
        		for n in range (leds_nb):
        			learning_phase(n,neuron)
        			loop += 1
        
        print('Apprentissage réalisé en {:d} pas'.format(loop))
        
        #Enregistrement des poids
        wl = []
        for neuron in range(neurons_nb):
        	wl.append(weights[neuron])
        
        with open(data_file, 'wb') as fo:
        	pickle.dump(neurons_nb, fo)
        	pickle.dump(match_data, fo)
        	pickle.dump(wl, fo)
        
        print('Création du fichier {}'.format(data_file))
        
        input('Entrée ...')
        

        Et le fichier de données chiffres_0_9.txt :

        [
        [
        1,1,1,1,1,0,1
        ]
        ,
        [
        0,0,1,1,0,0,0
        ]
        ,
        [
        1,0,1,0,1,1,1
        ]
        ,
        [
        0,0,1,1,1,1,1
        ]
        ,
        [
        0,1,0,1,0,1,0
        ]
        ,
        [
        0,1,0,1,1,1,1
        ]
        ,
        [
        1,1,0,1,1,1,1
        ]
        ,
        [
        0,0,1,1,0,0,1
        ]
        ,
        [
        1,1,1,1,1,1,1
        ]
        ,
        [
        0,1,1,1,1,1,1
        ]
        ]
        *
        k




        -
        Edité par Phil_1857 31 janvier 2023 à 17:27:55

        • Partager sur Facebook
        • Partager sur Twitter
          1 février 2023 à 14:11:50

          En débuguant, on voit que le 9ème neurone bascule entre 2 états de ses poids d'indice 1 et 4 

          (par exemple [27.0, -4.0, -5.0, -6.0, -18.0, 13.0, -2.0] et [27.0, 6.0, -5.0, 4.0, -18.0, 13.0, -2.0] )

          d'où la boucle infinie résultante.

          Reste à trouver le pourquoi .... 

          • Partager sur Facebook
          • Partager sur Twitter
            1 février 2023 à 14:36:43

            C'est bien ça, à l'affichage, on voit que ces 2 valeurs oscillent en permanence alors que les autres affichent bien un 1 sur la diagonale

            Avec 7 chiffres ca donne ceci:

            Reste à savoir pourquoi, pas facile car il faudrait suivre l'évolution des poids à chaque étape ...

            • Partager sur Facebook
            • Partager sur Twitter
              1 février 2023 à 15:22:41

              j'ai modifié le code ainsi pour voir pourquoi ça bloquait

              ...
                  #Liaison des poids avec les grilles
                  old_weights=copy.deepcopy(weights)
                  for neuron in range(neurons_nb):
                      for n in range (leds_nb):
                          learning_phase(n,neuron)
                          loop += 1
                  
                  print([x for x in weights if x not in old_weights])
                  #if old_weights==weights: break
                  if loop > 3000 : break
              ...

              Le problème vient je pense au niveau du calcul des poids, ou de get_output

              on voit aussi que l'écart est dans le même sens pour les 2 (et la somme des 2 vaut 2*learning_pitch)

              • Partager sur Facebook
              • Partager sur Twitter
                1 février 2023 à 16:53:34

                De mon coté, j'ai tenté une expérience au hasard:

                le seul chiffre qui ne se stabilise pas dans la matrice affichée, c'est le 8

                et c'est la seule liste du fichier texte ayant une série de 1 (pas de zéro)

                J'ai donc mis l'un des chiffres à 0, bah pourquoi pas, et bingo: l'apprentissage se termine:

                Evidemment, le chiffre 8 est bizarre, mais bon, il y a peut-être un truc à voir de ce côté-là 

                -
                Edité par Phil_1857 1 février 2023 à 16:55:01

                • Partager sur Facebook
                • Partager sur Twitter

                IA : réseau de neurones

                × 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