Comment automatiser facilement la surveillance avec l'apprentissage en profondeur

Cet article est un didacticiel rapide pour la mise en oeuvre d'un système de surveillance utilisant la détection d'objet basée sur l'apprentissage en profondeur. Il compare également les performances de différents modèles de détection d'objets à l'aide du multitraitement GPU pour l'inférence, sur la détection de piétons.

La surveillance fait partie intégrante de la sécurité et des patrouilles. Pour la plupart, le travail implique de longues périodes de recherche de quelque chose de indésirable. C’est crucial, mais c’est aussi une tâche très banale.

La vie ne serait-elle pas beaucoup plus simple s'il y avait quelque chose qui pourrait nous «surveiller et attendre»? Eh bien, vous avez de la chance. Avec les progrès technologiques de ces dernières années, nous pourrions écrire des scripts pour automatiser les tâches ci-dessus - et cela aussi, assez facilement. Mais avant de plonger plus profondément, demandons-nous:

Est-ce que les machines sont bonnes comme des humains?

Toute personne familiarisée avec Deep Learning saurait que les classificateurs d'images ont surpassé la précision au niveau humain.

Taux d'erreur sur le jeu de données ImageNet au fil du temps, pour les humains, la vision artificielle par ordinateur (CV) et l'apprentissage en profondeur. (Source de l'image: Lien)

Alors oui, une machine peut garder un œil sur les objets au même standard (ou mieux) par rapport à un humain. Cela dit, utiliser la technologie pour effectuer une surveillance est beaucoup plus efficace.

  • La surveillance est une tâche répétitive et banale. Cela peut causer des chutes de performances pour nous, êtres humains. En laissant la technologie se charger de la surveillance, nous pourrions nous concentrer sur les mesures à prendre si quelque chose ne va pas.
  • Pour arpenter une grande bande de terrain, vous avez besoin de beaucoup de personnel. Les caméras fixes ont également un champ de vision limité. Avec les robots de surveillance mobiles (tels que les micro drones), ces problèmes peuvent être atténués.

De plus, la même technologie peut être utilisée pour une variété d'applications qui ne se limitent pas à la sécurité, telles que les moniteurs pour bébé ou la livraison automatisée de produits.

C'est suffisant. Mais comment l'automatiser?

Avant de concevoir des théories compliquées, réfléchissons au fonctionnement normal de la surveillance. Nous regardons un flux vidéo et si nous repérons quelque chose d'anormal, nous agissons. En résumé, notre technologie devrait parcourir chaque image de la vidéo, dans l’espoir de repérer quelque chose d’anormal. Ce processus vous dit quelque chose?

Comme vous l'avez peut-être deviné, c'est l'essence même de la détection d'objet avec localisation. Il est légèrement différent de la classification selon laquelle nous devons connaître l'emplacement exact de l'objet. De plus, nous pouvons avoir plusieurs objets dans une même image.

Pour trouver l'emplacement exact, notre algorithme doit inspecter chaque partie de l'image pour rechercher l'existence d'une classe. C'est plus difficile qu'il n'y paraît. Mais depuis 2014, la recherche itérative continue dans Deep Learning a introduit des réseaux de neurones hautement techniques capables de détecter des objets en temps réel.

Regardez comment les performances ont augmenté en l'espace de deux ans seulement!

Il existe plusieurs architectures Deep Learning, qui utilisent différentes méthodes en interne, pour effectuer la même tâche. Les variantes les plus populaires sont les réseaux Faster RCNN, YOLO et SSD.

Compromis entre vitesse et précision. Une MAP plus élevée et un temps GPU plus court sont optimaux.

Chaque modèle dépend d'un classificateur de base, ce qui influe considérablement sur la précision finale et la taille du modèle. De plus, le choix du détecteur d'objet peut fortement influencer la complexité de calcul et la précision finale.

Il y a toujours un compromis vitesse, précision et taille lors du choix d'un algorithme de détection d'objet.

Dans ce billet de blog, nous allons apprendre à mettre en place un système de surveillance simple mais efficace, à l'aide de la détection d'objet. Parlons d’abord des contraintes auxquelles nous sommes liés en raison de la nature de la tâche de surveillance.

Contraintes pour l'apprentissage en profondeur en surveillance

Souvent, nous aimerions surveiller une grande étendue de terre. Cela entraîne deux facteurs dont nous devrons peut-être tenir compte avant d'automatiser la surveillance.

1. Flux vidéo

Naturellement, pour garder un œil sur une grande surface, nous pouvons avoir besoin de plusieurs caméras. De plus, ces caméras doivent stocker ces données quelque part. soit localement, soit sur un site distant.

Caméras de surveillance typiques. (Photo par Scott Webb sur Unsplash)

Une vidéo de qualité supérieure nécessitera beaucoup plus de mémoire qu'une vidéo de qualité inférieure. De plus, un flux d'entrée RVB est 3 fois plus grand qu'un flux d'entrée BW. Comme nous ne pouvons stocker qu'une quantité finie du flux d'entrée, la qualité est souvent réduite pour maximiser le stockage.

Par conséquent, un système de surveillance évolutif devrait pouvoir interpréter des images de mauvaise qualité. Par conséquent, notre algorithme d'apprentissage en profondeur doit également être formé sur des images de qualité médiocre.

2. Puissance de traitement

Maintenant que nous avons résolu la contrainte d'entrée, nous pouvons répondre à une question plus importante. Où traitons-nous les données obtenues à partir de sources de caméras? Il existe deux méthodes pour ce faire.

  • Traitement sur un serveur centralisé:

Les flux vidéo des caméras sont traités image par image sur un serveur distant ou un cluster. Cette méthode est robuste et nous permet de tirer parti des avantages de modèles complexes avec une grande précision. Le problème évident est la latence; vous avez besoin d’une connexion Internet rapide pour un délai limité. De plus, si vous n'utilisez pas une API commerciale, les coûts d'installation et de maintenance du serveur peuvent être élevés.

Consommation de mémoire en fonction du temps GPU d'inférence (millisecondes). La plupart des modèles hautes performances consomment beaucoup de mémoire. (La source)
  • Traitement sur le bord:

En connectant un petit microcontrôleur, nous pouvons effectuer une inférence en temps réel sur la caméra elle-même. Il n'y a pas de délai de transmission et les anomalies peuvent être signalées plus rapidement que la méthode précédente. En outre, il s'agit d'un excellent complément pour les robots mobiles, de sorte qu'ils ne doivent pas être limités par la plage de connexions WiFi / Bluetooth disponible. (tels que les microdrones).

Capacité FPS de divers détecteurs d'objets. (La source)

L’inconvénient est que les microcontrôleurs ne sont pas aussi puissants que les GPU et que, par conséquent, vous pourriez être obligé d’utiliser des modèles avec une précision moindre. Ce problème peut être contourné en utilisant des GPU intégrés, mais c'est une solution coûteuse. Une solution intéressante consisterait à utiliser un logiciel tel que TensorRT, qui peut optimiser votre programme d’inférence.

Former un système de surveillance

Dans cette section, nous verrons comment identifier les piétons à l'aide de la détection d'objet. Nous allons utiliser l’API de détection d’objet TensorFlow pour créer notre module de détection d’objet. Nous allons explorer brièvement la manière de configurer l’API et de la former à notre tâche de surveillance. Pour une explication plus détaillée, vous pouvez consulter cet article de blog.

L'ensemble du processus peut être résumé en trois phases:

  1. Préparation des données
  2. Former le modèle
  3. Inférence
Le flux de travail impliqué dans la formation d'un modèle de détection d'objet.

Si vous souhaitez voir les résultats vous motiver plus à l'essayer, n'hésitez pas à faire défiler jusqu'à la phase 3!

Phase 1: Préparation des données

Étape 1: obtenir le jeu de données

Les séquences de surveillance prises dans le passé constituent probablement l'ensemble de données le plus précis que vous puissiez obtenir. Mais il est souvent difficile d’obtenir de telles vidéos de surveillance dans la plupart des cas. Dans ce cas, nous pouvons former notre détecteur d'objet à reconnaître généralement nos cibles à partir d'images normales.

Exemple d'image annotée de notre jeu de données.

Comme indiqué précédemment, les images de votre appareil photo peuvent être de qualité inférieure. Vous devez donc former votre modèle à travailler dans de telles conditions. Une méthode très élégante consiste à augmenter les données, ce qui est expliqué en détail ici. Essentiellement, nous devons ajouter du bruit pour dégrader la qualité d'image de l'ensemble de données. Nous pourrions également expérimenter les effets de flou et d’érosion.

Nous allons utiliser le jeu de données TownCentre pour notre tâche de détection d’objet. Nous utiliserons les 3 600 premières images de la vidéo pour la formation et la validation, et les 900 images restantes pour les tests. Vous pouvez utiliser les scripts de mon dépôt GitHub pour extraire l'ensemble de données.

Étape 2: Annoter le jeu de données

Vous pouvez utiliser un outil tel que LabelImg pour effectuer les annotations. C’est une tâche fastidieuse, mais néanmoins importante. Les annotations sont enregistrées en tant que fichiers XML.

Heureusement, les propriétaires du jeu de données TownCentre ont fourni des annotations au format CSV. J'ai écrit un script rapide pour convertir les annotations au format XML requis, que vous pouvez trouver dans mon dépôt GitHub.

Étape 3: cloner le référentiel

Cloner le référentiel. Exécutez les commandes suivantes pour installer la configuration requise, compiler des bibliothèques Protobuf et définir des variables de chemin

pip install -r Requirements.txt
sudo apt-get install protobuf-compiler
protoc object_detection / protos / *. proto --python_out =.
export PYTHONPATH = $ PYTHONPATH: `pwd`:` pwd` / slim

Étape 4: Préparez les entrées de soutien

Nous devons attribuer un identifiant à notre cible. Nous définissons l'ID dans le fichier nommé label_map.pbtxt comme suit

article {
 id: 1
 nom: ‘cible’
}

Ensuite, vous devez créer un fichier texte avec les noms des fichiers XML et image. Par exemple, si vous avez img1.jpg, img2.jpg et img1.xml, img2.xml dans votre jeu de données, votre fichier trainval.txt devrait ressembler à ceci:

img1
img2

Séparez votre jeu de données dans deux dossiers, à savoir les images et les annotations. Placez les labels label_map.pbtxt et trainval.txt dans votre dossier d'annotations. Créez un dossier nommé xml dans le dossier des annotations et placez tous vos fichiers XML à l'intérieur. Votre hiérarchie de répertoires devrait ressembler à ceci:

-base_directory
| -images
| -annotations
|| -xmls
|| -label_map.pbtxt
|| -trainval.txt

Étape 5: Créer des enregistrements TF

L'API accepte les entrées au format de fichier TFRecords. Utilisez le fichier create_tf_record.py fourni dans mon référentiel pour convertir votre jeu de données en TFRecords. Vous devez exécuter la commande suivante dans votre répertoire de base:

python create_tf_record.py \
    --data_dir = `pwd` \
    --output_dir = `pwd`

Vous trouverez deux fichiers, train.record et val.record, une fois l'exécution du programme terminée.

Phase 2: Former le modèle

Étape 1: Sélection du modèle

Comme mentionné précédemment, il existe un compromis entre vitesse et précision. De plus, construire et former un détecteur d’objets à partir de zéro prendrait énormément de temps. Ainsi, l’API de détection d’objets TensorFlow fournit un ensemble de modèles pré-formés, que vous pouvez ajuster à votre cas d’utilisation. Ce processus est appelé apprentissage par transfert et accélère énormément votre processus de formation.

Un tas de modèles pré-formés sur le jeu de données MS COCO

Téléchargez l'un de ces modèles et extrayez le contenu dans votre répertoire de base. Vous recevrez les points de contrôle du modèle, un graphe d'inférence gelé et un fichier pipeline.config.

Étape 2: Définition du travail de formation

Vous devez définir le «travail de formation» dans le fichier pipeline.config. Placez le fichier dans le répertoire de base. Ce qui compte vraiment, ce sont les dernières lignes du fichier - il vous suffit de définir les valeurs en surbrillance sur vos emplacements de fichier respectifs.

gradient_clipping_by_norm: 10.0
  fine_tune_checkpoint: "model.ckpt"
  from_detection_checkpoint: true
  num_steps: 200000
}
train_input_reader {
  label_map_path: "annotations / label_map.pbtxt"
  tf_record_input_reader {
    chemin_entrée: "train.record"
  }
}
eval_config {
  num_examples: 8000
  max_evals: 10
  use_moving_averages: false
}
eval_input_reader {
  label_map_path: "annotations / label_map.pbtxt"
  mélanger: faux
  num_epochs: 1
  nombre de lecteurs: 1
  tf_record_input_reader {
    chemin_entrée: "val.record"
  }
}

