IMA4 2018/2019 P35

De Wiki de Projets IMA
Révision datée du 15 avril 2019 à 15:10 par Plin (discussion | contributions) (Semaine 10)


Présentation générale

Nom du projet : Machine Learning pour navigation autonome de robots mobiles

Résumé : Le but du projet est de permettre le robot trouver un trajectoire optimale

Etudiants : Wenjing CHEN et Puyuan LIN

Description

L'apprentissage automatique (en anglais machine learning ) est un champ d'étude de l'intelligence artificielle qui se fonde sur des approches statistiques pour donner aux ordinateurs la capacité d' « apprendre » à partir de données, c'est-à-dire d'améliorer leurs performances à résoudre des tâches sans être explicitement programmés pour chacune. Plus largement, cela concerne la conception, l'analyse, le développement et l'implémentation de telles méthodes. Dans notre projet, machine learning est appliqué au robot prenant les données du capteur comme les entrées et donnant les comportements d'action du robot dans la situation correspondante comme les sorties. Nous fournissons au robot un ensemble de données d'entrée / sortie des . Le robot apprend l'ensemble d'entrée/sortie pour obtenir un modèle du calcul lui-même. Donc le robot peut utiliser ce modèle pour permettre la navigation autonome.

Nous traiterons dans ce projet de l'aspect navigation autonome de robot, la carte et les obstacles ne changent pas, nous utilisons le Tensorflow et la langage python progrmme le robot et permettre le robot trouver la trajectoire optimale. Notre projet ne contient pas localisation de robot, détection d'obstacle.

Objectifs

robotino

Dans le but de réaliser notre projet nous devrons remplir les objectifs suivants:

  • Nous devons apprendre et utiliser python pour programmer le robot afin de réaliser la fonction de machine learning, afin que le robot puisse trouver le meilleur itinéraire.
  • Nous devons apprendre et utiliser TensorFlow pour apprendre le machine learning.
  • Nous devons apprendre et utiliser Intel Neural Compute Stick pour calculer nos base de donnée.

Analyse du projet

Positionnement par rapport à l'existant

Il existe actuellement une grande tendance de robots mobiles de navigation autonome, dont certaines utilisent la carte intégrée pour atteindre la destination, tandis que d’autres obtiennent le chemin en avant via le code à barres attaché au sol. Mais pour éviter les obstacles, il s’agit essentiellement de capteurs pour surveiller les obstacles environnants.

Analyse du premier concurrent

Aethon Robot
Aethon Inc,un fournisseur mondial de robots de transport mobiles autonomes, a été fondé en 2001.Sa technologie principale comprend les robots mobiles automatiques(TUG). Le TUG est un robot mobile autonome et intelligent doté de devenir une phénomène normale dans les hôpitaux car il délivre matériaux et fournitures. TUG livre efficacement des chariots de fournitures là où ils sont nécessaires, y compris les repas, linge de maison, ainsi que l'enlèvement des ordures.Contrairement aux autres robots de navigation autonomes, il utilise des cartes intégrées et une gamme de capteurs embarqués pour la navigation. Les développeurs utilisent des cartes de haute précision des installations hospitalières, puis programment leur agencement, y compris l’utilisation des ascenseurs, l’ouverture automatique des portes, les points de livraison et les stations de recharge. La carte programmée est chargée dans la mémoire du TUG. TUG utilise des cartes embarquées à des fins de guidage et calcule sa position en temps réel à l'aide de l'algorithme d'odométrie breveté d'Aethon. Il utilise des capteurs embarqués pour ajuster les corridors dynamiques et changeants en temps réel, naviguant en toute sécurité autour des personnes et des obstacles, tout en utilisant toujours sa carte intégrée pour le suivi.



https://aethon.com/products/

Analyse du second concurrent

