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/03/31 14:00] – [Du code expliqué avec beaucoup d'amour] sergel_intelligence_du_semaphore [2020/02/04 16:27] – ↷ Liens modifiés en raison d'un déplacement. serge
Ligne 3: Ligne 3:
 **{{tagpage>semaphore|Sémaphores}}**  ....  **{{tagpage>bge|Blender Game Engine}}** ....  **{{tagpage>ia|Intelligence Artificielle}}** **{{tagpage>semaphore|Sémaphores}}**  ....  **{{tagpage>bge|Blender Game Engine}}** ....  **{{tagpage>ia|Intelligence Artificielle}}**
 </WRAP> </WRAP>
 +<WRAP center round box 60% centeralign> 
 +C'est quoi un sémaphore ? 
 +{{ youtube>F3sY6_fOx2I?medium }}
 {{ chappe.jpeg?400 }} {{ chappe.jpeg?400 }}
-=====Les images à reconnaître=====+</WRAP> 
 + 
 +<WRAP center round box 60% centeralign> 
 +**Calcul de [[Le sémaphore avec TensorFlow|Le sémaphore avec TensorFlow]] sur GPU au lieu du CPU avec TensorFlow** 
 +</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 group>
 <WRAP third column> <WRAP third column>
-{{:2019_03:shot_0_a.png?200|}}+{{:shot_0_a.png?200|}}
 </WRAP> </WRAP>
 <WRAP third column> <WRAP third column>
-{{:2019_03:shot_1_.png?200|}}+{{:shot_1_b.png?200|}}
 </WRAP> </WRAP>
 <WRAP third column> <WRAP third column>
-{{:2019_03:shot_2_b.png?200|}}+{{: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>
 </WRAP> </WRAP>
  
  
- 
- 
-=====La Reconnaissance faciale, c'est cool !===== 
- 
-  * **[[https://medium.com/@ageitgey/machine-learning-is-fun-part-4-modern-face-recognition-with-deep-learning-c3cffc121d78|Machine Learning is Fun! Part 4: Modern Face Recognition with Deep Learning]]** 
 ===== 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 45: 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 [[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.  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 77: Ligne 93:
  
 ====Diagonale de 1==== ====Diagonale de 1====
-{{ :2019_02:matrice_3x3_1.png?200 |}} +{{ media_01:matrice_3x3_1.png?200 |}} 
-  numpy.eye(N, M=None, k=0, dtype=<class 'float'>, order='C')\\+ 
 +  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.   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 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
Ligne 90: Ligne 108:
 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). 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).
  
-====Notre réseau==== 
-Réseau de neurones: **Une colonne de 1600 en entrée, 2 nodes de 100, une sortie de 27 caractères.** 
  
 ===== Réseau de neurones Convolutif ===== ===== Réseau de neurones Convolutif =====
-  * **[[ https://fr.wikipedia.org/wiki/R%C3%A9seau_neuronal_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. 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.
  
-=====Du code expliqué avec beaucoup d'amour=====+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. 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. 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.
  
-<file ia.py python>+====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 #!/usr/bin/env python3
 # -*- coding: UTF-8 -*- # -*- coding: UTF-8 -*-
Ligne 147: Ligne 180:
  
     def training(self):     def training(self):
-        """Apprentissage avec 60 000 images. Poids enregistré dans weights.npy"""+        """Apprentissage avec 50 000 images. Poids enregistré dans weights.npy"""
         print("Training...")         print("Training...")
  
Ligne 161: Ligne 194:
         # Initialisation des poids des nodes, pour ne pas à être à 0         # Initialisation des poids des nodes, pour ne pas à être à 0
         # Construit 3 matrices (100x1600, 100x100, 27x100)         # Construit 3 matrices (100x1600, 100x100, 27x100)
-        # /np.sqrt() résultat expérimental de l'initialisation de Glorot He Xavier+        # /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]) / \         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)]                        np.sqrt(self.layers[k]) for k in range(len(self.layers)-1)]
Ligne 171: Ligne 204:
  
             # Affichage pour distraire les mangalore             # Affichage pour distraire les mangalore
-            # TODO: mettre ça dans un truc à l'ext de cette méthode 
             if i % 10000 == 0:             if i % 10000 == 0:
                 print(i, nombre_lettre)                 print(i, nombre_lettre)
Ligne 190: Ligne 222:
  
                 # self.activations = non linéaire sinon sortie fonction linéaire de l'entrée                 # self.activations = non linéaire sinon sortie fonction linéaire de l'entrée
-                # imite le seuil d'activation électrique du neuronne+                # imite le seuil d'activation électrique du neurone
                 vecteur_colonne = self.activations[k](z)                 vecteur_colonne = self.activations[k](z)
  
Ligne 197: Ligne 229:
             # Retro propagation, delta_a = écart entre la sortie réelle et attendue             # Retro propagation, delta_a = écart entre la sortie réelle et attendue
             delta_a = vecteur_colonne - diagonale[:,[nombre_lettre]]             delta_a = vecteur_colonne - diagonale[:,[nombre_lettre]]
-            # Parcours des nodes en sens inverse pour corriger proportionnellemnt+            # Parcours des nodes en sens inverse pour corriger proportionnellement
             # les poids en fonction de l'erreur par rapport à la valeur souhaitée             # les poids en fonction de l'erreur par rapport à la valeur souhaitée
             # Descente du Gradient stochastique             # Descente du Gradient stochastique
Ligne 236: Ligne 268:
                 success += 1                 success += 1
             else:             else:
-                # TODO: mettre ça dans un truc à l'ext de cette méthode 
                 if self.failed:                 if self.failed:
                     self.write_failed(img, nombre_lettre, reconnu, success)                     self.write_failed(img, nombre_lettre, reconnu, success)
Ligne 271: Ligne 302:
  
     for i in range(5):     for i in range(5):
-        print("Petit test de l'influence du random dans la liste des poids") 
         learningrate = 0.022         learningrate = 0.022
         failed = 0         failed = 0
Ligne 278: Ligne 308:
         resp = sia.testing()         resp = sia.testing()
         print("Learningrate: {} Résultat {}".format(learningrate, round(resp, 1)))         print("Learningrate: {} Résultat {}".format(learningrate, round(resp, 1)))
-</code>    +</file>    
  
-=====La reconnaissance seule===== 
-L'image en entrée doit être: 
-  * 40 x 40 pixels 
-  * en noir et blanc convertit en 0 et 1, que des 0 et des 1 dans le array 
-  * Floutée entre 5 et 7 
-  * Convertie en vecteur ligne: img = img.reshape(1600) 
  
-====Les poids==== +===== Etape suivante: YOLO Darknet=====
-Le fichier weights.npy doit être dans le dossier du script. +
-**[[https://github.com/sergeLabo/semaphore/raw/master/weights.npy|weights.npy téléchargeable sur GitHub]]**. +
- +
-====La class Reconnaissance==== +
-<code python> +
-import numpy as np +
-import cv2 +
- +
- +
-def sigmoid(x): +
-    return 1 / (1 + np.exp(-x)) +
-def relu(x): +
-    return np.maximum(0, x) +
- +
-class Reconnaissance: +
-    def __init__(self): +
-        self.weight = np.load('weights.npy'+
- +
-    def testing(self, img): +
-        vecteur_ligne = img +
-        layers = [1600, 100, 100, 27] +
-        activations = [relu, relu, sigmoid] +
-        for k in range(len(layers)-1): +
-            vecteur_ligne = activations[k](np.dot(self.weight[k], +
-                                                       vecteur_ligne)) +
-            reconnu = np.argmax(vecteur_ligne) +
-        return reconnu +
-</code> +
- +
-====Adaptation de l'image==== +
-<code python> +
-# frame peut être la capture d'une webcam +
-cv2.imshow('RGB Input', frame) +
- +
-# Application d'un seuil pour extraire le sémaphore du fond +
-# Le seuil est à adapter en fonction de la couleur du sémaphore +
-hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV) +
-lower = np.array([120, 80, 80]) +
-upper = np.array([255, 255, 255]) +
-img = cv2.inRange(hsv, lower, upper) +
- +
-# Flou: GaussianBlur semble mieux que Averaging=cv2.blur() +
-img = cv2.GaussianBlur(img, (5, 5), 0) +
- +
-# Resize +
-img = cv2.resize(img, (40, 40), interpolation=cv2.INTER_AREA) +
- +
-# Noir et blanc, sans gris +
-ret, nb = cv2.threshold(img, 2, 255, cv2.THRESH_BINARY) +
- +
-# Valeur 0 ou 1 +
-nb = nb / 255 +
-                 +
-# Reshape pour avoir un vecteur ligne +
-vect = nb.reshape(40*40) +
- +
-reco = Reconnaissance() +
-reconnu = reco.testing(vect) +
-print("Caractère reconnu:", reconnu) +
-</code> +
- +
-====Les fichiers pour un test avec Webcam et un sémaphore en carton==== +
-  * **[[https://github.com/sergeLabo/semaphore/tree/master/reconnaissance|Reconnaissance sur GitHub]]** +
- +
-===== Etape suivante: Mask R-CNN===== +
-Solution déposée en 2017 par un chercheur chez F...B...k.+
 **[[computer_vision_and_pattern_recognition_segmentation_d_image|Computer Vision and Pattern Recognition Mask R-CNN]]** **[[computer_vision_and_pattern_recognition_segmentation_d_image|Computer Vision and Pattern Recognition Mask R-CNN]]**
  
-===== Idées de choses à faire par Max===== +{{tag> bge ia python sb semaphore }}
- +
-  * Essayer d'implémenter un petit réseau de neurones convolutif pas trop compliqué. +
-  * Essayer de reconnaître les coordonnées de la position du sémaphore (un quadrilatère entourant le sémaphore sur l'image) en plus de sa valeur. +
-  * Essayer de reconnaître la forme du sémaphore plutôt que l'associé à un symbole : Reconnaître la position du régulateur et des 2 indicateurs. Les buts étant de pouvoir changer l'alphabet sans réapprendre, et de pouvoir dessiner un sémaphore schématique tel que reconnu par l'IA. +
-  * Essayer de reconnaître plusieurs sémaphores simultanément. Le but est de pouvoir choisir lequel on veut pouvoir imiter. +
- +
-==== Idée directrice ==== +
-Réaliser 2 apprentissages indépendants pour faciliter l'apprentissage et ajouter du filtrage intermédiaire. Je propose de réaliser un premier apprentissage qui reconnaîtrait la position d'un sémaphore dans une image. Il retournerait ses coordonnées. Le second apprentissage reconnaîtrait la forme d'un sémaphore dans un cadre particulier. +
-\\ \\ +
-Je vois plusieurs avantages : +
-  * Nous savons que dans une vidéo, un sémaphore ne peut pas se promener d'un bout à l'autre d'une frame de manière discontinue. On peut donc facilement filtrer les faux positifs de détection d'un sémaphore du premier apprentissage qui se déplaceraient de manière discontinue. +
-  * Une fois la première reconnaissance réalisé il est facile de recadrer l'image en entrée et la présenter dans un format particulier au second apprentissage (ex: 40px x 40px). +
-  * Il est plus facile d'apprendre à détecter plusieurs positions de sémaphore simultanés que de reconnaitre la forme de plusieurs sémaphore simultanément. +
-  * Si nous reconnaissons plusieurs sémaphores simultanément, nous pourrons lancer un traitement de reconnaissance de leur forme pour chaque détection indépendament. +
-  * Un filtrage intelligent pourrait comprendre qu'un sémaphore est occulté par un obstacle mouvant avant d'etre de nouveau visible. +
-==== Petit réseau convolutif ==== +
-  * En entré, il faudrait une première couche identique, et une deuxième couche qui n'est pas relié à tous les neurones de la première couche, mais uniquement à un ensemble représentant une tuile. Il faut donc modifier l'algo actuel qui relie toujours tous les neurones de la couche N-1 à tous les neurones de la couche N. +
-  * Comment paver l'image de tuiles ? Est ce que les tuiles doivent se chevaucher ? Il serait interessant de variabiliser la taille des tuiles et leur chevauchement. +
- +
-==== Reconnaître les coordonnées du sémaphore ==== +
-  * Il faut lors de la génération des images ajouter une méta information dans l'image indiquant dans les coordonnées d'un quadrilataire inscrivant le sémaphore. +
-  * Quels types de coordonnées ? Les coordonées de 2 angles opposés ? les coordonées d'un angle et 2 distances ? autre ? +
-  * Comment modifier la sortie du réseau de neurones pour reconnaître le couple (position du sémaphore, valeur) ? +
- +
-==== Reconnaître la forme du sémaphore ==== +
-  * Plutôt que de tagger l'image avec un symbole, il faudrait la tagger avec la forme du sémaphore. +
-  * Quels informations pour coder la forme ? Les 3 Angles absolue du régulateur et des indicateurs ? +
-  * Comment modifier la sortie du réseau de neurones pour reconnaître le couple (position du sémaphore, forme du sémaphore) ? +
- +
-==== Reconnaître plusieurs sémaphores ==== +
-  * Comment modifier la sortie du réseau de neurones pour reconnaître plusieurs couples (position, forme) ? +
- +
-{{tag>ia semaphore sb realisations_logicielles}}+
  
l_intelligence_du_semaphore.txt · Dernière modification : 2020/12/27 15:07 de serge