Outils pour utilisateurs

Outils du site


l_intelligence_du_semaphore

Différences

Ci-dessous, les différences entre deux révisions de la page.

Lien vers cette vue comparative

Les deux révisions précédentesRévision précédente
Prochaine révision
Révision précédente
Prochaine révisionLes deux révisions suivantes
l_intelligence_du_semaphore [2019/01/26 13:24] – [Sigmoïd] sergel_intelligence_du_semaphore [2020/09/05 10:38] – [Le script] serge
Ligne 1: Ligne 1:
 ====== L'intelligence du sémaphore ====== ====== L'intelligence du sémaphore ======
 +<WRAP center round box 80% centeralign>
 +**{{tagpage>semaphore|Sémaphores}}**  ....  **{{tagpage>bge|Blender Game Engine}}** ....  **{{tagpage>ia|Intelligence Artificielle}}**
 +</WRAP>
 +<WRAP center round box 60% centeralign>
 +C'est quoi un sémaphore ?
 +{{ youtube>F3sY6_fOx2I?medium }}
 +{{ chappe.jpeg?400 }}
 +</WRAP>
  
 <WRAP center round box 60% centeralign> <WRAP center round box 60% centeralign>
-**{{tagpage>ia|Toutes les pages sur L'Intelligence Artificielle}}**+**Calcul de [[Le sémaphore avec TensorFlow|Le sémaphore avec TensorFlow]] sur GPU au lieu du CPU avec TensorFlow**
 </WRAP> </WRAP>
 +=====Les sources sur GitHub=====
 +  * **[[https://github.com/sergeLabo/semaphore|semaphore chez github.com]]**
 +=====Les images utilisées pour l'apprentissage=====
 +====Images sorties de Blender====
 +<WRAP group>
 +<WRAP third column>
 +{{media_03:shot_0_a.png?200|}}
 +</WRAP>
 +<WRAP third column>
 +{{media_03:shot_1_b.png?200|}}
 +</WRAP>
 +<WRAP third column>
 +{{media_03:shot_2_c.png?200|}}
 +</WRAP>
 +</WRAP>
 +====Images adaptées pour l'apprentissage====
 +L'optimisation a montré que la meilleure solution est avec ce type d'image.
 +<WRAP group>
 +<WRAP third column>
 +{{media_01:shot_0_a.png?200|}}
 +</WRAP>
 +<WRAP third column>
 +{{media_01:shot_1_.png?200|}}
 +</WRAP>
 +<WRAP third column>
 +{{media_01:shot_2_b.png?200|}}
 +</WRAP>
 +</WRAP>
 +
  
 ===== Des maths ! ==== ===== Des maths ! ====
 ====Relu Rectifier neural networks==== ====Relu Rectifier neural networks====
 +{{ relu.jpg?400 |}}
   * **[[https://en.wikipedia.org/wiki/Rectifier_(neural_networks)|Rectifier (neural networks)]]**  sur Wikipedia en   * **[[https://en.wikipedia.org/wiki/Rectifier_(neural_networks)|Rectifier (neural networks)]]**  sur Wikipedia en
 <code python> <code python>
Ligne 26: Ligne 64:
 <code python> <code python>
 def relu_prime(z): def relu_prime(z):
-    """La fonction de Heaviside (également fonction échelon unité, fonction +    """La fonction de Heaviside (également fonction échelon unité, fonction marche d'escalier) est la fonction indicatrice de R. 
-    marche d'escalier) est la fonction indicatrice de R. +     
-    Une fonction fonction indicatrice, est une fonction définie sur un +Une fonction indicatrice, est une fonction définie sur un ensemble E qui explicite l’appartenance ou non à un sous-ensemble F de E de tout élément de E.  
-    ensemble E qui explicite l’appartenance ou non à un sous-ensemble F de E +C'est donc la fonction H (discontinue en 0) prenant la valeur 1 pour tous les réels positifs et la valeur 0 pour les réels strictement négatifs.
-    de tout élément de E.  +
-    C'est donc la fonction H (discontinue en 0) prenant la valeur 1 pour tous +
-    les réels positifs et la valeur 0 pour les réels strictement négatifs.+
     """     """
     return np.asarray(z > 0, dtype=np.float32)     return np.asarray(z > 0, dtype=np.float32)
 </code> </code>
 ====Sigmoïd==== ====Sigmoïd====
 +{{ sigmoid.png?400 |}}
   * **[[https://fr.wikipedia.org/wiki/Sigmo%C3%AFde_(math%C3%A9matiques)|Sigmoïde]]**  sur Wikipedia fr   * **[[https://fr.wikipedia.org/wiki/Sigmo%C3%AFde_(math%C3%A9matiques)|Sigmoïde]]**  sur Wikipedia fr
-Elle représente la fonction de répartition de la loi logistique. Elle est souvent utilisée dans les réseaux de neurones parce qu'elle est dérivable, ce qui est une contrainte pour l'algorithme de [[https://fr.wikipedia.org/wiki/R%C3%A9tropropagation_du_gradient|rétropropagation]] de Werbos. La forme de la dérivée de sa fonction inverse est extrêmement simple et facile à calculer, ce qui améliore les performances des algorithmes. +Elle représente la fonction de répartition de la loi logistique. Elle est souvent utilisée dans les réseaux de neurones parce qu'elle est dérivable, ce qui est une contrainte pour l'algorithme de [[https://fr.wikipedia.org/wiki/R%C3%A9tropropagation_du_gradient|rétropropagation]] de [[https://fr.wikipedia.org/wiki/Perceptron_multicouche#Perceptron_multicouche_%C3%A0_r%C3%A9tropropagation|Werbos]]. La forme de la dérivée de sa fonction inverse est extrêmement simple et facile à calculer, ce qui améliore les performances des algorithmes. 
 <code python> <code python>
 def sigmoid(x): def sigmoid(x):
 +    """La fonction sigmoïde est une courbe en S."""
     return 1 / (1 + np.exp(-x))     return 1 / (1 + np.exp(-x))
 </code> </code>
-===== Réseau de neurones convolutifs  ===== 
  
-Un réseau de neurones convolutifs est un type de réseau de neurones artificiels dans lequel le motif de connexion entre les neurones est inspiré par le cortex visuel des animaux.+====Sigmoïd prime==== 
 +<code python> 
 +def sigmoid_prime(z): 
 +    """La dérivée de la fonction sigmoid.""" 
 +    return z * (1 - z) 
 +</code> 
 + 
 +====Algorithme du gradient stochastique==== 
 +  * **[[https://fr.wikipedia.org/wiki/Algorithme_du_gradient_stochastique|Algorithme du gradient stochastique]]** 
 +L'algorithme du gradient stochastique est une méthode de descente de gradient (itérative) utilisée pour la minimisation d'une fonction objectif qui est écrite comme une somme de fonctions différentiables.  
 + 
 +====Diagonale de 1==== 
 +{{ media_01:matrice_3x3_1.png?200 |}} 
 + 
 +  numpy.eye(N, M=None, k=0, dtype=<class 'float'>, order='C'
 +   
 +  Return a 2-D array with ones on the diagonal and zeros elsewhere. 
 +Matrice ou la sortie est idéale: le 1 correspond à entée[i] = sortie[i], et entée[j],sortie[k] =0 si j différent de k 
 + 
 +====Initialisation de X. Glorot et He==== 
 +X = Xavier = prénom 
 +  * **[[http://deepdish.io/2015/02/24/network-initialization/|Initialization of deep networks]]** 
 + 
 +===== Réseau de neurones Perceptron multicouches  ===== 
 +  * **[[https://fr.wikipedia.org/wiki/Perceptron_multicouche|Perceptron multicouche]]** 
 +Un réseau de neurones Perceptron multicouches est un type de réseau dont l'information circule dans un unique sens, de la couche d'entrée vers la couche de sortie. Ont dit qu'il est un réseau "à propagation directe" (feedforward). 
 + 
 + 
 +===== Réseau de neurones Convolutif ===== 
 +  * **[[https://fr.wikipedia.org/wiki/R%C3%A9seau_neuronal_convolutif|Réseau neuronal convolutif]]** 
 +Un réseau de neurones Convolutif est un type de réseau de neurones artificiels dans lequel le motif de connexion entre les neurones est inspiré par le cortex visuel des animaux. Actuellement, il est très utilisé pour l'analyse des images, des vidéos et du langage naturel. 
 + 
 +Ce type de réseau est développé avec [[yolo_avec_mes_propres_images|Yolo Darknet Préparation de mes propres images]] puis [[yolo_sans_carte_graphique|Yolo Darknet sans carte graphique]] et enfin [[yolo_darknet_sur_un_portable_optimus|Yolo Darknet sur un portable Optimus]]. 
 + 
 +=====Réseau de neurones Perceptron multicouches en python===== 
 +**Du code expliqué avec beaucoup d'amour** 
 +Enfin, là c'est de l'intelligence qu'on cherche, pas de l'amour. 
 + 
 +====Notre réseau==== 
 + **Une colonne de 1600 en entrée, 2 nodes de 100, une sortie de 27 caractères.** 
 + 
 +{{ media_01:perceptron.svg.png?1000 |}} 
 + 
 +La totalité du projet est à **[[https://github.com/sergeLabo/semaphore|Semaphore]]** sur Github, et  **[[jeu_du_semaphore_dans_le_blender_game_engine|Jeu du sémaphore dans le Blender Game Engine]]** pour la création des images. 
 + 
 +====Installation==== 
 +Installation de pip3: 
 +  sudo apt install pip3 
 +Installation de numpy et opencv 
 +  sudo pip3 install opencv numpy 
 +Il faut installer mon [[pymultilame|module python perso]] disponible sur Github 
 +  sudo pip3 install -e git+https://github.com/sergeLabo/pymultilame.git#egg=pymultilame 
 +   
 +====Le script==== 
 +<file python ia.py> 
 +#!/usr/bin/env python3 
 +# -*- coding: UTF-8 -*- 
 + 
 +import shutil 
 +import numpy as np 
 +import cv2 
 +from pymultilame import MyTools 
 + 
 +def sigmoid(x): return 1 / (1 + np.exp(-x)) 
 +def sigmoid_prime(z): return z * (1 - z) 
 +def relu(x): return np.maximum(0, x) 
 +def relu_prime(z): return np.asarray(z > 0, dtype=np.float32) 
 + 
 +class SemaphoreIA: 
 +    def __init__(self, root, learningrate, failed=0): 
 +        self.root = root 
 +        self.learningrate = learningrate 
 +        self.failed = failed 
 +        self.tools = MyTools() 
 + 
 +        # Dossier des ratés 
 +        if self.failed: 
 +            # Suppression du dossier failed et recréation pour le vider 
 +            try: 
 +                shutil.rmtree(self.root + 'failed'
 +            except: 
 +                print('Pas de dossier failed'
 +            self.tools.create_directory(self.root + 'failed'
 + 
 +        # Réseau de neurones: colonne 1600 en entrée, 2 nodes de 100, sortie de 27 caractères 
 +        self.layers = [1600, 100, 100, 27] 
 +        # Fonction d'activation: imite l'activation d'un neuronne 
 +        self.activations = [relu, relu, sigmoid] 
 + 
 +        fichier = np.load(self.root + 'semaphore.npz'
 +        self.x_train, self.y_train = fichier['x_train'], fichier['y_train'
 +        self.x_train = 1 - self.x_train 
 +        self.x_test, self.y_test = self.x_train[50000:,:], self.y_train[50000:
 +        self.x_train, self.y_train = self.x_train[:50000,:], self.y_train[:50000] 
 + 
 +        # Affichage des images pour distraire 
 +        cv2.namedWindow('img'
 + 
 +    def training(self): 
 +        """Apprentissage avec 50 000 images. Poids enregistré dans weights.npy""" 
 +        print("Training..."
 + 
 +        # Matrice diagonale de 1 
 +        diagonale = np.eye(27, 27) 
 + 
 +        # globals() Return a dictionary representing the current global symbol table. 
 +        self.activations_prime = [globals()[fonction.__name__ + '_prime'] for fonction in self.activations] 
 + 
 +        node_dict = {} 
 + 
 +        # Liste des poids 
 +        # Initialisation des poids des nodes, pour ne pas à être à 0 
 +        # Construit 3 matrices (100x1600, 100x100, 27x100) 
 +        # /np.sqrt() résultat expérimental de l'initialisation d'un gars qui s'appelle Xavier Glorot et d'un autre qui s'appelle He ! 
 +        weight_list = [np.random.randn(self.layers[k+1], self.layers[k]) / \ 
 +                       np.sqrt(self.layers[k]) for k in range(len(self.layers)-1)] 
 + 
 +        # vecteur_ligne = image en ligne à la 1ère itération 
 +        # nombre_lettre = nombre correspondant à la lettre de l'image 
 +        # i pour itération, vecteur_colonne = x_train de i, nombre_lettre = y_train de i 
 +        for i, (vecteur_ligne, nombre_lettre) in enumerate(zip(self.x_train, self.y_train)): 
 + 
 +            # Affichage pour distraire les mangalore 
 +            if i % 10000 == 0: 
 +                print(i, nombre_lettre) 
 +                img = vecteur_ligne.reshape(40,40) * 255 
 +                img = cv2.resize(img, (600, 600), interpolation=cv2.INTER_AREA) 
 +                cv2.imshow("img", img) 
 +                cv2.waitKey(1) 
 + 
 +            # la ligne devient colonne 
 +            vecteur_colonne = np.array(vecteur_ligne, ndmin=2).T 
 + 
 +            # Forward propagation 
 +            node_dict[0] = vecteur_colonne 
 +            for k in range(len(self.layers)-1): 
 +                # weight_list[k] (100x1600, 100x100 27x100) vecteur_colonne (1600,) 
 +                # z de format 100 x 1 
 +                z = np.dot(weight_list[k], vecteur_colonne) 
 + 
 +                # self.activations = non linéaire sinon sortie fonction linéaire de l'entrée 
 +                # imite le seuil d'activation électrique du neurone 
 +                vecteur_colonne = self.activations[k](z) 
 + 
 +                node_dict[k+1] = vecteur_colonne 
 + 
 +            # Retro propagation, delta_a = écart entre la sortie réelle et attendue 
 +            delta_a = vecteur_colonne - diagonale[:,[nombre_lettre]] 
 +            # Parcours des nodes en sens inverse pour corriger proportionnellement 
 +            # les poids en fonction de l'erreur par rapport à la valeur souhaitée 
 +            # Descente du Gradient stochastique 
 +            for k in range(len(self.layers)-2, -1, -1): 
 +                delta_z = delta_a * self.activations_prime[k](node_dict[k+1]) 
 +                delta_w = np.dot(delta_z, node_dict[k].T) 
 +                delta_a = np.dot(weight_list[k].T, delta_z) 
 +                # Pour converger vers le minimum d'erreur 
 +                weight_list[k] -= self.learningrate * delta_w 
 + 
 +        # Dans un fichier 
 +        np.save(self.root + 'weights.npy', weight_list) 
 +        print('weights.npy enregistré'
 +        cv2.destroyAllWindows() 
 + 
 +    def testing(self): 
 +        """Teste avec 10 000 images, retourne le ratio de bon résultats""" 
 +        print("Testing..."
 + 
 +        weight_list = np.load(self.root + 'weights.npy'
 + 
 +        # Nombre de bonnes reconnaissance 
 +        success = 0 
 + 
 +        # Dict avec le nombre d'erreurs par lettre 
 +        failed_dict = {} 
 + 
 +        for vecteur_ligne, nombre_lettre in zip(self.x_test, self.y_test): 
 +            # image en ligne au 1er passage pour les failed 
 +            img = vecteur_ligne.copy() 
 + 
 +            for k in range(len(self.layers)-1): 
 +                vecteur_ligne = self.activations[k](np.dot(weight_list[k], 
 +                                                      vecteur_ligne)) 
 + 
 +            reconnu = np.argmax(vecteur_ligne) 
 +            if reconnu == nombre_lettre: 
 +                success += 1 
 +            else: 
 +                if self.failed: 
 +                    self.write_failed(img, nombre_lettre, reconnu, success) 
 +                if nombre_lettre in failed_dict: 
 +                    failed_dict[nombre_lettre] += 1 
 +                else: 
 +                    if self.failed: 
 +                        self.tools.create_directory(self.root + 'failed' + '/bad_' + str(nombre_lettre)) 
 +                        failed_dict[nombre_lettre] = 1 
 + 
 +        if self.failed: 
 +            sorted_by_value = sorted(failed_dict.items(), key=lambda kv: kv[1], reverse=True) 
 +            print(sorted_by_value) 
 + 
 +        resp = 100.0 * success / len(self.x_test) 
 +        return resp 
 + 
 +    def write_failed(self, img, nombre_lettre, reconnu, S): 
 +        """Les images avec erreur de reconnaisance sont copiées dans 
 +        /semaphore/failed/bad_11/11_6_9067.png 
 +        11 est la lettre k, donc dans le dossier il ny a que la lettre k 
 +        et le 2ème nombre est la lettre reconnue fausse 
 +        """ 
 +        name = str(nombre_lettre) + '_' + str(reconnu) + '_'  + str(S) + '.png' 
 +        fichier = self.root + 'failed' + '/bad_' + str(nombre_lettre) + '/' + name 
 +        img = img.reshape(40,40) * 255 
 +        cv2.imwrite(fichier, img) 
 + 
 + 
 +if __name__ == "__main__": 
 +    print(MyTools().get_absolute_path(__file__)) 
 +    root = MyTools().get_absolute_path(__file__)[:-28] 
 +    print("Current directory:", root) 
 + 
 +    for i in range(5): 
 +        learningrate = 0.022 
 +        failed = 0 
 +        sia = SemaphoreIA(root, learningrate, failed) 
 +        sia.training() 
 +        resp = sia.testing() 
 +        print("Learningrate: {} Résultat {}".format(learningrate, round(resp, 1))) 
 +</file>     
 + 
 +=====La même chose avec Cupy ou Tensorflow===== 
 + 
 + 
 +===== Etape suivante: YOLO Darknet===== 
 +**[[computer_vision_and_pattern_recognition_segmentation_d_image|Computer Vision and Pattern Recognition Mask R-CNN]]**
  
 +{{tag> bge ia python sb semaphore }}
  
l_intelligence_du_semaphore.txt · Dernière modification : 2020/12/27 15:07 de serge