Kiva Robot
Amazon Robotics, anciennement Kiva Systems, est une entreprise du Massachusetts qui fabrique des systèmes d'exécution robotiques mobiles. Traditionnellement, les marchandises sont déplacées autour d’un centre de distribution à l’aide d’un système de convoyage ou de machines actionnées par l’homme (comme des chariots élévateurs). Dans l’approche de Kiva, les articles sont stockés sur des unités de stockage portables. Lorsqu'une commande est validée dans le système de base de données Kiva, le logiciel localise le robot mobile le plus proche de l'article et lui ordonne de le récupérer. Les robots mobiles naviguent dans l’entrepôt en suivant une série d’autocollants de codes à barres informatisés posés au sol. Chaque unité d’entraînement est équipée d’un capteur qui l’empêche de se heurter aux autres. Lorsque l'unité d’entraînement arrive à l'endroit objectif, elle glisse sous la nacelle et la soulève du sol grâce à un tire-bouchon. Le robot transporte ensuite la nacelle vers l'opérateur pour prendre les articles.

Kiva a deux modèles de robots. Le plus petit modèle mesure environ 2 pieds sur 2,5 pieds et un pied de haut et peut soulever 1 000 livres. Le plus grand modèle peut transporter des palettes et des charges pesant jusqu'à 3 000 livres. La vitesse maximale d'un robot est de 1,3 mètre par seconde. Les robots mobiles sont alimentés par batterie et doivent être rechargés toutes les heures pendant cinq minutes.


https://www.amazonrobotics.com/

Scénario d'usage du produit ou du concept envisagé

  • Nos produits sont adaptés à les entreprise logistiques ou les entreprises de commerce électronique. Le robot peut traiter lui-même la commande afin de terminer la livraison des marchandises, en réduisant les coûts de main-d'œuvre et en améliorant l'efficacité.
  • Nos produits conviennent également à la gestion des entrepôts de l'entreprise.
  • La perspective de cette voiture intelligente peut également être utilisée dans les futures voitures intelligentes. Nous pouvons planifier le point de départ et la destination de la voiture, puis la voiture fonctionne de manière autonome pour éviter les obstacles et atteindre la fin.

Réponse à la question difficile

Est-ce qu'on commence à zéro ou utilise des bibliothèque?

Nous n'avons pas besoin d'écrire le programme entier à partir de zéro. Parce que ce sujet est assez grand, il peut se diviser en plusieurs parties, par exemple la partie de création de la carte d'endroit, la partie de connaissance des obstacles statiques, la partie de détections des gens et des robots, la partie de navigation, etc. C'est difficile pour nous de réaliser tous pour le temps limité. Tout ce que nous devons faire est de réaliser un algorithme de machine learning pour réaliser un seul but, la navigation autonome. Pour les restes, nous pouvons utiliser les code précédent pour apporter des améliorations en fonction de cela.


Est-ce que la mémoire de robot est assez suiffissant pour stocker le base de donnée de machine learning?

La taille de la mémoire de robot n'arrive pas à réaliser nombreux de calcul, nous devons utiliser intel neural compute stick pour calculer et stocker des données.

Préparation du projet

Cahier des charges

Le robot mobile autonome devra réaliser:

  • Générer une trajectoire automatiquement selon le point de départ et la destination par lui-même.


Phase d'apprentissage

  • Prise de connaissance de machine learning et familiarisation avec l'environnement Tensorflow.
  • Prise de connaissance de langage de programmation (Python).
  • Prise de connaissance de Intel Neural Compute Stick.
  • Prise de connaissance du principe d'algorithme dans le domaine de machine learning.

Techniques Logicielles

  • Utilisation de Tensorflow.
  • Utilisation de Python.
  • Utilisation de Intel Neural Compute Stick.

Liste des tâches à effectuer

  • Conception du schéma global des différentes parties :
    • Apprentissage des logicielles (programmable, robotique)
    • Génération de trajectoires avec un algorithme
    • Exécution de trajectoire
    • Validation du modèle

Calendrier prévisionnel

Réalisation du Projet

Feuille d'heures

Tâche Prélude Heures S1 Heures S2 Heures S3 Heures S4 Heures S5 + vacance Heures S6 Heures S7 Heures S8 Heures S9 Heures S10 Total
Analyse du projet 4 4 2 2 1 0
Analyse de la structure de donnée d'entrée et sortie 0 0 3 2 1 1
Installation du Tensorflow et Python 0 0 0 0 3 0
Analyse de la modèle du reseau de neurone 0 0 0 5 0 5
Programmation de Tensorflow 0 0 0 0 0 4.5
Rédaction du wiki 3 1 0.5 0.5 0.5 1
Total de la semaine (heure) 8 5 5.5 9.5 5.5 11.5