Étape 3: commencer l'entraînement

Exécutez la commande ci-dessous pour démarrer le travail de formation. Il est recommandé d’utiliser une machine avec un processeur graphique assez volumineux (à condition d’avoir installé la version gpu de tensorflow) pour accélérer le processus de formation.

python object_detection / train.py \
--logtostderr \
--pipeline_config_path = pipeline.config \
--train_dir = train

Phase 3: Inférence

Étape 1: Exporter le modèle formé

Avant de pouvoir utiliser le modèle, vous devez exporter les fichiers de point de contrôle formés vers un graphe d'inférence gelé. C’est vraiment plus facile que cela n’a été dit - il suffit d’exécuter le code ci-dessous (Remplacez «xxxxx» par le numéro du point de contrôle):

python object_detection / export_inference_graph.py \
--input_type = image_tensor \
--pipeline_config_path = pipeline.config \
--trained_checkpoint_prefix = train / model.ckpt-xxxxx \
--output_directory = sortie

Vous obtiendrez un fichier appelé frozen_inference_graph.pb, ainsi qu'un ensemble de fichiers de points de contrôle.

Étape 2: Utilisez-le sur un flux vidéo

Nous devons extraire des images individuelles de notre source vidéo. Pour ce faire, utilisez la méthode VideoCapture d’OpenCV, comme suit:

