Rapport de projet

Détection de chute de personnes

Broutin Aurélien - Cochet Antoine - Haelewyn Jérémy

UTBM - IN54 - 2019

Sommaire

  1. Introduction
  2. Jeu de données
  3. Keras et les réseaux de neurones (VGGNet, ResNet, ...)
  4. Résultats
  5. Améliorations
  6. Conclusion
  7. Sources

  1. Introduction

Objectif

Le but de notre projet réside dans la détection de chute de personne via un réseau de neurones.

Grâce à un jeu de données, composé de vidéos de personnes marchant et chutant, nous entraînons notre réseau de neurones initialement configuré. Celui-ci va apprendre les différences lorsqu’une personne est debout et lorsque celle-ci chute. Pour se faire, nous avons choisi d’utiliser Keras et un réseau de neurones convolutionnel avec le modèle VGGNet légèrement modifié dans un premier temps puis ResNet dans un second temps.

Keras est une librairie de deep-learning pour Python, interfaçable avec TensorFlow (framework de machine learning open source). Elle permet d’utiliser les réseaux de neurones convolutifs et/ou récurrents mais également d’utiliser de façon transparente le CPU ou le GPU.

Pourquoi le machine learning ?

Nous avons choisi d’utiliser le machine learning car c’est une technologie intéressante que nous avons souhaité apprendre. De plus, l’utilisation de celle-ci concordait avec les besoins du projet.
Durant la fin de l’année, nous avons même pu constater qu’un TD était réservé pour apprendre les bases de l’utilisation d’un réseau de neurones.

Conditions nécessaires