Prologue

Semaine 1

Cette semaine nous avons commencé nos recherches sur machine learning et avons essayé de comprendre le principe de la palteforme «Tensorflow». Nous avons determiné nos prochaines étapes:

  • 1.Exploration de données: Connaître la format des données d'entrées et sorties.
  • 2.Préparation de données: Transformer des données en format standard(Tous les tableaux entiers sont en même taille.)
  • 3.Construire une modèle.
  • 4.Former la modèle: Utiliser des échantillons pour la formation.
  • 5.Evaluer la modèle: Calculer taux de précision en utilisant l'ensemble du test

Semaine 2

Avec l'aide de Monsieur Vincent Coelen, nous avons déterminé comment collecter des données pour entraîner la modèles de machine learning. On veut utiliser la simulation qu'il fournit la carte virtuelle dont nous avons besoin et le robotino peut s'y déplacer pour simuler l'itinéraire de navigation. Nous utilisons la manette externe pour contrôler le mouvement du robotino. On utilise cette méthode pour collecter des données. Après avoir les données, il faut utiliser l'autre logicielle pour les stocker.

Semaine 3

Cette semaine, nous avons analysé de la structure de la donnée qu'on nous devons collecte. Nous avons décidé de collecter la vitesse de l'abscisse, la vitesse de l'ordonnée et la vitesse angulaire de chaque point sur une trajectoire, afin de pouvoir relier tous les points en une trajectoire entier. En même temps, il faut noter les coordonnées du point de départ et la destination.

Tensorflow.png

Semaine 4

  • Initiation au Deep learning. Suivre le lien [1] pour avoir accès à des cours et des travaux pratiques centrés sur l'apprentissage approfondi.
  • Pour installer Anaconda : [2]
  • Pour installer PyTorch : [3]
  • Pour installer Tensorflow : [4]

Semaine 5

Nous avons décidé notre méthode pour construire notre modèle de machine learning avec l'aide de Monsieur Vincent Coelen.

  • Nous utilison le simulateur et la manntte pour collecter toutes les données dont nous avons besion. Ils se composent des points de départ, des points de destination et de tous les points de vitesse chaque 0,1 seconde (la frèquence du simulateur = 10Hz). Parce qu'on pilote le robot jusqu'à la destination munuellement, nous devons donc le contrôler artificiellement pour choisir la trajectoire optimale et supprimer les chemins qui sont loin du meilleur.
  • Après dans la phase d'entraînement, nous donnons toutes de trajectoires qu'on a collecté au reseau de neurones. Grâce à ce processus d'entraînement, le robot peut mémoriser la carte et l'emplacement des obstacles. Si plus de données sont formées, plus la carte en mémoire est précise, nous avons décidé de collecter au moins 100 jeux de données.Ensuite, après la modèle est finie, il faut évaluer la fidélité de la modèle. On a décidé d'utiliser l'algorithme du gradient pour augmenter la fidélité petit-à-petit.
  • Enfin, dans la phase d'utilisation, on fournit le point de départ et la destination comme les entrées, et par ailleurs, on aussi donne les premiers 10 points de vitesse pour arriver à la destination comme les entrées. Donc le réseau peut utiliser ces conditions et calculer pour continuer à deplacer pas-à-pas (1 point) jusqu'à la destination. Bien sûr, si nous plus de points comme l'entrée, la précision sera meilleure. Nous avons temporairement fixer à 10 points. Le robot va sûrement s'arrêter pour calculer le point suivant. Mais le temps est très court. Donc on pense qu'on peut le négliger.

Semaine 6-7

Nous avons commencé la semaine avec un rendez-vous avec notre tuteur afin de faire un compte rendu du simulateur de robotino. On lancer logiciel Rviz et utilise la mannette pour piloter notre robot.La vitesse et la vitesse angulaire à cet instant sont enregistrées automatiquementtoutes toutes les 0,01 secondes. Chaque fois on pilote le robot jusqu'à la destination, la prochaine destination apparaîtra au hasard sur la carte et ensuit on ferme l'acquisition, et toutes les données sur cet itinéraire seront automatiquement enregistrées sous forme de texte, Il faut faire attention que les données de la prochaine destination seront enregistrées aussi à ce moment-là, n'oubliez pas de supprimer. Parce que nous utilisons la mannette pour collecter manuellement des données, nous ne pouvons que contrôler le robot suive l'itinéraire optimal approximatif. Si parfois l'itinéraire que nous empruntons et que les meilleurs itinéraires sont éloignés, nous devons supprimer cette itinéraire inutiles.