cap = cv2.VideoCapture ()
flag = True
tandis que (drapeau):
    drapeau, cadre = cap.read ()
    ## - Code de détection d'objet -

Le code d’extraction de données utilisé lors de la phase 1 crée automatiquement un dossier ‘test_images’ avec les images de notre ensemble de tests. Nous pouvons exécuter notre modèle sur le jeu de tests en exécutant les opérations suivantes:

python object_detection / inference.py \
--input_dir = {CHEMIN} \
--output_dir = {PATH} \
--label_map = {CHEMIN} \
--frozen_graph = {CHEMIN} \
--num_output_classes = 1 \
--n_jobs = 1 \
--delay = 0

Expériences

Comme mentionné précédemment, il existe un compromis entre vitesse et précision lors du choix d'un modèle de détection d'objet. J'ai effectué des expériences qui mesuraient le FPS et comptaient la précision des personnes détectées à l'aide de trois modèles différents. De plus, les expériences ont été menées sur différentes contraintes de ressources (contraintes de parallélisme du GPU). Le résultat de ces expériences peut vous fournir des informations précieuses lors de la sélection d'un modèle de détection d'objet.

Installer

Les modèles suivants ont été sélectionnés pour notre expérience. Celles-ci sont disponibles dans le modèle Zoo de l’API TensorFlow Object Detection.

  • RCNN plus rapide avec ResNet 50
  • SSD avec MobileNet v1
  • SSD avec InceptionNet v2

