Ce projet contient une description en français et en anglais.
Le but de ce projet est de reconnaitre les aliments d’une assiette à partir d’une photographie de ceux-ci. Il s’inscrit dans un cadre plus large visant à fournir un outil aux diabétiques leur permettant d’avoir une estimation des glucides de leur repas à partir d’une simple photographie depuis leur téléphone.
L’intégralité du code est disponible ici.
- https://www.oreilly.com/ideas/object-detection-with-tensorflow
- http://androidkt.com/train-object-detection/
- https://github.com/datitran/raccoon_dataset
- https://medium.com/@WuStangDan/step-by-step-tensorflow-object-detection-api-tutorial-part-1-selecting-a-model-a02b6aabe39e
- https://cloud-annotations.github.io/training/object-detection/cli/index.html
- Recherche de datasets de nourriture et d'aliments
- Recherches et compréhension des différents algorithmes
- Familiarisation avec le dataset Food-101
- Mise en place d'une instance IBM Cloud Storage
- Upload d'une partie du dataset sur celle-ci
- Utilisation de l'outil Cloud Annotation Tool pour annoter ces images
- Entrainement d'un modèle SSD MobileNet sur une instance IBM Cloud Computing
- Récupération du modèle
- Installation et configuration d'une application ReactJS pour tester le résultat sur ma webcam
Le dataset était beaucoup trop petit pour avoir des résultats pertinents. De plus, le choix de pouvoir détecter les aliments à partir d'une vidéo (ou webcam) n'est pas pertinent, on n'a pas besoin de sacrifier la performance pour augmenter le temps de calcul.
J'ai extrait environ 15 classes du dataset Food101, en choississant celles qui avaient beaucoup de chance de contenir d'autres classes dans leurs images, afin de gagner du temps de scrapping et de labelisation (ex: burger, ketchup et fries souvent ensemble).
De plus, j'ai scrappé Google Images pour obtenir des classes personnalisées comme "salad", "ketchup" ou "bread" à l'aide de l'outil de téléchargement Bulk Image Downloader.
J'ai donc obtenu environ 1900 images pour 19 classes, soit plus ou moins 100 images par classe. J'ai ensuite redimensionné celles-ci en format 250x250 pixels.
Annotation du dataset avec l'outil LabelImg au format PascalVOC.
Suite à de nombreux problèmes dans l'installation et configuration des outils de compilation de Tensorflow et de Python sous Windows, j'ai décidé de migrer sous Linux. J'ai donc mis en place une VM chez Amazon Web Services. VM de type g3.4xlarge, optimisée pour les calculs GPU (16 coeurs, 47 ECU et 122Gio de mémoire). Ensuite mise en place des dépendances et de Tensorflow.
- Transfert du dataset vers l'instance AWS
scp -i <key_path> -r <user>@<server>:<remote_path> <local_path>
- Convertion des annotations du format PascalVOC vers un format CSV
python voc_to_csv.py
- Mise en place d'un script de séparation des ensembles de test et d'entrainement
python labels_test_train_split.py
- Compilation du dataset en un fichier tfrecord, à réaliser deux fois pour les subsets d'entrainement et de test.
python generate_tfrecord.py
- Création du fichier de mappage des classes
On utilise la méthode du transfer learning pour initialiser notre modèle à partir d'un modèle pré-entrainé sur des énormes quantités de données.
Nous avons le choix entre les modèles "légers" et plus "approximatifs", et des modèles plus lents et "précis". J'ai choisi la seconde catégorie suite à ma première expérience décrite plus haut. Le modèle est Inception v2 entrainé sur le dataset Coco. On a fait le choix de reconnaitre le bon aliment en plus de temps de calcul.
- On clone le projet à partir du GitHub de Tensorflow
- On l'intègre à notre projet et on configure le pipeline
On lance l'entrainement
python object_detection/model_main.py \
--pipeline_config_path=training/inception_v2.config \
--model_dir=<RESULT_MODEL_PATH>/ \
--num_train_steps=<NUM_TRAIN_STEP> \
--sample_1_of_n_eval_examples=1 \
--alsologtostderr
On supervise l'entrainement avec TensorBoard (évaluation jobs).
# ssh into the server and tunnel the ports
ssh -L 127.0.0.1:<local_port>:127.0.0.1:<remote_port> <user>@<server>
# launch tensorboard
cd path/to/project
tensorboard log_dir=.
Enfin on sauvegarde le modèle en tant que fichier .pb.
python export_inference_graph.py
--input_type image_tensor
--pipeline_config_path training/inception_v2.config
--trained_checkpoint_prefix <last_checkpoint_path>
--output_directory <out_directory>
Une fois le modèle exporté en format JSON, on obtient un dossier avec les éléments model.json
(configuration du modèle), group1-shardXofX.bin
(poids), labels.json
(classes).
J'ai simplement ajouté les fichiers statiques obtenus précedemment sur l'API de mon site personnel pour qu'ils soient disponibles de n'importe où. Cette API est developpée en TypeScript, grâce au framework NodeJS, sur un modèle similaire à celui-là.
La partie client de l'application web est inspiré de ce projet. Je n'ai malheureusement pas réussi à faire marcher React avec mon modèle, suite à de nombreux problèmes sur le formattage des images et des tensors.
J'ai donc utilisé le modèle MobileNet v2 pré-entrainé par Tensorflow sur le dataset Coco.
L'application client est développé en ReactJS, elle permet de faire des prédictions avec ce modèle à partir de n'importe quelle image.
L'utilisateur peut charger une image depuis ses fichiers localement, où depuis des images pré-rentrées. Grâce à TensorflowJS, tous les calculs sont fait localement, aucune image n'est envoyée sur le serveur.
- Mise en place d'une API servant notre modèle
- Refactor l'architecture du projet pour respecter les bonnes pratiques
- Ajouter des classes à reconnaitre
J'ai rencontré beaucoup de difficultés à mettre en place un environnement de travail sous Windows, de plus la création d'un dataset est un processus très long et répétitif.
J'ai pris beaucoup de plaisir à mettre en place un dataset unique, et à le coupler à un modèle de Deep Learning. De plus, malgré beaucoup d'optimisations possibles, le modèle reconnait déjà ses premières images.
Georges Cosson : LinkedIn - GitHub
MIT License, Copyright (c) 2019 G. Cosson
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.