6terminaux.jpg

Pour réaliser toutes les fonctions, il faut lancer 6 terminaux (droite à gauche).

  • Le premier et le deuxième terminal sont d'ouvrir refbox.
 dans le 1er terminal:                  
                  cd refbox/rcll-refbox/
                  bin/llsf-refbox
 dans le 2ème terminal:
                  cd refbox/rcll-refbox/
                  bin/llsf-refbox

  • Le troisième terminal est d'ouvrir l'environnement de simulateur et lancer le fichier de simulateur.
                  roslaunch gazebo_sim_launch env_global.launch sim:=true
                  roslaunch ML_acquisition StartAcquisition.launch
  • Le quatrième terminal est d'ouvrir la carte virtuelle dont on a besoin.
                  rviz
                  load config ~/.rviz/ML_acquisition.rviz
  • Le cinquième terminal est de connecter entre PC et la mannette. Et on ne contrôle qu'un robotino (robot 1).
                  launch the joystick controller
                  roslaunch robotino_teleop joystick_teleop.launch robot:=robotino1
  • Le sixième terminal est d'engistrer toutes les données dans un texte.
                  cd ~/acquisition
                  rosrun ML_acquisition GenerateWaypoints1.py


Lacarte.jpg


Quand on ouvre la logicielle rviz, on peut trouver différents types de carte. La première carte simule l'environnement réel. Les rectangles représentent les obstacles. Le cercle représente le Robotino. On peut aussi voir une flèche rouge sur la carte, qui représente le point de destination et sa direction. Alors, il y a l'autre type de la carte. Il nous semble que les obstacles ont les couches épaissies. La fonction de cette couche est d'éviter la collision entre le Robotino et l'obstacle. Parce que l'épaisseur de la couche est supérieure à le rayon du Robotino. On peut aussi trouver que quelques lignes vertes apparaissent sur les obstacles. Ces lignes servent à représenter le contour de l'obstacle mesuré par le capteur de distance. En comparant ces deux types, nous avons finalement choisi le dernier pour collecter des données. Car on n'a pas besoin de s'inquiéter la situation de la collision. Donc, on peut obtenir les données qui est proche de la trajectoire optimale.


Joysticks.jpg


On utilise une manette sans fil pour simuler l'opération du Robotino dans la situation réelle. Quand on a fini une trajectoire, on doit arrêter le simulateur. Et nous devons traiter les données (supprimer les point de départ répétés et les point qui appartiennent au point de destination suivant). Enfin, on doit collecter au moins de 100 groupes de données qui peuvent permettre construire le réseau de neurones.



En plus, pendant le processus de la collection des données, on a a essayé de programmer la première partie: lire les données qu'on a déjà collecté; enregistrer dans le tensorflow et définir les groupes d'entraînement et les groupes de test. En fin, on doit réaliser la normalisation des données:

On a utilisé quelques bibliothèques:

  import tensorflow as tf                                 
  import matplotlib.pyplot as plt                   # pour dessiner les trajectoires
  import numpy as np
  import pandas as pd                               # pour qu'on peut utiliser les tableaux                                                                               
  import time


D'abord, on a définit une fonction pour lire des documents:

  def load_data(input_file):
      print("Load Data:\n")
      dataset = np.loadtxt(input_file, delimiter=",") 
      print("Done")
      print(len(dataset))
      return dataset
      train_targets = []  #Créer un tableau pour entraînement
      test_targets = []   #Créer un tableau pour test
      for n in [15]:
         train_data = dataset[15:, :14]
 
    #Pare qu'on a 4 types de données (point de départ, point de vitesse, point de destination et image de carte ), donc 'num_classes' égale à 4                                                                                                             
       test_data = dataset[:15, :14]
         train_target = to_categorical(dataset[15:, n], num_classes=4)  
       test_target = to_categorical(dataset[:15, n], num_classes=4)
       test_targets = dataset[15:, 5:]
       test_targets = test_targets.astype(int)  #on change le type de label en entier