Notre projet a été réalisé avec les outils suivants :

  • Python version 3.6.7
  • OpenCV version 3.4.4
  • Keras version 2.2.4
  • Tensorflow version 1.12.0
  • Scikit-learn version 0.20.2
  • Matplotlib version 3.0.2
  • Imutils version 0.5.2
  • Numpy version 1.15.4
  • Nous avons également utilisé Anaconda afin de faciliter l’installation de la plupart de ces outils.


    1. Jeu de données

    Notre base pour l'entraînement du réseau de neurone est composée de plusieurs vidéos de chute avec différents angles de vue.

    Chaque vidéo possède un fichier texte associé. Et chaque fichier texte nous donne les données suivantes :

    • Un intervalle de frames qui correspond aux frames où l’individu est en train de tomber
    • Puis une table qui contient la hauteur, largeur et les coordonnées du centre de la bounding box de l’individu pour chaque frame de la vidéo

    Voici un exemple :

    Cependant, pour notre réseau de neurones, nous avons besoin d’images. Nous avons donc créé un script permettant de découper chaque vidéo en images et de les ranger dans un dossier indiquant leur classe: normal, en train de tomber, tombé.
    Pour garder un équilibre et éviter le “biais” lors de l’apprentissage du réseau de neurones, nous avons supprimé certaines images afin d’obtenir un nombre identique d’images de chaque état, et particulièrement pour les états tombé et normal.

    De plus, afin d’agrandir notre jeu de données, nous avons pensé à créer un script capable de récupérer une image et réaliser une rotation horizontale de celle-ci, puis l’ajouter à notre dataset. Ainsi, nous avons pour doubler la quantité de données pour nourrir notre réseau de neurones, et avoir des images qui étaient toujours valides.


    1. Keras et les réseaux de neurones (VGGNet, ResNet, ...)

    Le but de notre réseau de neurones est de traiter, d’analyser et de détecter la chute d’une personne. Pour se faire, nous allons entraîner un réseau de neurones afin d’apprendre le modèle d’une chute.

    Nous allons tout d’abord vous présenter la méthode que nous avons utilisé afin de découper notre jeu de données. Par la suite nous introduirons le modèle VGGNet qui a été notre la base de notre premier réseau de neurones, puis le modèle ResNet sur lequel nous avons expérimenté.

    Découpage du jeu de données et étiquetage

    Afin d’entraîner convenablement notre réseau, nous devons partager notre jeu de données en deux : un jeu d'entraînement et un jeu de test. Celui-ci d'entraînement servira directement à l’apprentissage du réseau de neurones, et le jeu de test à vérifier que celui-ci apprend correctement.

    Pour notre projet, nous avons décidé de consacrer 75% de notre jeu de données à l'entraînement et 25% aux tests.

    Grâce à Scikit-Learn, nous pouvons utiliser une fonction qui va permettre de mélanger aléatoirement notre jeu de données en deux :

    (trainX, testX, trainY, testY) = train_test_split(data, labels, test_size=0.25, random_state=42)

    Jusque là, le nom des classes est toujours représenté par une chaîne de caractères. Cependant, Keras n’accepte que les entiers. Nous avons donc utilisé une autre fonction du Scikit-Learn :

    lb = LabelBinarizer()
    #fit_transform va trouver chaque classe présente
    trainY = lb.fit_transform(trainY)
    #transform va appliquer le changement de nom de classe
    testY = lb.transform(testY)

    A la suite de ces appels de fonctions, le nom de chaque classe va être décrit différemment. Par exemple :

    [1,0,0] # correspond à la classe “normal”
    [0,1,0] # correspond à la classe “en train de tomber”
    [0,0,1] # correspond à la classe “tombé”

    Nous avons utilisé deux type de modèle d'entraînement : le VGGNet et le ResNet

    Ces deux architectures sont des CNN (Convolutional Neural Network). Ils consistent en un empilage multicouche de perceptrons, dont le but est de prétraiter de petites quantités d'informations.

    Une architecture de réseau de neurones convolutifs est formée par un empilement de couches de traitement :

    • la couche de convolution (CONV) qui traite les données d'une portion limitée de l'image (champ récepteur)
    • la couche de pooling (POOL), qui permet de compresser l'information en réduisant la taille de l'image intermédiaire (souvent par sous-échantillonnage)
    • la couche de correction, souvent appelée par abus « ReLU » en référence à la fonction d'activation (Unité de rectification linéaire)
    • la couche « entièrement connectée » (FC), qui est une couche de type perceptron
    • la couche de perte (LOSS)

    Ces couches sont empilées pour former l’architecture du réseau de neurones

    VGGNet
    Concernant le modèle VGGNet, voici l’empilement utilisé:

    Entre chaque couche ReLU et POOL, nous avons utilisé le “Batch Normalization”. Cela va servir à réduire le nombres d’epoch requis pour entraîner notre CNN.
    Le nombre d’epoch correspond au nombre de fois où l’on va entraîner notre réseau.

    Un epoch est donc une itération d’entraînement.
    Le batch size est le nombre de paquet d’image qui va être analysé dans un epoch.

    Puis, il reste la dernière couche Softmax. Celle-ci permet de retourner les probabilités de nos classes.

    Il ne nous reste plus qu’à entraîner notre réseau en choisissant un batch size et un nombre d’epoch.

    Pour ce modèle, nous avons essayé de nombreuses possibilités sur le nombre d’epoch et de batch size, en affinant en fonction des résultats, et nous avons gardé un modèle entraîné avec 75 epoch et une taille du batch de 32.

    ResNet

    Voici un exemple d’empilement de couche pour un residual neural network (réseau de neurones résiduel):

    Dans notre projet, l’architecture est la suivante :

    • Le premier bloc est une couche CONV avec 64 filtres
    • Le deuxième bloc comporte 3 blocs résiduels. Et chaque couche CONV dans chaque bloc residual possède 32,32 et 128 filtres respectivement.
    • Le troisième bloc comporte 4 blocs résiduels. Et chaque couche CONV dans chaque bloc possède 64,64 et 256 filtres respectivement.
    • Le quatrième bloc comporte 6 blocs résiduels. Et chaque couche CONV dans chaque bloc possède 128,128 et 512 filtres respectivement.

    L'empilage des couches CONV avec de petits filtres de pooling (plutôt un grand filtre) permet un traitement plus puissant, avec moins de paramètres. Cependant, avec l’inconvénient de demander plus de puissance de calcul.

    Une fois notre architecture configurée nous pouvons le compiler et entraîner notre réseau.

    Pour ce modèle, nous avons essayé de nombreuses possibilités sur le nombre d’epoch et de batch size, en affinant en fonction des résultats, et nous avons gardé un modèle entraîné avec 20 epoch.

    Le ResNet est l’architecture des réseaux de neurones la plus récente et la plus précise. Cependant, elle est également plus complexe que la VGG.

    Une fois entraîné, nous pouvons lui soumettre une image et lui demander si oui ou non une personne chute sur celle-ci, et nous répond avec un pourcentage de fiabilité.


    1. Résultats

    VGGNet

    Ci dessus, les courbes obtenues lors de l’apprentissage de notre réseau de neurones pour 50 epochs.

    L’erreur (loss) est calculée sur les phases d’apprentissage et de test. Elle permet de savoir dans quelle mesure le modèle se comporte pour ces deux phases. Au contraire de la précision (accuracy), l’erreur n’est pas un pourcentage mais une somme des erreurs faites pour chaque exemple de la base d’entraînement et de test.
    On peut constater que l’erreur de l’apprentissage (train_loss), qui correspond à la capacité à classifier correctement nos images d'entraînement, décroît très rapidement pour avoisiner les 0,1. L’erreur de notre partie de test (val_loss), obtient de meilleures résultats puisque qu’elle avoisine elle aussi rapidement les 0,5.
    La précision de l’entraînement (train_acc) augmente très vite pour atteindre le 97% aux alentours des 20 epochs. Celle de notre partie de test (val_acc) va être assez similaire mais comme pour l’erreur, elle va être légèrement supérieur, environs 98%.
    Cependant, nous pouvons obtenir des faux positifs, c’est-à-dire des images mals classifiées par notre réseau. Nous pouvons donc avoir une forte précision mais des erreurs.


    Sur cette photo, notre réseau détecte bien la chute, avec une précision de 71,95%. ResNet

    Dû au temps de calcul d’une epoch avec cette méthode, nous nous sommes arrêtés à 20.

    Nous pouvons constater que les erreurs d’apprentissage et de test finales sont légèrement inférieures à celle de VGGNet, un peu moins de 5%. Concernant la précision, nous avons obtenus pour l’entraînement et le test une précision de 100%.
    Cependant, lors de test du réseau avec d’autres vidéos, nous nous sommes aperçus que le réseau ne détectait pas correctement et n’est donc pas fiable pour notre projet.
    Cela est possiblement dû à une configuration non optimale du réseau de neurones et au paramétrage des couches.

    Fonctions d’erreur à optimiser

    Pour ces deux méthodes, nous avons choisi d’optimiser selon le choix de l’utilisateur, les fonctions d’erreur binary crossentropy et categorical crossentropy.
    La binary crossentropy est utilisé dans le cas où il n’y a que deux classes (normal et tombée) dans le réseau de neurones alors que la categorical crossentropy est utilisée lorsqu’il y a plus de deux classes (normal, tombe et tombé).


    1. Améliorations

    Long Short-Term Memory

    Lors de nos recherches, nous avons également trouvé l’emploi d’un LSTM (long short-term memory) additionné à un réseau de neurones convolutionnel.
    Cette architecture a été développée pour les problèmes de prédictions de séries chronologiques d’image et pour la génération de description textuelle à partir de séquences d’images.


    Ci-dessus, un exemple des possibilités d’un réseau de neurones convolutionnel additionné avec un LSTM.

    Jeu de données plus grand et plus varié

    Notre jeu de données possède uniquement 60 vidéos, dont 30 étant réalisées dans un bureau et 30 dans une maison, ainsi qu’une autre série de 20 vidéos. Cependant, pour avoir un réseau de neurones plus efficace, il faudrait diversifier les lieux et les angles de caméras.

    Une autre fonction d’optimisation

    Actuellement, nous utilisons celle de la descente de gradient. Pour la méthode du VGGNet, celle-ci est assez efficace. Cependant, nous pourrions peut être obtenir de meilleurs résultats avec d’autres fonction (RMSprop, Adagrad, Adam, …).

    Utiliser une méthode de régularisation

    Actuellement, nous n’utilisons pas de méthode de régularisation pour le VGGNet. Cependant, celle-ci pourrait être utile pour éviter le surapprentissage.
    La régularisation permet d'appliquer des pénalités sur les paramètres des filtres ou sur l'activité de ceux-ci pendant l'optimisation. Ces pénalités sont intégrées dans la fonction de perte que le réseau optimise.


    1. Conclusion

    Pour conclure, il est important de mentionner que ce projet nous a apporté de nombreuses connaissances pratiques sur les réseaux de neurones et leur implémentation. Malgré le fait que Keras nous offre la possibilité de les développer et tester à plus haut niveau, cela nous a réellement permis d’en apprendre davantage sur ce thème.
    De plus, le fait de développer en Python, qui était un langage que nous ne maîtrisions que très peu, nous a permis d’ajouter un outil réellement utile en tant qu'ingénieur et informaticien.

    Cependant, nous avons rencontré quelques difficultés lors de notre projet. Étant uniquement 3 étudiants de IN54, nous n’avons pas eu les bases pour notre projet qui ont été apprises en IN52, ni la main d’oeuvre que nous aurions souhaité pour la détection de chute.
    De surcroît, l’apprentissage des réseaux de neurones depuis zéro requiert un temps très long, et résultant parfois en des résultats très peu satisfaisants malgré des apprentissages avec beaucoup d’itérations. L’installation des outils est également une contrainte de temps non négligeable lors d’un projet comme celui-ci.

    Il aurait été également possible de réaliser ce projet en utilisant la vitesse et accélération en détectant la position des personnes, mais cette méthode à été volontairement écartée car très simpliste et ne nous aurait pas autant apporté en terme de savoir et d’apprentissage.

    Enfin, nous aurions souhaité le développer davantage, et nous espérons avoir l’opportunité de travailler à l’avenir sur des technologies similaires.


    1. Sources

    Pour le développement:

    • https://arxiv.org/abs/1409.1556
    • https://www.pyimagesearch.com/
    • https://keras.io/

    Pour les jeux de données:

    • http://www.iro.umontreal.ca/~labimage/Dataset/
    • http://le2i.cnrs.fr/Fall-detection-Dataset?lang=fr