Tous les modèles ont été formés sur Google Colab pendant 10 000 pas (ou jusqu’à saturation de leur perte). Pour l'inférence, une instance AWS p2.8xlarge a été utilisée. La précision du comptage a été mesurée en comparant le nombre de personnes détectées par le modèle et la vérité au sol. La vitesse d'inférence en images par seconde (FPS) a été testée sous les contraintes suivantes:

  • GPU unique
  • Deux GPU en parallèle
  • Quatre GPU en parallèle
  • Huit GPU en parallèle

Résultats

Voici un extrait du résultat obtenu en utilisant FasterRCNN sur notre ensemble de test. J'ai également joint une vidéo comparant la sortie de chaque modèle vers la fin de ce blog. Ne hésitez pas à faire défiler et à vérifier!

Temps de formation

Le graphique ci-dessous montre le temps nécessaire pour former chaque modèle pour 10 000 étapes (en heures). Ceci exclut le temps requis pour une recherche d'hyperparamètre.

Lorsque votre application est très différente du modèle de pré-entrainement que vous utilisez pour l’apprentissage par transfert, vous devrez peut-être fortement ajuster les hyperparamètres. Toutefois, lorsque votre demande est similaire, vous n’avez pas besoin de faire une recherche approfondie. Néanmoins, vous devrez peut-être toujours expérimenter des paramètres d’entraînement tels que le taux d’apprentissage et le choix de l’optimiseur.