Lorsque différentes caractéristiques sont regroupées, les petites données en valeur absolue sont «consommées» par les méga données en raison de l'expression de la caractéristique elle-même. À ce stade, nous devons extraire "features vector". Normalisation s'assure que chaque caractéristiques est traitée de manière égale par le classificateur. Il y a beaucoup de méthode pour normaliser les données. On choisit une méthode classique: scikit-learn (StandardScaler):

       mean = train_data.mean(axis=0)
       train_data -= mean
       std = train_data.std(axis=0)
       train_data /= std
       test_data -= mean
       test_data /= std
       train_targets.append(train_target)
       test_targets.append(test_target)
       return train_data, train_targets, test_data, test_targets  


Ensuite, on doit enregistre les données dans un tableau et enregistrer le tableau dans un nouveau csv document:

  def readwrite(input_file,output_file):
      data_f=pd.read_csv(input_file,names=['StaX', 'StaY', 'StaA',          
                                           'VelX', 'VelY', 'VelA',
                                           'EndX', 'EndY', 'EndA', 'image'],sep=',')
      print(type(data_f), '\t', data_f.shape)
      data_f[['StaX', 'StaY', 'StaA', 
              'VelX', 'VelY', 'VelA',
              'EndX', 'EndY', 'EndA']].to_csv(output_file, sep=',', header=False,index=False)

Semaine 8

Nous souhaitons réaliser deux fonctions principales: laisser le robot reconnaître les obstacles sur la carte et naviguer une trajectoire correcte. Nous devons donc créer deux réseaux neuronaux pour permettre aux robots d’apprendre ensemble. Notre tâche cette semaine est de construire le premier réseau pour identifier les images. Nous avons décidé de le mettre en œuvre en utilisant un réseau neuronal convolutif. En apprentissage automatique, un réseau de neurones convolutifs ou réseau de neurones à convolution (en anglais CNN ou ConvNet pour Convolutional Neural Networks) est un type de réseau de neurones artificiels acycliques (feed-forward), dans lequel le motif de connexion entre les neurones est inspiré par le cortex visuel des animaux. Les neurones de cette région du cerveau sont arrangés de sorte qu'ils correspondent à des régions qui se chevauchent lors du pavage du champ visuel. Leur fonctionnement est inspiré par les processus biologiques, ils consistent en un empilage multicouche de perceptrons, dont le but est de prétraiter de petites quantités d'informations. Les réseaux neuronaux convolutifs ont de larges applications dans la reconnaissance d'image et vidéo. https://fr.wikipedia.org/wiki/R%C3%A9seau_neuronal_convolutif

Le principe de notre projet que nous avons conçu suivant:


Conv2.png


D'abord, nous transformons l'image de la carte en une groupe de données, utilisant une bibliothèque de tensorflow. Et ensuite, nous devons calculer les convolutions de les données, et comme l'entrée de la fonction d'activation, et les mettre dans le pool et choisir la valeur maximal ou moyenne,après les mettre dans différent labels.


Les programmes principaux:

Nous devons d'abord récupérer les données contenant les informations des cartes :

 def load_imdata(input_file):
     image_datas = []
     X_im = []
     pathDir_1 =  os.listdir(input_file)                 # retourner une liste de noms des fichiers dans le document 'input_file'
     for allDir_1 in pathDir_1:
         child = os.path.join('%s/%s' % (input_file, allDir_1))   # connecter entre le document 'input_file' et les fichiers 
                                                                    pour devenir un sous-chemin d'accès,  par exemple :child =  'input_file/nom_de_fichier'
         df=pd.read_csv(child)                           # lire le fichier
         image_datas.append(df)                          # ajouter des nouveaux données à la fin de la liste      
     for data in image_datas:
         # print(data.shape)
         x = data.values.reshape(-1, data.shape[0], data.shape[1], 1).astype('float32') / 255.   # reconstituer la liste précédente pour que nous pouvons 
                                                                                                   transformer la liste en une forme matricielle
     X_im.append(x)
     print(len(X_im))
     # X_im = np.array(X_im)
     return X_im

