Détection d'objets avec tensorflow2

Dans cette section nous allons utiliser l’API Tensorflow Object Detection (a.k.a TOD) qui propose :

Contrairement à la stratégie de Classification présentée dans la section Classification tf2, la Détection d’objets permet de trouver directement les boîtes englobantes des objets “face avec un 1” et “face avec un 2” : cette approche évite de faire appel au traitement d’image classique pour extraire les faces des cubes dans un premier temps, puis de classifier les images des faces des cubes dans un deuxième temps.

Le traitement d’image utilisé pour la classification est basé sur une approche traditionnelle de manipulation des pixels de l’image (seuillage, extraction de contour, segmentation…). Il est assez fragile : sensible à la luminosité, à la présence ou non d’un fond noir…

Un avantage attendu de l’approcje Object Detection est de fournir directement les boîtes englobantes des faces des cubes, sans passer par l’étape de traitement d’image.

Prérequis

L’entraînement des réseaux de neurones avec le module tensorflow se fera de préférence dans un environnement virtuel Python (EVP) qui permet de travailler dans un environnement Python séparé de celui existant pour le travail sous ROS.

💻 Utilise la FAQ Python : environnement virtuel pour créer un EVP :

1. Documentation

  1. Documentation générale sur numpy :

  2. Documentation sur l'API TOD pour tensorflow2 :

    • Le tutoriel officiel complet : TensorFlow 2 Object Detection API tutorial
    • Le dépôt git : models/research/object_detection

      Le tutoriel peut être consulté pour aller chercher des détails qui ne sont pas développés dans l’activité proposée, mais il est préferrable de suivre les indications du document présent pour installer et utiliser rapidement une version récente de tensorflow2.
  3. Lectures complémentaires :

2. Installer l’API TOD

L’installation de l’API TOD se déroule en 5 étapes :

  1. Créer et initialiser ton espace de travail
  2. Cloner le dépôt tensorflow/models
  3. Installer les outils protobuf
  4. Installer l’API COCO
  5. Installer le package object_detection

Dans tout le document le prompt du terminal sera noté (tf2) jlc@pikatchou $ : le préfixe (tf2) est là pour bien rappeler que le travail Python pour l’API TOD se fait dans l'Environnement Virtuel Python tf2 que tu auras créé au préalable (cf les Prérequis).

2.1 Créer et initialiser ton espace de travail

La première étape consiste à créer le répertoire de travail tod_tf2, dans lequel seront créés tous les fichiers, et de te positionner dans ce répertoire qui sera le dossier racine du projet. :

(tf2) jlc@pikatchou $ cd <quelque_part>   # choisis le répertoire où créer `tod_tf2`, par exemple "cd ~/catkins_ws"
(tf2) jlc@pikatchou $ mkdir tod_tf2
(tf2) jlc@pikatchou $ cd tod_tf2/

📥 Ensuite, tu clones le dépôt github cjlux/tod_tf2_tools.git et tu copies les fichiers *.py et *.ipynb du dossier tod_tf2_tools dans le dossier tod_tf2 :