Vitesse (images par seconde)

C'était la partie la plus intéressante de notre expérience. Comme indiqué précédemment, nous avons mesuré les performances en termes de FPS de nos trois modèles pour cinq contraintes de ressources différentes. Les résultats sont montrés plus bas:

Les SSD sont extrêmement rapides et battent facilement la vitesse de Faster RCNN lorsque nous utilisons un seul GPU. Cependant, Faster RCNN rattrape rapidement le SSD lorsque nous augmentons le nombre de GPU (travaillant en parallèle). Il va sans dire que le SSD avec MobileNet est beaucoup plus rapide que le SSD avec InceptionNet dans un environnement à faible GPU.

Une caractéristique notable du graphique ci-dessus est que, les FPS diminuent légèrement lorsque nous augmentons le nombre de GPU pour SSD avec MobileNet. Il existe en fait une réponse simple à ce paradoxe apparent. Il s’avère que notre configuration a traité les images plus rapidement qu’elles n’étaient fournies par la fonction de lecture d’image!

La vitesse de votre système de traitement vidéo ne peut être supérieure à la vitesse à laquelle les images sont envoyées au système.

Pour prouver mon hypothèse, j'ai donné une longueur d'avance à la fonction de lecture d'image. Le graphique ci-dessous montre l’amélioration du FPS pour SSD avec MobileNet lorsqu’un délai a été ajouté. La légère réduction du nombre d'images par seconde dans le graphique précédent est due au surcoût lié à la demande d'entrée de plusieurs GPU.

Inutile de dire que nous observons une forte augmentation des FPS si nous introduisons des retards. En fin de compte, nous avons besoin d’un pipeline de transfert d’images optimisé pour éviter les goulots d’étranglement. Mais comme notre cas d'utilisation est la surveillance, nous avons un goulot d'étranglement supplémentaire. Le FPS de la caméra de surveillance définit la limite supérieure du FPS de notre système.

Compter la précision

Nous définissons la précision de comptage comme le pourcentage de personnes correctement reconnues par notre système de détection d'objets. Je me suis dit que c’était plus propice à la surveillance. Voici comment chacun de nos modèles a performé:

Inutile de dire que Faster RCNN est le modèle le plus précis. Aussi étonnamment, MobileNet fonctionne mieux qu'InceptionNet.

Sur la base des expériences, il est évident qu’il existe un compromis vitesse / précision. Cependant, nous pouvons utiliser un modèle très précis avec un bon taux de FPS si nous disposons de suffisamment de ressources. Nous constatons que Faster RCNN avec ResNet-50 offre la meilleure précision, ainsi qu'un très bon indice de FPS lorsqu'il est déployé sur 4+ GPU en parallèle.

C'était beaucoup d'étapes!

Eh bien ... je ne discuterais pas. C'est en effet beaucoup d'étapes. De plus, configurer une instance cloud pour que ce modèle fonctionne en temps réel serait fastidieux et coûteux.

Une meilleure solution consisterait à utiliser un service API déjà déployé sur des serveurs afin que vous puissiez vous soucier du développement de votre produit. C’est là que Nanonets intervient. Leur API est déployée sur du matériel de qualité avec GPU, de sorte que vous obtenez des performances insensées sans aucun problème!

J'ai converti mes annotations XML existantes au format JSON et les ai transférées à l'API Nanonets. En fait, si vous ne souhaitez pas annoter manuellement votre jeu de données, vous pouvez lui demander de l'annoter pour vous. Voici le flux de travail réduit lorsque Nanonets prend en charge les tâches lourdes.

Flux de travail réduit avec Nanonets