Pour construire notre réseau CNN:

 class CNN:
     @staticmethod                            # La fonction intégrée @staticmethod retourne une méthode statique pour une fonction donnée.
     def build(input_shape):
         input = Input(shape=input_shape)
         x = Conv2D(64, (3, 3))(input)             #Conv2D pour la convolution d'images
         # x = Conv2D(128, (3, 3))(x)
         x = MaxPooling2D((2, 2))(x)               #définir Max pooling avec un filtre 2 × 2
         # x = Conv2D(256, (3, 3))(x)
         x = Flatten()(x)                                    # renvoie une copie de tableau réduit en une dimension.
         # x = Dense(16, activation='relu')(x)
         # x = Dropout(0.1)(x)
         x = Dense(1, activation='sigmoid')(x)
         return Model(input,x)
 model = CNN.build(input_shape)
 sgd = SGD(lr=0.01, decay=1e-6, momentum=0.9, nesterov=True)    # créer un optimiseur de descente de gradient stochastique
 model.compile(
           loss='categorical_crossentropy',
           optimizer=sgd,
           metrics=['accuracy'])
 H = model.fit(
           x=train_data,
           y =train_targets,
           epochs=EPOCH,
           batch_size=1)



Ensuite, nous devons construire un réseau pour prédire des trajectoires. Nous avons décider d'utiliser RNN

class LSTMRNN(object):    
   def __init__(self, n_steps, input_size, output_size, cell_size, batch_size):        
       self.n_steps = n_steps        
       self.input_size = input_size        
       self.output_size = output_size        
       self.cell_size = cell_size        
       self.batch_size = batch_size        
       with tf.name_scope('inputs'):            
           self.xs = tf.placeholder(tf.float32, [None, n_steps, input_size], name='xs')            
           self.ys = tf.placeholder(tf.float32, [None, n_steps, output_size], name='ys')        
       with tf.variable_scope('in_hidden'):            
           self.add_input_layer()       
       with tf.variable_scope('LSTM_cell'):            
           self.add_cell()        
       with tf.variable_scope('out_hidden'):            
           self.add_output_layer()        
       with tf.name_scope('cost'):            
           self.compute_cost()        
       with tf.name_scope('train'):            
           self.train_op = tf.train.AdamOptimizer(LR).minimize(self.cost)     
           
   def add_input_layer(self,):        
       l_in_x = tf.reshape(self.xs, [-1, self.input_size], name='2_2D')              
       Ws_in = self._weight_variable([self.input_size, self.cell_size])            
       bs_in = self._bias_variable([self.cell_size,])           
       with tf.name_scope('Wx_plus_b'):            
           l_in_y = tf.matmul(l_in_x, Ws_in) + bs_in             
           self.l_in_y = tf.reshape(l_in_y, [-1, self.n_steps, self.cell_size], name='2_3D')     
           
   def add_cell(self):        
       lstm_cell = tf.contrib.rnn.BasicLSTMCell(self.cell_size, forget_bias=1.0, state_is_tuple=True)        
       with tf.name_scope('initial_state'):            
           self.cell_init_state = lstm_cell.zero_state(self.batch_size, dtype=tf.float32)        
           self.cell_outputs, self.cell_final_state = tf.nn.dynamic_rnn(            
               lstm_cell, self.l_in_y, initial_state=self.cell_init_state, time_major=False)     
           
   def add_output_layer(self):             
       l_out_x = tf.reshape(self.cell_outputs, [-1, self.cell_size], name='2_2D')        
       Ws_out = self._weight_variable([self.cell_size, self.output_size])        
       bs_out = self._bias_variable([self.output_size, ])             
       with tf.name_scope('Wx_plus_b'):            
           self.pred = tf.matmul(l_out_x, Ws_out) + bs_out     
           
   def compute_cost(self):        
       losses = tf.contrib.legacy_seq2seq.sequence_loss_by_example(            
           [tf.reshape(self.pred, [-1], name='reshape_pred')],            
           [tf.reshape(self.ys, [-1], name='reshape_target')],            
           [tf.ones([self.batch_size * self.n_steps], dtype=tf.float32)],            
           average_across_timesteps=True,            
           softmax_loss_function=self.ms_error,            
           name='losses'        
           )        
       with tf.name_scope('average_cost'):            
           self.cost = tf.div(                
               tf.reduce_sum(losses, name='losses_sum'),                
               self.batch_size,                
               name='average_cost')            
           tf.summary.scalar('cost', self.cost)                    
   @staticmethod    
   def ms_error(labels, logits):        
       return tf.square(tf.subtract(labels, logits))     
   def _weight_variable(self, shape, name='weights'):        
       initializer = tf.random_normal_initializer(mean=0., stddev=1.,)        
       return tf.get_variable(shape=shape, initializer=initializer, name=name)     
       
   def _bias_variable(self, shape, name='biases'):        
       initializer = tf.constant_initializer(0.1)        
       return tf.get_variable(name=name, shape=shape, initializer=initializer)