# From tod_tf2/
(tf2) jlc@pikatchou $ git clone https://github.com/cjlux/tod_tf2_tools.git
(tf2) jlc@pikatchou $ cp tod_tf2_tools/*.py .
(tf2) jlc@pikatchou $ cp tod_tf2_tools/*.ipynb .

2.2 Cloner le dépôt tensorflow/models

📥 Dans le dossier de travail tod_tf2 clone le dépôt github tensorflow/models (~ 635 Mo) :

# From tod_tf2/
(tf2) jlc@pikatchou $ git clone https://github.com/tensorflow/models.git

Tu obtiens un dossier models. L’API TOD est dans le dossier models/research/object_detection :

(tf2) jlc@pikatchou $ tree -d -L 2 .
.
└── models
    ├── community
    ├── official
    ├── orbit
    └── research

📥 Complète ton installation avec quelques paquets Python utiles pour le travail avec l’API TOD :

(tf2) jlc@pikatchou $ conda install cython contextlib2 pillow lxml
(tf2) jlc@pikatchou $ pip install labelimg rospkg

Mets à jour la variable d’environnement PYTHONPATH en ajoutant à la fin du fichier ~/.bashrc les deux lignes :

export TOD_ROOT="<chemin absolu du dossier tod_tf2>"
export PYTHONPATH=$TOD_ROOT/models:$TOD_ROOT/models/research:$PYTHONPATH

remplace "<chemin absolu du dossier tod_tf2>" par le chemin absolu du dossier tod_tf2 sur ta machine.

jlc@pikatchou $ conda activate tf2
(tf2) jlc@pikatchou $

2.3 Installer les outils protobuf

L’API native TOD utilise des fichiers *.proto pour la configuration des modèles et le stockage des paramètres d’entraînement. Ces fichiers doivent être traduits en fichiers *.py afin que l’API Python puisse fonctionner correctement :

(tf2) jlc@pikatchou $ sudo apt install protobuf-compiler
# From tod_tf2/models/research/
(tf2) jlc@pikatchou $ protoc object_detection/protos/*.proto  --python_out=.

Cette commande travaille de façon muette.

2.4 Installer l’API COCO

COCO est une banque de données destinée à alimenter les algorithmes de détection d’objets, de segmentation…
Voir cocodataset.org pour les tutoriels, publications…

📥 Pour installer l’API Python de COCO, clone le site cocoapi.git (~ 15 Mo) dans le dossier /tmp, tape la commande make dans le dossier cocoapi/PythonAPI, puis recopie le dossier pycococtools dans ton dossier .../models/research/ :

(tf2) jlc@pikatchou $ cd /tmp
(tf2) jlc@pikatchou $ git clone  https://github.com/cocodataset/cocoapi.git
(tf2) jlc@pikatchou $ cd cocoapi/PythonAPI/
(tf2) jlc@pikatchou $ make
(tf2) jlc@pikatchou $ cp -r pycocotools/ <chemin absolu du dossier tod_tf2>/models/research/

remplace "<chemin absolu du dossier tod_tf2>" par le chemin absolu du dossier tod_tf2 sur ta machine (par exemple ~/catkins_ws/tod_tf2).

2.5 Installer le package object_detection

Pour finir l’installation, place-toi dans le dossier models/research/ et tape les commandes :

# From tod_tf2/models/research/
(tf2) jlc@pikatchou $ cp object_detection/packages/tf2/setup.py .
(tf2) jlc@pikatchou $ python setup.py build
(tf2) jlc@pikatchou $ pip install .

2.6 Tester l’installation de l’API TOD

Pour tester ton installation de l’API TOD, place-toi dans le dossier models/research/ et tape la commande :

# From within tod_tf2/models/research/
(tf2) jlc@pikatchou $ python object_detection/builders/model_builder_tf2_test.py

Le programme déroule toute une série de tests et doit se terminer par un OK sans fiare apparaître d’erreur :

...
[       OK ] ModelBuilderTF2Test.test_invalid_second_stage_batch_size
[ RUN      ] ModelBuilderTF2Test.test_session
[  SKIPPED ] ModelBuilderTF2Test.test_session
[ RUN      ] ModelBuilderTF2Test.test_unknown_faster_rcnn_feature_extractor
INFO:tensorflow:time(__main__.ModelBuilderTF2Test.test_unknown_faster_rcnn_feature_extractor): 0.0s
I0505 18:19:38.639148 140634691176256 test_util.py:2075] time(__main__.ModelBuilderTF2Test.test_unknown_faster_rcnn_feature_extractor): 0.0s
[       OK ] ModelBuilderTF2Test.test_unknown_faster_rcnn_feature_extractor
[ RUN      ] ModelBuilderTF2Test.test_unknown_meta_architecture
INFO:tensorflow:time(__main__.ModelBuilderTF2Test.test_unknown_meta_architecture): 0.0s
I0505 18:19:38.640017 140634691176256 test_util.py:2075] time(__main__.ModelBuilderTF2Test.test_unknown_meta_architecture): 0.0s
[       OK ] ModelBuilderTF2Test.test_unknown_meta_architecture
[ RUN      ] ModelBuilderTF2Test.test_unknown_ssd_feature_extractor
INFO:tensorflow:time(__main__.ModelBuilderTF2Test.test_unknown_ssd_feature_extractor): 0.0s
I0505 18:19:38.641987 140634691176256 test_util.py:2075] time(__main__.ModelBuilderTF2Test.test_unknown_ssd_feature_extractor): 0.0s
[       OK ] ModelBuilderTF2Test.test_unknown_ssd_feature_extractor
----------------------------------------------------------------------
Ran 21 tests in 53.105s

OK (skipped=1)

Pour finir, tu peux vérifier l’installation en utilisant le notebook IPython object_detection_tutorial.ipynb présent dans le dossier tod_tf2.
(note : c’est une copie du notebook tod_tf2/models/research/object_detection/colab_tutorials/object_detection_tutorial.ipynb dans laquelle on a enlevé les cellules d’installation de l’API_TOD et quelques autres cellules qui peuvent générer des erreurs…).

La suite du travail se décompose ainsi :

3. Compléter l’arborescence de travail

L’arborescence générique proposée est la suivante :

tod_tf2
├── images
│   └──<project>
│       ├── test
│       │   └── *.jpg, *.png ... *.xml
│       ├── train
│       │   └── *.jpg, *.png ... *.xml
│       └── *.csv
├── pre_trained
│	└── <pre_trained-network>
├── training
│   └──<project>
│       ├── <pre_trained-network>
│       ├── train.record
│       ├── test.record
│       └── label_map.txt
└── models
    └── research
        └── object_detection

Pour la détection des faces des cubes dans les images de la caméra du robot, le dossier <project> sera nommé faces_cubes, ce qui donne l’arborescence de travail :

tod_tf2
├── images
│   └── faces_cubes
│       ├── test
│       │   └── *.jpg, *.png ... *.xml
│       ├── train
│       │   └── *.jpg, *.png ... *.xml
│       └── *.csv
├── pre_trained
│	└── <pre_trained-network>
├── training
│   └── faces_cubes
│       ├─── <pre_trained-network>
│       ├── train.record
│       ├── test.record
│       └── label_map.txt
└── models
    └── research
        └── object_detection

Quelques commandes shell suffisent pour créer les premiers niveaux de cette arborescence :

# From within tod_tf2
(tf2) jlc@pikatchou $ mkdir -p images/faces_cubes/test
(tf2) jlc@pikatchou $ mkdir -p images/faces_cubes/train
(tf2) jlc@pikatchou $ mkdir pre_trained
(tf2) jlc@pikatchou $ mkdir -p training/faces_cubes

Vérifions :

# From within tod_tf2
(tf2) jlc@pikatchou $ tree -d . -I models
.
├── images
│   └── faces_cubes
│       ├── test
│       └── train
├── pre_trained
├── tod_tf2_tools
└── training
    └── faces_cubes

4. Télécharger le réseau pré-entraîné

Plusieurs familles de réseaux dédiés à la détection d’objets sont proposés sur le site TensorFlow 2 Detection Model Zoo, parmi lesquelles :

La différence entre “Faster R-CNN” et SSD est qu’avec R-CNN on réalise une classification sur chacune des 2000 fenêtres générées par l’algorithme de recherche ciblée, alors qu’avec SSD on cherche à prédire la classe ET la fenêtre de l’objet en même temps. Cela rend SSD plus rapide que “Faster R-CNN”, mais également moins précis.

Dans le tableau du site TensorFlow 2 Detection Model Zoo, les performances des différents réseaux sont exprimées en COCO mAP (Mean Average Precision), métrique couramment utilisée pour mesurer la précision d’un modèle de détection d’objets. Elle consiste à mesurer la proportion de détections réussies sur des images déjà annotées du dataset COCO (Common Object in CONtext) qui contient 200 000 images annotées avec 80 objets différents. Cette mesure sert de référence pour comparer la précision de différentes architectures de détection d’objets (plus d’informations sur mAP dans la lecture [2]).

📥 Pour le travail de détection des faces des cubes dans les images fournies par la caméra du robot Ergo Jr tu peux télécharger le réseau Faster R-CNN ResNet50 V1 640x640 sur le site TensorFlow 2 Detection Model Zoo (~203 Mo).

Une fois téléchargée, il faut extraire l’archive TGZ au bon endroit dans l’arborescence de travail :

# From within tod_tf2/
(tf2) jlc@pikatchou $ tar xvzf ~/Téléchargements/faster_rcnn_resnet50_v1_640x640_coco17_tpu-8.tar.gz -C pre_trained

puis créer le dossier correspondant faster_rcnn_resnet50_v1_640x640_coco17_tpu-8 dans le dossier training/faces_cubes :

# From within tod_tf2/
(tf2) jlc@pikatchou $ mkdir training/faces_cubes/faster_rcnn_resnet50_v1_640x640_coco17_tpu-8

On vérifie :

# From within tod_tf2/
(tf2) jlc@pikatchou $ tree -d pre_trained
pre_trained
└── faster_rcnn_resnet50_v1_640x640_coco17_tpu-8
    ├── checkpoint
    └── saved_model
        └── variables
        
(tf2) jlc@pikatchou $ tree -d training
training
└── faces_cubes
    └── faster_rcnn_resnet50_v1_640x640_coco17_tpu-8

5. Créer les données pour l’apprentissage supervisé

Cette étape du travail comporte cinq tâches :

  1. Créer des images avec la caméra du robot -> fichiers *.jpg, *.png
  2. Annoter les images avec le logiciel labelImg -> fichiers *.xml
  3. Convertir les fichiers annotés XML au format CSV
  4. Convertir les fichiers annotés CSV au format tensorflow record
  5. Créer le fichier label_map.pbtxt qui contient les labels des objets à reconnaître.

5.1 Créer les images avec la caméra du robot

Les images des faces des cubes peuvent être obtenues en utilisant le service ROS /get_image proposé par le robot Poppy Ergo Jr.

image001.png image002.png
image1 image2

🤖 Rappels : lancement du ROS Master et des services ROS sur le robot :

(tf2) jlc@pikatchou: $ ssh pi@poppy.local
pi@poppy.local password:
...

pi@poppy:~ $ env|grep ROS_MASTER
ROS_MASTER_URI=http://poppy.local:11311
pi@poppy:~ $ roslaunch poppy_controllers control.launch
...

💻 Et maintenant dans un terminal sur ton PC, avec l’EVP (tf2) désactivé :

(tf2) jlc@pikatchou: $ env|grep ROS_MASTER
ROS_MASTER_URI=http://poppy.local:11311

🐍 Tu peux utiliser le programme Python get_image_from_robot.py du dossier tod_tf2 pour enregistrer les images des cubes dans des fichiers nommées imagesxxx.png (xxx = 001, 002…). Un appui sur une touche clavier permet de passer d’une image à l’autre, un appui sur la touche Q permet de quitter le programme :

import cv2, rospy
from poppy_controllers.srv import GetImage
from cv_bridge import CvBridge

i=1
while True:
    get_image = rospy.ServiceProxy("get_image", GetImage)
    response  = get_image()
    bridge    = CvBridge()
    image     = bridge.imgmsg_to_cv2(response.image)
    cv2.imwrite(f"image{i:03d}.png", image)
    cv2.imshow("Poppy camera", image)
    key = cv2.waitKey(0)
    if key==ord('q') or key==ord("Q"): break
    cv2.destroyAllWindows()
    i += 1
cv2.destroyAllWindows()

📍 En cas de conflit grave “ROS / EVP tf2 / PyQT” en utilisant le programme get_image_from_robot.py tu peux désactiver temporairement l’EVP tf2 :

Chaque équipe doit faire une dizaine d’images en variant les faces des cubes visibles, puis les images pourront être partagées sur un serveur pour servir à toutes les équipes.

Une fois collectées toutes les images, il faut mettre environ 90 % des images dans le dossier images\faces_cubes\train et le reste dans le dossier images\faces_cubes\test.

5.2 Annoter les images avec le logiciel labelImg

L’annotation des images peut être faite de façon très simple avec le logiciel labelImg. C’est une étape du travail qui prend du temps et qui peut être réalisée à plusieurs en se répartissant les images à annoter…

L’installation du module Python labelImg faite dans l’EVP tf2 (cf section 2.) permet de lancer le logiciel labelImg en tapant :

(tf2) jlc@pikatchou:~ $ labelImg

Utilise les boutons [Open Dir] et [Change Save Dir] pour te positionner la lecture ET l’écriture des fichiers dans le dossier images/face_cubes/train/.
La première image est automatiquement chargée dans l’interface graphique :

labelImg_2.png

Pour chaque image, tu dois annoter les objets à reconnaître :

5.3 Convertir les fichiers XML annotés au format CSV

Cette étape permet de synthétiser dans un fichier CSV unique les données d’apprentissage contenues dans les différents fichiers XML crées à l’étape d’annotation. Le programme xml_to_csv_tt.py permet de générer les deux fichiers CSV correspondant aux données d’apprentissage et de test.
Depuis le dossier tod_tf2 tape la commande suivante :

# From within tod_tf2
(tf2) jlc@pikatchou:~ $ python xml_to_csv_tt.py -p faces_cubes
Successfully converted xml data in file <images/faces_cubes/train_labels.csv>.
Successfully converted xml data in file <images/faces_cubes/test_labels.csv>.

Les fichiers train_labels.csv et test_labels.csv sont créés dans le dossier images/faces_cubes/.

5.4 Convertir les fichiers CSV annotés au format tfrecord

Pour cette étape, on utilise le programme generate_tfrecord_tt.py.
Depuis le dossier tod_tf2 tape la commande :

# From within tod_tf2
(tf2) jlc@pikatchou:~ $ python generate_tfrecord_tt.py --project faces_cubes
Successfully created the TFRecord file: ./training/faces_cubes/train.record
Successfully created the TFRecord file: ./training/faces_cubes/test.record

Avec cette commande tu viens de créer les 2 fichiers train.record et test.record dans le dossier training/faces_cubes : ce sont les fichiers qui serviront pour l’entraînement et l’évaluation du réseau.

5.5 Créer le fichier label_map.pbtxt

La dernière étape consiste a créer le fichier label_map.pbtxt dans le dossier training/faces_cubes.

Ce fichier décrit la « carte des labels » (label map) nécessaire à l’entraînement du réseau. La carte des labels permet de connaître l’ID (nombre entier) associé à chaque étiquette (label) identifiant les objets à reconnaître. La structure type du fichier est la suivante :

 item {
   id: 1
   name: 'objet_1'
 }
 item {
   id: 2
   name: 'objet_2'
 }
 ...

Pour le projet face_cubes, le contenu du fichier training/faces_cubes/label_map.pbtxt à créer est :

 item {
   id: 1
   name: 'one'
 }
 item {
   id: 2
   name: 'two'
 }

6. Lancer l’entraînement supervisé du réseau pré-entraîné

Ce travail se décompose en plusieurs étapes :

  1. Modifier le fichier de configuration du réseau pré-entraîné pour décrire la configuration d’entraînement.
  2. Lancer l’entraînement supervisé.
  3. Exporter les poids du réseau entrainé dans un format utilisable.

6.1 Modifier le fichier de configuration

C’est la dernière étape avant de lancer l’entraînement…

paramètre Description Valeur initiale valeur à donner explication
010 num_classes nombre de classe d’objets 90 2 les deux classes ‘one’ et ‘two’
077 max_detections_per_class nombre max de détection par classe 100 4 4 cubes
078 max_total_detections nombre max total de détections 100 4 4 cubes
093 batch_size nombre d’images à traiter en lot avant mise à jour des poids du réseau 64 1, 2,… une valeur trop élevée risque de faire dépasser la capacité mémoire RAM de ta machine… à régler en fonction de la quantité de RAM de ta machine.
097 num_steps Nombre max d’itérations d’entraînement 25000 1000 une valeur trop grande donne des temps de calcul prohibitifs et un risque de sur-entraînement
113 fine_tune_checkpoint chemin des fichiers de sauvegarde des poids du réseau pré-entraîné “PATH_TO_BE_
CONFIGURED”
“pre_trained/faster_rcnn_resnet50_v1_
640x640_coco17_tpu-8/checkpoint/ckpt-0”
se termine par /ckpt-0 qui est le préfixe des fichiers dans le dossier .../checkpoint/
114 fine_tune_checkpoint_type Choix de l’algorithme : “classification” ou “detection” “classification” “detection” on veut faire de la detection d’objets
120 max_number_of_boxes Nombre max de boîtes englobantes dans chaque image 100 4 les faces des cubes sur une image
122 use_bfloat16 true pour les architectures TPU, false pour CPU true false
126 label_map_path chemin du fichier des labels “PATH_TO_BE_
CONFIGURED”
“training/faces_cubes/label_map.pbtxt” utilisé pour l’entraînement
128 input_path fichier des données d’entrée d’entraînement au format tfrecord “PATH_TO_BE_
CONFIGURED”
“training/faces_cubes/train.record” utilisé pour l’entraînement
139 label_map_path chemin du fichier des labels “PATH_TO_BE_
CONFIGURED”
“training/faces_cubes/label_map.pbtxt” utilisé pour l’évaluation
128 input_path fichier des données d’entrée de test au format tfrecord “PATH_TO_BE_
CONFIGURED”
“training/faces_cubes/test.record” utilisé pour l’évaluation

6.2 Lancer l’entraînement

# From within tod_tf2
(tf2) jlc@pikatchou $ python model_main_tf2.py --model_dir=training/faces_cubes/faster_rcnn_resnet50_v1_640x640_coco17_tpu-8/checkpoint1  --pipeline_config_path=training/faces_cubes/faster_rcnn_resnet50_v1_640x640_coco17_tpu-8/pipeline.config

Les fichiers des poids entraînés seront écrits dans le dossier .../faster_rcnn_resnet50_v1_640x640_coco17_tpu-8/checkpoint1 : si tu relances l’entraînement, tu peux utiliser .../checkpoint2, .../checkpoint3 pour séparer des essais successifs.

Le programme Python lancé est très verbeux…
au bout d’un temps qui peut être assez long (plusieurs minutes avec un petit CPU), les logs de l’entraînement apparaissent à l’écran :

...
...
W0507 00:24:41.010936 140206908888832 deprecation.py:531] From /home/jlc/miniconda3/envs/tf2/lib/python3.8/site-packages/tensorflow/python/util/deprecation.py:605: calling map_fn_v2 (from tensorflow.python.ops.map_fn) with dtype is deprecated and will be removed in a future version.
Instructions for updating:
Use fn_output_signature instead
INFO:tensorflow:Step 100 per-step time 22.002s loss=0.825
I0507 01:01:11.942076 140208909420352 model_lib_v2.py:676] Step 100 per-step time 22.002s loss=0.825
INFO:tensorflow:Step 200 per-step time 20.926s loss=0.813
I0507 01:36:04.090147 140208909420352 model_lib_v2.py:676] Step 200 per-step time 20.926s loss=0.813
INFO:tensorflow:Step 300 per-step time 20.803s loss=0.801
I0507 02:10:44.351419 140208909420352 model_lib_v2.py:676] Step 300 per-step time 20.803s loss=0.801
INFO:tensorflow:Step 400 per-step time 20.946s loss=0.812
I0507 02:45:38.927271 140208909420352 model_lib_v2.py:676] Step 400 per-step time 20.946s loss=0.812
INFO:tensorflow:Step 500 per-step time 20.960s loss=0.794
I0507 03:20:34.990385 140208909420352 model_lib_v2.py:676] Step 500 per-step time 20.960s loss=0.794
INFO:tensorflow:Step 600 per-step time 21.045s loss=0.802
I0507 03:55:39.516442 140208909420352 model_lib_v2.py:676] Step 600 per-step time 21.045s loss=0.802
INFO:tensorflow:Step 700 per-step time 20.863s loss=0.786
I0507 04:30:25.868283 140208909420352 model_lib_v2.py:676] Step 700 per-step time 20.863s loss=0.786
INFO:tensorflow:Step 800 per-step time 20.744s loss=0.799
I0507 05:05:00.163027 140208909420352 model_lib_v2.py:676] Step 800 per-step time 20.744s loss=0.799
INFO:tensorflow:Step 900 per-step time 20.825s loss=0.837
I0507 05:39:42.691898 140208909420352 model_lib_v2.py:676] Step 900 per-step time 20.825s loss=0.837
INFO:tensorflow:Step 1000 per-step time 20.789s loss=0.778
I0507 06:14:21.503472 140208909420352 model_lib_v2.py:676] Step 1000 per-step time 20.789s loss=0.778

Dans l’exemple ci-dessus, on voit des logs tous les 100 pas, avec environ 20 secondes par pas, soit environ 35 minutes entre chaque affichage et environ 6h de calcul pour les 1000 pas.

En cas d’arrêt brutal du programme avec le message “Processus arrêté”, ne pas hésiter à diminer la valeur du paramètre batch_size jusquà 2 voire 1 si nécessaire….
Même avec un batch_size de 2, le processus Python peut nécessiter jusqu’à 2 ou 3 Go de RAM pour lui tout seul, ce qui peut mettre certains portables en difficulté…

Une fois l’entraînement terminé tu peux analyser les statistiques d’entraînement avec tensorboard en tapant la commande :

# From within tod_tf2
(tf2) jlc@pikatchou:~ $ tensorboard --logdir=training/faces_cubes/faster_rcnn_resnet50_v1_640x640_coco17_tpu-8/checkpoint1/train
Serving TensorBoard on localhost; to expose to the network, use a proxy or pass --bind_all
TensorBoard 2.4.0 at http://localhost:6006/ (Press CTRL+C to quit)
...

tensorflow lance un serveur HHTP en local sur ta machine, et tu peux ouvrir la page http:// avec un navigateur pour voir les courbes d’analyse en faisant CTRL + clic avec le curseur de la souris positionné sur le mot http://localhost:6006/ :

tensorflow

Le logiciel tensorboard permet d’examiner l’évolution de statistiques caractéristiques de l’apprentissage.

6.3 Exporter les poids du réseau entraîné

On utilise le script Python exporter_main_v2.py du dossier models/reasearch/object_detection/ pour extraire le graph d’inférence entraîné et le sauvegarder dans un fichier saved_model.pb qui pourra être rechargé ultérieurement pour exploiter le réseau entraîneé :

# From within tod_tf2
(tf2) jlc@pikatchou $ cp models/research/object_detection/exporter_main_v2.py .
(tf2) jlc@pikatchou $ python exporter_main_v2.py --input_type image_tensor --pipeline_config_path training/faces_cubes/faster_rcnn_resnet50_v1_640x640_coco17_tpu-8/pipeline.config --trained_checkpoint_dir training/faces_cubes/faster_rcnn_resnet50_v1_640x640_coco17_tpu-8/checkpoint1 --output_directory training/faces_cubes/faster_rcnn_resnet50_v1_640x640_coco17_tpu-8/saved_model1

Le script Python créé le fichier saved_model.pb dans le dossier .../faster_rcnn_resnet50_v1_640x640_coco17_tpu-8/saved_model1/saved_model :

# From within tod_tf2
(tf2) jlc@pikatchou:~ $ tree training/
training/
└── faces_cubes
    └── faster_rcnn_resnet50_v1_640x640_coco17_tpu-8
        ├── checkpoint1
        │   ├── checkpoint
        │   ├── ckpt-1.data-00000-of-00001
        │   ├── ckpt-1.index
        │   └── train
        │       └── events.out.tfevents.1620391994.pikatchou.30554.1504.v2
        ├── pipeline.config
        ├── saved_model1
        │   ├── checkpoint
        │   │   ├── checkpoint
        │   │   ├── ckpt-0.data-00000-of-00001
        │   │   └── ckpt-0.index
        │   ├── pipeline.config
        │   └── saved_model
        │       ├── assets
        │       ├── saved_model.pb
        │       └── variables
        │           ├── variables.data-00000-of-00001
        │           └── variables.index

7. Évaluation du réseau entraîné

On va vérifier que le réseau entraîné est bien capable de détecter les faces des cubes en discriminant correctement les numéros écrits sur les faces.

Le script Python plot_object_detection_saved_model.py permet d’exploiter le réseau entraîné sur des images, les arguments sont :

Par exemple pour faire la détection des cubes des images de test avec le réseau qu’on vient d’entraîner :

# From within tod_tf2
(tf2) jlc@pikatchou: $ python plot_object_detection_saved_model.py -p faces_cubes -s training/faces_cubes/faster_rcnn_resnet50_v1_640x640_coco17_tpu-8/saved_model1/saved_model -i images/faces_cubes/test/ -n 4

Loading model...Done! Took 11.77 seconds

Running inference for images/faces_cubes/test/image016.png... [2 1 1 2]
[0.999408   0.99929774 0.9985869  0.99794155]
[[0.4046488  0.13016616 0.6338345  0.31058723]
 [0.40798646 0.56277716 0.63340956 0.7373474 ]
 [0.40612057 0.3360289  0.63908    0.5120028 ]
 [0.40730068 0.7692113  0.6340802  0.9632611 ]]

Running inference for images/faces_cubes/test/image018.png... [2 2 1 1]
[0.9995958  0.99956626 0.99756575 0.9960402 ]
[[0.4140944  0.62948036 0.6388739  0.7997428 ]
 [0.41462958 0.40451866 0.6399791  0.5834095 ]
 [0.41448513 0.19922832 0.63370967 0.36855492]
 [0.40865567 0.         0.63875306 0.16509269]]

Running inference for images/faces_cubes/test/image019.png... [2 2 1 1]
[0.99956614 0.99939644 0.9977343  0.99497354]
[[0.41152024 0.43164197 0.6439534  0.6055011 ]
 [0.41524586 0.65218127 0.6408151  0.8317957 ]
 [0.40619218 0.20989983 0.6326463  0.40074167]
 [0.40634462 0.         0.6389088  0.18785618]]

Running inference for images/faces_cubes/test/image017.png... [2 2 1 1]
[0.999482   0.99903905 0.9982924  0.99810815]
[[0.4101084  0.70229053 0.63589627 0.8758344 ]
 [0.4053984  0.05132582 0.6378698  0.23081933]
 [0.41257906 0.49104023 0.63610333 0.66249573]
 [0.40499112 0.29253355 0.63419634 0.46947986]]

Pour chaque image traitée on affiche ici :

Les images produites sont :

image016.png image018.png image019.png image017.png
1 2 3 4

8. Intégration

Une fois le réseau entraîné et évalué, si les résultats sont bons, “il ne reste plus qu’à” créer le fichier nn.py pour réaliser les traitements nécessaires à l’exploitation du réseau entraîné pour ton projet : le but est d’intégrer le réseau de neurones nn dans le contexte ROS :

intégration ROS

  1. Attendre que le paramètre ROS takeImage passe à True et le remettre à False
  2. Obtenir le fichier de l’image prise par la caméra du robot grâce au service ROS /get_image
  3. Traiter l’image pour obtenir les labels et les boîtes englobantes des faces des cubes (penser à remettre les cubes dans le bon ordre…)
  4. Et pour chaque cube : donner au paramètre ROSlabel la valeur du label du cube, mettre le paramètre ROS RobotReady à False et attendre que le paramètre rOS RobotReady repasse à True