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édentes Révision précédente
Prochaine révision
Révision précédente
l_intelligence_du_semaphore [2019/02/06 16:13]
serge
l_intelligence_du_semaphore [2020/09/05 12:40] (Version actuelle)
serge [La même chose avec Cupy ou Tensorflow]
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+    """​La fonction sigmoïde est une courbe en S."""​
-    https://fr.wikipedia.org/​wiki/​Sigmo%C3%AFde_(math%C3%A9matiques)"""​+
     return 1 / (1 + np.exp(-x))     return 1 / (1 + np.exp(-x))
 </​code>​ </​code>​
Ligne 52: Ligne 87:
     return z * (1 - z)     return z * (1 - z)
 </​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.+====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
  
-**Remarque ​de l'​auteur** +====Diagonale de 1==== 
-Nous pouvons en déduire ​qu'un réseau de neurones ​convolutifs n'a aucune ​intelligence ! +{{ 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
  
-=====Code qui marche à 96 %===== 
-<code python> 
-import numpy as np, cv2 
 def sigmoid(x): return 1 / (1 + np.exp(-x)) def sigmoid(x): return 1 / (1 + np.exp(-x))
 def sigmoid_prime(z):​ return z * (1 - z) def sigmoid_prime(z):​ return z * (1 - z)
 def relu(x): return np.maximum(0,​ x) def relu(x): return np.maximum(0,​ x)
 def relu_prime(z):​ return np.asarray(z > 0, dtype=np.float32) def relu_prime(z):​ return np.asarray(z > 0, dtype=np.float32)
-layers = [1600, 100, 100, 27] 
-activations,​ learningrate = [relu, relu, sigmoid], 0.05 
-f = np.load('/​media/​data/​3D/​projets/​semaphore/​semaphore.npz'​) 
-x_train, y_train = f['​x_train'​],​ f['​y_train'​] 
-x_train = 1 - x_train 
-x_test, y_test = x_train[50000:,:​],​ y_train[50000:​] 
-x_train, y_train = x_train[:​50000,:​],​ y_train[:​50000] 
-Y = np.eye(27, 27) 
-activations_prime = [globals()[f.__name__ + '​_prime'​] for f in activations] 
-A = {} 
-W = [np.random.randn(layers[k+1],​ layers[k]) / np.sqrt(layers[k]) for k in range(len(layers)-1)] 
-print("​Training..."​) 
-cv2.namedWindow('​img',​ cv2.WINDOW_NORMAL) 
-for epoch in range(1): 
-    for i, (a, d) in enumerate(zip(x_train,​ y_train)): 
-        if i % 100 == 0: 
-            print(epoch,​ i, d) 
-            cv2.imshow("​img",​ a.reshape(40,​40) * 255) 
-            cv2.waitKey(1) 
-        a = np.array(a, ndmin=2).T 
-        A[0] = a 
-        for k in range(len(layers)-1):​ 
-            z = np.dot(W[k],​ a) 
-            a = activations[k](z) 
-            A[k+1] = a 
-        delta_a = a - Y[:,[d]] 
-        for k in range(len(layers)-2,​ -1, -1): 
-            dz = delta_a * activations_prime[k](A[k+1]) 
-            dW = np.dot(dz, A[k].T) 
-            delta_a = np.dot(W[k].T,​ dz) 
-            W[k] -= learningrate * dW 
-print("​Testing..."​) 
-S = 0 
-for a, d in zip(x_test, y_test): 
-    for k in range(len(layers)-1):​ 
-        a = activations[k](np.dot(W[k],​ a)) 
-    if np.argmax(a) == d: 
-        S += 1 
-print("​Accuracy:​ %.1f %%" % (100.0 * S / len(x_test))) 
-np.save('​weights',​ W) 
-</​code> ​   ​ 
  
-{{tag>​ia ​semaphore ​sb}}+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===== 
 +  * **[[cupy_vs_numpy|Cupy:​ calcul numpy avec CUDA]]** 
 +  * **[[le_semaphore_avec_tensorflow|Le sémaphore avec 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.1549466009.txt.gz · Dernière modification: 2019/02/06 16:13 par serge