Enfin, il faut combiner les deux réseaux pour qu'ils peuvent entraîner ensemble:

def train_model():
   print("Train Begin:")
   train_data, train_targets, test_data, test_targets = load_imdata('images_data')
   vel_X, vel_Y, vel_A = get_vel("vel_data")
   coord_marix = load_sf("data")
   x_train_img = train_data[0]
   x_train_img = x_train_img.reshape((-1,199,320,1))
   x_train_img = np.tile(x_train_img, (64, 1, 1, 1))
   print(x_train_img.shape)
   x_train_coor = coord_marix[0]
   print(x_train_coor.shape)
   y_train = vel_X
   print(y_train.shape)
   input_shape_img = (199, 320, 1)
   input_init_img = Input(shape=input_shape_img)
   input_shape_coor = (100,)
   input_init_coor = Input(shape=input_shape_coor)
   processed_img = CNN.build(input_init_img)
   processed_coor = input_init_coor    
   merged_layer = Concatenate(axis=-1)([processed_img, processed_coor])
   x = Dense(600)(merged_layer)
   print("before:",tf.shape(x))
   my_reshape = Lambda(lambda x: K.reshape(x, (-1,600,1)))
   x = my_reshape(x)
   print("after:",tf.shape(x))
   x = LSTM(128, input_shape=(600,1), return_sequences=True)(x)
   out = TimeDistributed(Dense(1))(x)
   model_X = Model([input_init_img,input_init_coor], out)
   model_X.summary()
   model_X.compile(loss='mean_squared_error', 
               optimizer='adam', # rmsprop
               metrics=['mae', 'acc']) #metrics=['accuracy']
   history = model_X.fit([x_train_img,x_train_coor], y_train,
           batch_size=20,
           epochs=EPOCHS,
           
           ) 
   model_X.save("my_model/X_vel_model.h5")
   prediction = model_X.predict([x_train_img,x_train_coor])
   print(prediction[0])
   y_train = vel_Y
   model_Y = Model([input_init_img,input_init_coor], out)
   model_Y.summary()
   model_Y.compile(loss='mean_squared_error', 
               optimizer='adam', # rmsprop
               metrics=['mae', 'acc']) #metrics=['accuracy']
   history = model_Y.fit([x_train_img,x_train_coor], y_train,
           batch_size=20,
           epochs=EPOCHS,           
           ) 
   model_Y.save("my_model/Y_vel_model.h5")
   prediction = model_Y.predict([x_train_img,x_train_coor])
   print(prediction[0])
   y_train = vel_A
   model_A = Model([input_init_img,input_init_coor], out)
   model_A.summary()
   model_A.compile(loss='mean_squared_error', 
               optimizer='adam', # rmsprop
               metrics=['mae', 'acc']) #metrics=['accuracy']
   history = model_A.fit([x_train_img,x_train_coor], y_train,
           batch_size=20,
           epochs=EPOCHS          
           ) 
   model_A.save("my_model/A_vel_model.h5")
   prediction = model_A.predict([x_train_img,x_train_coor])
   print(prediction[0])

Semaine 9

Après avoir entraîné nos réseaux, nous essayons de tester. Mais le résultat n'est pas satisfait : Pour la prédiction du point de vitesse dans la direction de l'axe X, les points prédits pendant la période précédente est précise, mais il existe un écart très large entre la valeur prédite et la valeur réelle. Également, les prédiction du point de vitesse dans la phase d'angle et la directions de l'axe Y ne sont pas raisonnables. Donc nous avons considéré de changer notre réseau en utilisant à prédire des trajectoires.