J'ai mentionné précédemment comment les unités de surveillance mobiles telles que les micro drones peuvent améliorer considérablement l'efficacité. Nous pouvons créer de tels drones assez facilement en utilisant des micro-contrôleurs tels que le Raspberry Pi, et nous pouvons utiliser des appels API pour effectuer des inférences.

Il est assez simple de se familiariser avec l’API Nanonets pour la détection d’objets, mais pour un guide bien expliqué, vous pouvez consulter cet article de blog.

Résultats avec Nanonets

Il a fallu environ 2 heures aux Nanonets pour terminer le processus de formation. Ceci inclut le temps requis pour la recherche d'hyperparamètre. En termes de temps de formation, Nanonets est le grand gagnant. Nanonets a également battu FasterRCNN en termes de précision de comptage.

Précision du nombre FasterRCNN = 88.77%
Précision du nombre de nanonettes = 89,66%

Voici la performance des quatre modèles de notre jeu de données de test. Il est évident que les deux modèles de disque SSD sont un peu instables et ont une précision moindre. De plus, même si FasterRCNN et Nanonets ont des précisions comparables, ces derniers ont des boîtes englobantes plus stables.

La surveillance automatisée est-elle responsable?

L'apprentissage en profondeur est un outil formidable qui permet d'obtenir facilement des résultats exemplaires. Mais dans quelle mesure pouvons-nous faire confiance à notre système de surveillance pour agir seul? Il y a quelques cas où l'automatisation est discutable.

Mise à jour: À la lumière du RGPD et des raisons exposées ci-dessous, il est impératif que nous réfléchissions à la légalité et aux questions éthiques relatives à l'automatisation de la surveillance. Ce blog est uniquement à des fins éducatives et utilise un ensemble de données accessible au public. Il est de votre responsabilité de vous assurer que votre système automatisé est conforme à la loi de votre région.

1. Conclusions douteuses

Nous ne savons pas comment un algorithme d'apprentissage en profondeur parvient à une conclusion. Même si le processus d'alimentation des données est impeccable, il peut y avoir beaucoup de résultats parasites. Par exemple, ce filtre anti-profanation utilisé par les policiers britanniques continuait de supprimer les images de dunes de sable en les considérant comme des images obscènes. Des techniques telles que la rétro-propagation guidée peuvent expliquer les décisions dans une certaine mesure, mais nous avons encore un long chemin à parcourir.

2. Attaques contradictoires

Les systèmes d'apprentissage en profondeur sont fragiles. Les attaques conflictuelles s'apparentent à des illusions d'optique pour les classificateurs d'images. Mais ce qui est effrayant, c’est qu’une perturbation calculable et imperceptible peut forcer un modèle d’apprentissage en profondeur à mal classer. En utilisant le même principe, les chercheurs ont pu contourner les systèmes de surveillance basés sur un apprentissage en profondeur en utilisant des «lunettes contradictoires».

3. Faux positifs

Un autre problème est, que faisons-nous en cas de faux positifs. La gravité du problème dépend de l'application elle-même. Par exemple, un faux positif sur un système de patrouille frontalière peut être plus important qu'un système de surveillance de jardin. Il devrait y avoir une certaine quantité d'intervention humaine pour éviter les accidents.

4. visages similaires

Malheureusement, votre look n'est pas aussi unique que votre empreinte digitale. Il est possible que deux personnes (ou plus) se ressemblent beaucoup. Les jumeaux identiques en sont l'un des principaux exemples. Apple Face ID n'a pas réussi à distinguer deux collègues chinois non liés. Cela pourrait rendre la surveillance et l'identification des personnes plus difficiles.

5. Manque de diversité dans les jeux de données

Les algorithmes d'apprentissage en profondeur ne sont aussi bons que les données que vous fournissez. Les ensembles de données les plus populaires de visages humains ne comportent que des échantillons de Blancs. Bien qu'il puisse sembler évident à un enfant que les êtres humains peuvent exister de différentes couleurs, les algorithmes d'apprentissage profond sont plutôt stupides. En fait, Google a eu des problèmes parce qu'il a classé à tort une personne noire comme un gorille.

À propos de Nanonets: Nanonets construit des API pour simplifier l'apprentissage en profondeur pour les développeurs. Visitez-nous à https://www.nanonets.com pour plus)