class LSTMRNN(object):    
   def __init__(self, n_steps, input_size, output_size, cell_size, batch_size):        
       self.n_steps = n_steps        
       self.input_size = input_size        
       self.output_size = output_size        
       self.cell_size = cell_size        
       self.batch_size = batch_size        
       with tf.name_scope('inputs'):            
           self.xs = tf.placeholder(tf.float32, [None, n_steps, input_size], name='xs')            
           self.ys = tf.placeholder(tf.float32, [None, n_steps, output_size], name='ys')        
       with tf.variable_scope('in_hidden'):            
           self.add_input_layer()       
       with tf.variable_scope('LSTM_cell'):            
           self.add_cell()        
       with tf.variable_scope('out_hidden'):            
           self.add_output_layer()        
       with tf.name_scope('cost'):            
           self.compute_cost()        
       with tf.name_scope('train'):            
           self.train_op = tf.train.AdamOptimizer(LR).minimize(self.cost)     
           
   def add_input_layer(self,):        
       l_in_x = tf.reshape(self.xs, [-1, self.input_size], name='2_2D')        
       Ws_in = self._weight_variable([self.input_size, self.cell_size])              
       bs_in = self._bias_variable([self.cell_size,])            
       with tf.name_scope('Wx_plus_b'):            
           l_in_y = tf.matmul(l_in_x, Ws_in) + bs_in        
           # reshape l_in_y ==> (batch, n_steps, cell_size)        
           self.l_in_y = tf.reshape(l_in_y, [-1, self.n_steps, self.cell_size], name='2_3D')     
           
   def add_cell(self):        
       lstm_cell = tf.contrib.rnn.BasicLSTMCell(self.cell_size, forget_bias=1.0, state_is_tuple=True)        
       with tf.name_scope('initial_state'):            
           self.cell_init_state = lstm_cell.zero_state(self.batch_size, dtype=tf.float32)        
           self.cell_outputs, self.cell_final_state = tf.nn.dynamic_rnn(            
               lstm_cell, self.l_in_y, initial_state=self.cell_init_state, time_major=False)     
           
   def add_output_layer(self):        
       l_out_x = tf.reshape(self.cell_outputs, [-1, self.cell_size], name='2_2D')        
       Ws_out = self._weight_variable([self.cell_size, self.output_size])        
       bs_out = self._bias_variable([self.output_size, ])        
       # shape = (batch * steps, output_size)        
       with tf.name_scope('Wx_plus_b'):            
           self.pred = tf.matmul(l_out_x, Ws_out) + bs_out     
           
   def compute_cost(self):        
       losses = tf.contrib.legacy_seq2seq.sequence_loss_by_example(            
           [tf.reshape(self.pred, [-1], name='reshape_pred')],            
           [tf.reshape(self.ys, [-1], name='reshape_target')],            
           [tf.ones([self.batch_size * self.n_steps], dtype=tf.float32)],            
           average_across_timesteps=True,            
           softmax_loss_function=self.ms_error,            
           name='losses'        
           )        
       with tf.name_scope('average_cost'):            
           self.cost = tf.div(                
               tf.reduce_sum(losses, name='losses_sum'),                
               self.batch_size,                
               name='average_cost')            
           tf.summary.scalar('cost', self.cost)     
               
   @staticmethod    
   def ms_error(labels, logits):        
       return tf.square(tf.subtract(labels, logits))     
  
   def _weight_variable(self, shape, name='weights'):        
       initializer = tf.random_normal_initializer(mean=0., stddev=1.,)        
       return tf.get_variable(shape=shape, initializer=initializer, name=name)     
       
   def _bias_variable(self, shape, name='biases'):        
       initializer = tf.constant_initializer(0.1)        
       return tf.get_variable(name=name, shape=shape, initializer=initializer)

Semaine 10

Nous avons rencontré le même problème que nous avons la semaine dernière. Après avoir discuté avec nos profs, ils ont proposé plusieurs de solutions pour nous: 1. 2. 3. ....

Finalement, nous avons décider de changer la méthode pour connecter entre les deux réseaux. Nous n'utilisons pas de 'reshape' mais nous n'utilisons qu'une liste pour connecter les données des images et les points de départ et les points de destination.

Documents Rendus