Apache MXNet - Guide rapide

Ce chapitre met en évidence les fonctionnalités d'Apache MXNet et présente la dernière version de ce framework logiciel d'apprentissage en profondeur.

Qu'est-ce que MXNet?

Apache MXNet est un puissant instrument de cadre logiciel d'apprentissage en profondeur open source qui aide les développeurs à créer, former et déployer des modèles d'apprentissage profond. Ces dernières années, des soins de santé au transport en passant par la fabrication et, en fait, dans tous les aspects de notre vie quotidienne, l'impact de l'apprentissage en profondeur a été généralisé. De nos jours, les entreprises recherchent l'apprentissage en profondeur pour résoudre certains problèmes difficiles tels que la reconnaissance faciale, la détection d'objets, la reconnaissance optique de caractères (OCR), la reconnaissance vocale et la traduction automatique.

C'est la raison pour laquelle Apache MXNet est pris en charge par:

  • Certaines grandes entreprises comme Intel, Baidu, Microsoft, Wolfram Research, etc.

  • Fournisseurs de cloud public, notamment Amazon Web Services (AWS) et Microsoft Azure

  • Certains grands instituts de recherche comme Carnegie Mellon, MIT, l'Université de Washington et l'Université des sciences et technologies de Hong Kong.

Pourquoi Apache MXNet?

Il existe diverses plates-formes d'apprentissage en profondeur telles que Torch7, Caffe, Theano, TensorFlow, Keras, Microsoft Cognitive Toolkit, etc. alors vous vous demandez peut-être pourquoi Apache MXNet? Voyons quelques-unes des raisons derrière cela:

  • Apache MXNet résout l'un des plus gros problèmes des plates-formes d'apprentissage en profondeur existantes. Le problème est que pour utiliser les plates-formes d'apprentissage en profondeur, il faut apprendre un autre système pour une saveur de programmation différente.

  • Avec l'aide d'Apache, les développeurs MXNet peuvent exploiter toutes les capacités des GPU ainsi que le cloud computing.

  • Apache MXNet peut accélérer tout calcul numérique et met un accent particulier sur l'accélération du développement et du déploiement de DNN (Deep Neural Networks) à grande échelle.

  • Il fournit aux utilisateurs les capacités de programmation impérative et symbolique.

Diverses fonctionnalités

Si vous recherchez une bibliothèque flexible d'apprentissage en profondeur pour développer rapidement une recherche de pointe en apprentissage en profondeur ou une plate-forme robuste pour pousser la charge de travail de production, votre recherche se termine sur Apache MXNet. C'est à cause des caractéristiques suivantes:

Formation distribuée

Qu'il s'agisse de formation multi-GPU ou multi-hôte avec une efficacité de mise à l'échelle quasi linéaire, Apache MXNet permet aux développeurs de tirer le meilleur parti de leur matériel. MXNet prend également en charge l'intégration avec Horovod, qui est un cadre d'apprentissage en profondeur distribué open source créé chez Uber.

Pour cette intégration, voici quelques-unes des API distribuées courantes définies dans Horovod:

  • horovod.broadcast()

  • horovod.allgather()

  • horovod.allgather()

À cet égard, MXNet nous offre les capacités suivantes:

  • Device Placement - Avec l'aide de MXNet, nous pouvons facilement spécifier chaque structure de données (DS).

  • Automatic Differentiation - Apache MXNet automatise la différenciation c'est-à-dire les calculs dérivés.

  • Multi-GPU training - MXNet nous permet d'atteindre une efficacité de mise à l'échelle avec le nombre de GPU disponibles.

  • Optimized Predefined Layers - Nous pouvons coder nos propres couches dans MXNet ainsi que l'optimisation des couches prédéfinies pour la vitesse également.

Hybridation

Apache MXNet fournit à ses utilisateurs un frontal hybride. Avec l'aide de l'API Gluon Python, il peut combler le fossé entre ses capacités impératives et symboliques. Cela peut être fait en appelant sa fonctionnalité d'hybridation.

Calcul plus rapide

Les opérations linéaires comme des dizaines ou des centaines de multiplications matricielles sont le goulot d'étranglement de calcul pour les réseaux neuronaux profonds. Pour résoudre ce goulot d'étranglement, MXNet fournit -

  • Calcul numérique optimisé pour les GPU

  • Calcul numérique optimisé pour les écosystèmes distribués

  • Automatisation des flux de travail communs à l'aide desquels le NN standard peut être brièvement exprimé.

Liaisons de langues

MXNet a une intégration profonde dans des langages de haut niveau comme Python et R. Il fournit également un support pour d'autres langages de programmation tels que-

  • Scala

  • Julia

  • Clojure

  • Java

  • C/C++

  • Perl

Nous n'avons pas besoin d'apprendre de nouveau langage de programmation au lieu de cela MXNet, combiné à une fonction d'hybridation, permet une transition exceptionnellement fluide de Python au déploiement dans le langage de programmation de notre choix.

Dernière version MXNet 1.6.0

Apache Software Foundation (ASF) a publié la version stable 1.6.0 d'Apache MXNet le 21 février 2020 sous la licence Apache 2.0. Il s'agit de la dernière version de MXNet à prendre en charge Python 2, la communauté MXNet ayant voté pour ne plus prendre en charge Python 2 dans les versions ultérieures. Voyons quelques-unes des nouvelles fonctionnalités que cette version apporte à ses utilisateurs.

Interface compatible NumPy

En raison de sa flexibilité et de sa généralité, NumPy a été largement utilisé par les praticiens, les scientifiques et les étudiants en apprentissage automatique. Mais comme nous le savons, les accélérateurs matériels de nos jours tels que les unités de traitement graphique (GPU) sont de plus en plus assimilés dans diverses boîtes à outils d'apprentissage automatique (ML), les utilisateurs de NumPy, pour tirer parti de la vitesse des GPU, doivent passer à de nouveaux cadres. avec une syntaxe différente.

Avec MXNet 1.6.0, Apache MXNet évolue vers une expérience de programmation compatible NumPy. La nouvelle interface offre une utilisabilité et une expressivité équivalentes aux praticiens familiers avec la syntaxe NumPy. Parallèlement à cela, MXNet 1.6.0 permet également au système Numpy existant d'utiliser des accélérateurs matériels tels que les GPU pour accélérer les calculs à grande échelle.

Intégration avec Apache TVM

Apache TVM, une pile de compilateurs d'apprentissage en profondeur open source de bout en bout pour les backends matériels tels que les processeurs, les GPU et les accélérateurs spécialisés, vise à combler le fossé entre les frameworks d'apprentissage en profondeur axés sur la productivité et les backends matériels orientés performances. . Avec la dernière version MXNet 1.6.0, les utilisateurs peuvent tirer parti d'Apache (incubation) TVM pour implémenter des noyaux d'opérateurs hautes performances dans le langage de programmation Python. Deux avantages principaux de cette nouvelle fonctionnalité sont les suivants:

  • Simplifie l'ancien processus de développement basé sur C ++.

  • Permet de partager la même implémentation sur plusieurs backend matériels tels que CPU, GPU, etc.

Améliorations des fonctionnalités existantes

Outre les fonctionnalités énumérées ci-dessus de MXNet 1.6.0, il fournit également des améliorations par rapport aux fonctionnalités existantes. Les améliorations sont les suivantes -

Regroupement des opérations par élément pour le GPU

Comme nous le savons, les performances des opérations élémentaires dépendent de la bande passante mémoire et c'est la raison pour laquelle le chaînage de telles opérations peut réduire les performances globales. Apache MXNet 1.6.0 effectue une fusion d'opérations élément par élément, qui génère en fait des opérations fusionnées juste à temps lorsque cela est possible. Une telle fusion de fonctionnement par élément réduit également les besoins de stockage et améliore les performances globales.

Simplifier les expressions courantes

MXNet 1.6.0 élimine les expressions redondantes et simplifie les expressions courantes. Une telle amélioration améliore également l'utilisation de la mémoire et la durée totale d'exécution.

Optimisations

MXNet 1.6.0 fournit également diverses optimisations des fonctionnalités et opérateurs existants, qui sont les suivantes:

  • Précision mixte automatique

  • API Gluon Fit

  • MKL-DNN

  • Support de grand tenseur

  • TensorRT l'intégration

  • Prise en charge du gradient d'ordre supérieur

  • Operators

  • Profileur de performance de l'opérateur

  • Importation / exportation ONNX

  • Améliorations des API Gluon

  • Améliorations des API de symboles

  • Plus de 100 corrections de bogues

Pour démarrer avec MXNet, la première chose à faire est de l'installer sur notre ordinateur. Apache MXNet fonctionne sur à peu près toutes les plates-formes disponibles, y compris Windows, Mac et Linux.

OS Linux

Nous pouvons installer MXNet sur le système d'exploitation Linux des manières suivantes -

Unité de traitement graphique (GPU)

Ici, nous utiliserons diverses méthodes à savoir Pip, Docker et Source pour installer MXNet lorsque nous utilisons le GPU pour le traitement -

En utilisant la méthode Pip

Vous pouvez utiliser la commande suivante pour installer MXNet sur votre système d'exploitation Linus -

pip install mxnet

Apache MXNet propose également des packages MKL pip, qui sont beaucoup plus rapides lorsqu'ils sont exécutés sur du matériel Intel. Ici par exemplemxnet-cu101mkl signifie que -

  • Le package est construit avec CUDA / cuDNN

  • Le package est compatible MKL-DNN

  • La version CUDA est 10.1

Pour une autre option, vous pouvez également vous référer à https://pypi.org/project/mxnet/.

En utilisant Docker

Vous pouvez trouver les images du docker avec MXNet sur DockerHub, disponible sur https://hub.docker.com/u/mxnet Laissez-nous vérifier les étapes ci-dessous pour installer MXNet en utilisant Docker avec GPU -

Step 1- Tout d'abord, en suivant les instructions d'installation du docker disponibles sur https://docs.docker.com/engine/install/ubuntu/. Nous devons installer Docker sur notre machine.

Step 2- Pour activer l'utilisation des GPU à partir des conteneurs docker, nous devons ensuite installer nvidia-docker-plugin. Vous pouvez suivre les instructions d'installation données surhttps://github.com/NVIDIA/nvidia-docker/wiki.

Step 3- En utilisant la commande suivante, vous pouvez extraire l'image du docker MXNet -

$ sudo docker pull mxnet/python:gpu

Maintenant, pour voir si l'extraction d'image docker mxnet / python a réussi, nous pouvons lister les images docker comme suit -

$ sudo docker images

Pour obtenir les vitesses d'inférence les plus rapides avec MXNet, il est recommandé d'utiliser le dernier MXNet avec Intel MKL-DNN. Vérifiez les commandes ci-dessous -

$ sudo docker pull mxnet/python:1.3.0_cpu_mkl $ sudo docker images

De la source

Pour construire la bibliothèque partagée MXNet à partir de la source avec GPU, nous devons d'abord configurer l'environnement pour CUDA et cuDNN comme suit -

  • Téléchargez et installez la boîte à outils CUDA, ici CUDA 9.2 est recommandé.

  • Téléchargement suivant cuDNN 7.1.4.

  • Nous devons maintenant décompresser le fichier. Il est également nécessaire de passer au répertoire racine cuDNN. Déplacez également l'en-tête et les bibliothèques vers le dossier local CUDA Toolkit comme suit -

tar xvzf cudnn-9.2-linux-x64-v7.1
sudo cp -P cuda/include/cudnn.h /usr/local/cuda/include
sudo cp -P cuda/lib64/libcudnn* /usr/local/cuda/lib64
sudo chmod a+r /usr/local/cuda/include/cudnn.h /usr/local/cuda/lib64/libcudnn*
sudo ldconfig

Après avoir configuré l'environnement pour CUDA et cuDNN, suivez les étapes ci-dessous pour créer la bibliothèque partagée MXNet à partir de la source -

Step 1- Tout d'abord, nous devons installer les packages prérequis. Ces dépendances sont requises sur Ubuntu version 16.04 ou ultérieure.

sudo apt-get update
sudo apt-get install -y build-essential git ninja-build ccache libopenblas-dev 
libopencv-dev cmake

Step 2- Dans cette étape, nous téléchargerons la source MXNet et la configurerons. Commençons par cloner le référentiel en utilisant la commande suivante -

git clone –recursive https://github.com/apache/incubator-mxnet.git mxnet
cd mxnet
cp config/linux_gpu.cmake #for build with CUDA

Step 3- En utilisant les commandes suivantes, vous pouvez créer la bibliothèque partagée MXNet Core -

rm -rf build
mkdir -p build && cd build
cmake -GNinja ..
cmake --build .

Two important points regarding the above step is as follows−

Si vous souhaitez créer la version de débogage, spécifiez le comme suit -

cmake -DCMAKE_BUILD_TYPE=Debug -GNinja ..

Afin de définir le nombre de travaux de compilation parallèles, spécifiez ce qui suit -

cmake --build . --parallel N

Une fois que vous avez créé avec succès la bibliothèque partagée MXNet Core, dans le build dossier dans votre MXNet project root, tu trouveras libmxnet.so qui est nécessaire pour installer les liaisons de langue (facultatif).

Unité centrale de traitement (CPU)

Ici, nous utiliserons diverses méthodes, à savoir Pip, Docker et Source pour installer MXNet lorsque nous utilisons le processeur pour le traitement -

En utilisant la méthode Pip

Vous pouvez utiliser la commande suivante pour installer MXNet sur votre système d'exploitation Linus -

pip install mxnet

Apache MXNet propose également des packages pip compatibles MKL-DNN qui sont beaucoup plus rapides, lorsqu'ils sont exécutés sur du matériel Intel.

pip install mxnet-mkl

En utilisant Docker

Vous pouvez trouver les images du docker avec MXNet sur DockerHub, disponible sur https://hub.docker.com/u/mxnet. Laissez-nous vérifier les étapes ci-dessous pour installer MXNet en utilisant Docker avec CPU -

Step 1- Tout d'abord, en suivant les instructions d'installation du docker disponibles sur https://docs.docker.com/engine/install/ubuntu/. Nous devons installer Docker sur notre machine.

Step 2- En utilisant la commande suivante, vous pouvez extraire l'image du docker MXNet:

$ sudo docker pull mxnet/python

Maintenant, pour voir si l'extraction d'image docker mxnet / python a réussi, nous pouvons lister les images docker comme suit -

$ sudo docker images

Pour obtenir les vitesses d'inférence les plus rapides avec MXNet, il est recommandé d'utiliser le dernier MXNet avec Intel MKL-DNN.

Vérifiez les commandes ci-dessous -

$ sudo docker pull mxnet/python:1.3.0_cpu_mkl $ sudo docker images

De la source

Pour créer la bibliothèque partagée MXNet à partir de la source avec le processeur, suivez les étapes ci-dessous:

Step 1- Tout d'abord, nous devons installer les packages prérequis. Ces dépendances sont requises sur Ubuntu version 16.04 ou ultérieure.

sudo apt-get update

sudo apt-get install -y build-essential git ninja-build ccache libopenblas-dev libopencv-dev cmake

Step 2- Dans cette étape, nous téléchargerons la source MXNet et la configurerons. Commençons par cloner le référentiel en utilisant la commande suivante:

git clone –recursive https://github.com/apache/incubator-mxnet.git mxnet

cd mxnet
cp config/linux.cmake config.cmake

Step 3- En utilisant les commandes suivantes, vous pouvez créer la bibliothèque partagée MXNet Core:

rm -rf build
mkdir -p build && cd build
cmake -GNinja ..
cmake --build .

Two important points regarding the above step is as follows−

Si vous souhaitez créer la version de débogage, spécifiez le comme suit:

cmake -DCMAKE_BUILD_TYPE=Debug -GNinja ..

Afin de définir le nombre de travaux de compilation parallèles, spécifiez ce qui suit:

cmake --build . --parallel N

Une fois que vous avez créé avec succès la bibliothèque partagée MXNet Core, dans le build dans la racine de votre projet MXNet, vous trouverez libmxnet.so, qui est nécessaire pour installer les liaisons de langue (facultatif).

MacOS

Nous pouvons installer MXNet sur MacOS de la manière suivante -

Unité de traitement graphique (GPU)

Si vous envisagez de créer MXNet sur MacOS avec GPU, il n'y a PAS de méthode Pip et Docker disponible. La seule méthode dans ce cas est de le construire à partir des sources.

De la source

Pour créer la bibliothèque partagée MXNet à partir de la source avec GPU, nous devons d'abord configurer l'environnement pour CUDA et cuDNN. Vous devez suivre leNVIDIA CUDA Installation Guide qui est disponible à https://docs.nvidia.com et cuDNN Installation Guide, qui est disponible à https://docs.nvidia.com/deeplearning pour mac OS.

Veuillez noter qu'en 2019, CUDA a cessé de prendre en charge macOS. En fait, les futures versions de CUDA pourraient également ne pas prendre en charge macOS.

Une fois que vous avez configuré l'environnement pour CUDA et cuDNN, suivez les étapes ci-dessous pour installer MXNet à partir de la source sur OS X (Mac) -

Step 1- Comme nous avons besoin de quelques dépendances sur OS x, nous devons d'abord installer les packages prérequis.

xcode-select –-install #Install OS X Developer Tools

/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" #Install Homebrew

brew install cmake ninja ccache opencv # Install dependencies

Nous pouvons également créer MXNet sans OpenCV car opencv est une dépendance facultative.

Step 2- Dans cette étape, nous téléchargerons la source MXNet et la configurerons. Commençons par cloner le référentiel en utilisant la commande suivante -

git clone –-recursive https://github.com/apache/incubator-mxnet.git mxnet

cd mxnet
cp config/linux.cmake config.cmake

Pour un GPU activé, il est nécessaire d'installer d'abord les dépendances CUDA car lorsque l'on essaie de construire une build GPU sur une machine sans GPU, MXNet build ne peut pas détecter automatiquement votre architecture GPU. Dans de tels cas, MXNet ciblera toutes les architectures GPU disponibles.

Step 3- En utilisant les commandes suivantes, vous pouvez créer la bibliothèque partagée MXNet Core -

rm -rf build
mkdir -p build && cd build
cmake -GNinja ..
cmake --build .

Deux points importants concernant l'étape ci-dessus sont les suivants:

Si vous souhaitez créer la version de débogage, spécifiez le comme suit -

cmake -DCMAKE_BUILD_TYPE=Debug -GNinja ..

Afin de définir le nombre de travaux de compilation parallèles, spécifiez les éléments suivants:

cmake --build . --parallel N

Une fois que vous avez créé avec succès la bibliothèque partagée MXNet Core, dans le build dossier dans votre MXNet project root, tu trouveras libmxnet.dylib, qui est nécessaire pour installer les liaisons de langue (facultatif).

Unité centrale de traitement (CPU)

Ici, nous utiliserons diverses méthodes à savoir Pip, Docker et Source pour installer MXNet lorsque nous utilisons le processeur pour le traitement -

En utilisant la méthode Pip

Vous pouvez utiliser la commande suivante pour installer MXNet sur votre système d'exploitation Linus

pip install mxnet

En utilisant Docker

Vous pouvez trouver les images du docker avec MXNet sur DockerHub, disponible sur https://hub.docker.com/u/mxnet. Laissez-nous vérifier les étapes ci-dessous pour installer MXNet en utilisant Docker avec CPU−

Step 1- Premièrement, en suivant le docker installation instructions qui sont disponibles à https://docs.docker.com/docker-for-mac nous devons installer Docker sur notre machine.

Step 2- En utilisant la commande suivante, vous pouvez extraire l'image du docker MXNet -

$ docker pull mxnet/python

Maintenant, pour voir si l'extraction de l'image docker mxnet / python a réussi, nous pouvons lister les images docker comme suit -

$ docker images

Pour obtenir les vitesses d'inférence les plus rapides avec MXNet, il est recommandé d'utiliser le dernier MXNet avec Intel MKL-DNN. Vérifiez les commandes ci-dessous -

$ docker pull mxnet/python:1.3.0_cpu_mkl
$ docker images

De la source

Suivez les étapes ci-dessous pour installer MXNet à partir de la source sur OS X (Mac) -

Step 1- Comme nous avons besoin de certaines dépendances sur OS x, nous devons d'abord installer les packages prérequis.

xcode-select –-install #Install OS X Developer Tools
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" #Install Homebrew
brew install cmake ninja ccache opencv # Install dependencies

Nous pouvons également créer MXNet sans OpenCV car opencv est une dépendance facultative.

Step 2- Dans cette étape, nous téléchargerons la source MXNet et la configurerons. Tout d'abord, clonons le référentiel en utilisant la commande suivante -

git clone –-recursive https://github.com/apache/incubator-mxnet.git mxnet

cd mxnet

cp config/linux.cmake config.cmake

Step 3- En utilisant les commandes suivantes, vous pouvez créer la bibliothèque partagée MXNet Core:

rm -rf build
mkdir -p build && cd build
cmake -GNinja ..
cmake --build .

Two important points regarding the above step is as follows−

Si vous souhaitez créer la version de débogage, spécifiez le comme suit -

cmake -DCMAKE_BUILD_TYPE=Debug -GNinja ..

Afin de définir le nombre de travaux de compilation parallèles, spécifiez ce qui suit:

cmake --build . --parallel N

Une fois que vous avez créé avec succès la bibliothèque partagée MXNet Core, dans le build dossier dans votre MXNet project root, tu trouveras libmxnet.dylib, qui est nécessaire pour installer les liaisons de langue (facultatif).

Système d'exploitation Windows

Pour installer MXNet sous Windows, voici les prérequis -

Configuration minimale requise

  • Windows 7, 10, Server 2012 R2 ou Server 2016

  • Visual Studio 2015 ou 2017 (tout type)

  • Python 2.7 ou 3.6

  • pip

Configuration recommandée

  • Windows 10, Server 2012 R2 ou Server 2016

  • Visual Studio 2017

  • Au moins un GPU compatible NVIDIA CUDA

  • Processeur compatible MKL: processeur Intel® Xeon®, famille de processeurs Intel® Core ™, processeur Intel Atom® ou processeur Intel® Xeon Phi ™

  • Python 2.7 ou 3.6

  • pip

Unité de traitement graphique (GPU)

En utilisant la méthode Pip -

Si vous prévoyez de créer MXNet sur Windows avec des GPU NVIDIA, il existe deux options pour installer MXNet avec prise en charge CUDA avec un package Python -

Installer avec le support CUDA

Vous trouverez ci-dessous les étapes à l'aide desquelles nous pouvons configurer MXNet avec CUDA.

Step 1- Installez d'abord Microsoft Visual Studio 2017 ou Microsoft Visual Studio 2015.

Step 2- Ensuite, téléchargez et installez NVIDIA CUDA. Il est recommandé d'utiliser les versions 9.2 ou 9.0 de CUDA car certains problèmes avec CUDA 9.1 ont été identifiés dans le passé.

Step 3- Maintenant, téléchargez et installez NVIDIA_CUDA_DNN.

Step 4- Enfin, en utilisant la commande pip suivante, installez MXNet avec CUDA−

pip install mxnet-cu92

Installer avec le support CUDA et MKL

Vous trouverez ci-dessous les étapes à l'aide desquelles nous pouvons configurer MXNet avec CUDA et MKL.

Step 1- Installez d'abord Microsoft Visual Studio 2017 ou Microsoft Visual Studio 2015.

Step 2- Ensuite, téléchargez et installez Intel MKL

Step 3- Maintenant, téléchargez et installez NVIDIA CUDA.

Step 4- Maintenant, téléchargez et installez NVIDIA_CUDA_DNN.

Step 5- Enfin, en utilisant la commande pip suivante, installez MXNet avec MKL.

pip install mxnet-cu92mkl

De la source

Pour créer la bibliothèque principale MXNet à partir des sources avec GPU, nous avons les deux options suivantes:

Option 1− Build with Microsoft Visual Studio 2017

Pour créer et installer vous-même MXNet à l'aide de Microsoft Visual Studio 2017, vous avez besoin des dépendances suivantes.

Install/update Microsoft Visual Studio.

  • Si Microsoft Visual Studio n'est pas déjà installé sur votre ordinateur, commencez par le télécharger et l'installer.

  • Il vous demandera d'installer Git. Installez-le également.

  • Si Microsoft Visual Studio est déjà installé sur votre ordinateur mais que vous souhaitez le mettre à jour, passez à l'étape suivante pour modifier votre installation. Ici, vous aurez également la possibilité de mettre à jour Microsoft Visual Studio.

Suivez les instructions pour ouvrir le programme d'installation de Visual Studio disponible sur https://docs.microsoft.com/en-us pour modifier des composants individuels.

Dans l'application Visual Studio Installer, mettez à jour si nécessaire. Après cela, cherchez et vérifiezVC++ 2017 version 15.4 v14.11 toolset et cliquez Modify.

Maintenant, en utilisant la commande suivante, changez la version de Microsoft VS2017 en v14.11−

"C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvars64.bat" -vcvars_ver=14.11

Ensuite, vous devez télécharger et installer CMake disponible à https://cmake.org/download/ Il est recommandé d'utiliser CMake v3.12.2 qui est disponible à https://cmake.org/download/ car il est testé avec MXNet.

Maintenant, téléchargez et exécutez le OpenCV forfait disponible à https://sourceforge.net/projects/opencvlibrary/qui décompressera plusieurs fichiers. C'est à vous de décider si vous souhaitez les placer ou non dans un autre répertoire. Ici, nous allons utiliser le cheminC:\utils(mkdir C:\utils) comme chemin par défaut.

Ensuite, nous devons définir la variable d'environnement OpenCV_DIR pour qu'elle pointe vers le répertoire de construction OpenCV que nous venons de décompresser. Pour cette invite de commande ouverte et tapezset OpenCV_DIR=C:\utils\opencv\build.

Un point important est que si vous n'avez pas installé Intel MKL (Math Kernel Library), vous pouvez l'installer.

Un autre package open source que vous pouvez utiliser est OpenBLAS. Ici pour les instructions supplémentaires, nous supposons que vous utilisezOpenBLAS.

Alors, téléchargez le OpenBlas package disponible sur https://sourceforge.net et décompressez le fichier, renommez-le en OpenBLAS et le mettre sous C:\utils.

Ensuite, nous devons définir la variable d'environnement OpenBLAS_HOME pour pointer vers le répertoire OpenBLAS qui contient le include et librépertoires. Pour cette invite de commande ouverte et tapezset OpenBLAS_HOME=C:\utils\OpenBLAS.

Maintenant, téléchargez et installez CUDA disponible sur https://developer.nvidia.com. Notez que, si vous aviez déjà CUDA, puis installé Microsoft VS2017, vous devez réinstaller CUDA maintenant, afin de pouvoir obtenir les composants de la boîte à outils CUDA pour l'intégration de Microsoft VS2017.

Ensuite, vous devez télécharger et installer cuDNN.

Ensuite, vous devez télécharger et installer git qui se trouve à https://gitforwindows.org/ également.

Une fois que vous avez installé toutes les dépendances requises, suivez les étapes ci-dessous pour créer le code source MXNet -

Step 1- Ouvrez l'invite de commande dans Windows.

Step 2- Maintenant, en utilisant la commande suivante, téléchargez le code source MXNet depuis GitHub:

cd C:\

git clone https://github.com/apache/incubator-mxnet.git --recursive

Step 3- Ensuite, vérifiez ce qui suit -

DCUDNN_INCLUDE and DCUDNN_LIBRARY les variables d'environnement pointent vers include dossier et cudnn.lib fichier de l'emplacement d'installation de CUDA

C:\incubator-mxnet est l'emplacement du code source que vous venez de cloner à l'étape précédente.

Step 4- Ensuite, en utilisant la commande suivante, créez un build directory et allez aussi dans le répertoire, par exemple -

mkdir C:\incubator-mxnet\build
cd C:\incubator-mxnet\build

Step 5- Maintenant, en utilisant cmake, compilez le code source MXNet comme suit -

cmake -G "Visual Studio 15 2017 Win64" -T cuda=9.2,host=x64 -DUSE_CUDA=1 -DUSE_CUDNN=1 -DUSE_NVRTC=1 -DUSE_OPENCV=1 -DUSE_OPENMP=1 -DUSE_BLAS=open -DUSE_LAPACK=1 -DUSE_DIST_KVSTORE=0 -DCUDA_ARCH_LIST=Common -DCUDA_TOOLSET=9.2 -DCUDNN_INCLUDE=C:\cuda\include -DCUDNN_LIBRARY=C:\cuda\lib\x64\cudnn.lib "C:\incubator-mxnet"

Step 6- Une fois le CMake terminé avec succès, utilisez la commande suivante pour compiler le code source MXNet -

msbuild mxnet.sln /p:Configuration=Release;Platform=x64 /maxcpucount

Option 2: Build with Microsoft Visual Studio 2015

Pour créer et installer vous-même MXNet à l'aide de Microsoft Visual Studio 2015, vous avez besoin des dépendances suivantes.

Installez / mettez à jour Microsoft Visual Studio 2015. La configuration minimale requise pour générer MXnet à partir de la source est la mise à jour 3 de Microsoft Visual Studio 2015. Vous pouvez utiliser Tools -> Extensions and Updates... | Product Updates menu pour le mettre à jour.

Ensuite, vous devez télécharger et installer CMake qui est disponible à https://cmake.org/download/. Il est recommandé d'utiliserCMake v3.12.2 qui est à https://cmake.org/download/, car il est testé avec MXNet.

Maintenant, téléchargez et exécutez le package OpenCV disponible sur https://excellmedia.dl.sourceforge.netqui décompressera plusieurs fichiers. C'est à vous de décider si vous souhaitez les placer dans un autre répertoire ou non.

Ensuite, nous devons définir la variable d'environnement OpenCV_DIR pour pointer vers le OpenCVrépertoire de construction que nous venons de décompresser. Pour cela, ouvrez l'invite de commande et tapez setOpenCV_DIR=C:\opencv\build\x64\vc14\bin.

Un point important est que si vous n'avez pas installé Intel MKL (Math Kernel Library), vous pouvez l'installer.

Un autre package open source que vous pouvez utiliser est OpenBLAS. Ici pour les instructions supplémentaires, nous supposons que vous utilisezOpenBLAS.

Alors, téléchargez le OpenBLAS forfait disponible à https://excellmedia.dl.sourceforge.net et décompressez le fichier, renommez-le en OpenBLAS et placez-le sous C: \ utils.

Ensuite, nous devons définir la variable d'environnement OpenBLAS_HOME pour qu'elle pointe vers le répertoire OpenBLAS qui contient les répertoires include et lib. Vous pouvez trouver le répertoire dansC:\Program files (x86)\OpenBLAS\

Notez que, si vous aviez déjà CUDA, puis installé Microsoft VS2015, vous devez réinstaller CUDA maintenant afin que vous puissiez obtenir les composants de la boîte à outils CUDA pour l'intégration de Microsoft VS2017.

Ensuite, vous devez télécharger et installer cuDNN.

Maintenant, nous devons définir la variable d'environnement CUDACXX pour qu'elle pointe vers le CUDA Compiler(C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v9.1\bin\nvcc.exe par exemple).

De même, nous devons également définir la variable d'environnement CUDNN_ROOT pour pointer vers le cuDNN répertoire qui contient le include, lib et bin répertoires (C:\Downloads\cudnn-9.1-windows7-x64-v7\cuda par exemple).

Une fois que vous avez installé toutes les dépendances requises, suivez les étapes ci-dessous pour créer le code source MXNet -

Step 1- Tout d'abord, téléchargez le code source MXNet depuis GitHub−

cd C:\
git clone https://github.com/apache/incubator-mxnet.git --recursive

Step 2- Ensuite, utilisez CMake pour créer un Visual Studio dans ./build.

Step 3- Maintenant, dans Visual Studio, nous devons ouvrir le fichier de solution,.sln, et compilez-le. Ces commandes produiront une bibliothèque appeléemxnet.dll dans le ./build/Release/ or ./build/Debug dossier

Step 4- Une fois le CMake terminé avec succès, utilisez la commande suivante pour compiler le code source MXNet

msbuild mxnet.sln /p:Configuration=Release;Platform=x64 /maxcpucount

Unité centrale de traitement (CPU)

Ici, nous utiliserons diverses méthodes à savoir Pip, Docker et Source pour installer MXNet lorsque nous utilisons le processeur pour le traitement -

En utilisant la méthode Pip

Si vous prévoyez de construire MXNet sur Windows avec des CPU, il existe deux options pour installer MXNet à l'aide d'un package Python -

Install with CPUs

Utilisez la commande suivante pour installer MXNet avec CPU avec Python−

pip install mxnet

Install with Intel CPUs

Comme indiqué ci-dessus, MXNet a un support expérimental pour Intel MKL ainsi que MKL-DNN. Utilisez la commande suivante pour installer MXNet avec Intel CPU avec Python−

pip install mxnet-mkl

En utilisant Docker

Vous pouvez trouver les images du docker avec MXNet sur DockerHub, disponible à https://hub.docker.com/u/mxnet Laissez-nous vérifier les étapes ci-dessous, pour installer MXNet en utilisant Docker avec CPU−

Step 1- Tout d'abord, en suivant les instructions d'installation du docker qui peuvent être lues sur https://docs.docker.com/docker-for-mac/install. Nous devons installer Docker sur notre machine.

Step 2- En utilisant la commande suivante, vous pouvez extraire l'image du docker MXNet -

$ docker pull mxnet/python

Maintenant, pour voir si l'extraction de l'image docker mxnet / python a réussi, nous pouvons lister les images docker comme suit -

$ docker images

Pour obtenir les vitesses d'inférence les plus rapides avec MXNet, il est recommandé d'utiliser le dernier MXNet avec Intel MKL-DNN.

Vérifiez les commandes ci-dessous -

$ docker pull mxnet/python:1.3.0_cpu_mkl $ docker images

Installation de MXNet sur le cloud et les appareils

Cette section explique comment installer Apache MXNet sur le cloud et sur les appareils. Commençons par apprendre à installer MXNet sur le cloud.

Installer MXNet sur le cloud

Vous pouvez également obtenir Apache MXNet sur plusieurs fournisseurs de cloud avec Graphical Processing Unit (GPU)soutien. Deux autres types de support que vous pouvez trouver sont les suivants:

  • Prise en charge hybride GPU / CPU pour des cas d'utilisation tels que l'inférence évolutive.
  • Prise en charge des GPU factoriels avec AWS Elastic Inference.

Voici les fournisseurs de cloud fournissant une prise en charge GPU avec différentes machines virtuelles pour Apache MXNet−

La console Alibaba

Vous pouvez créer le NVIDIA GPU Cloud Virtual Machine (VM) disponible à https://docs.nvidia.com/ngc avec la console Alibaba et utilisez Apache MXNet.

Services Web Amazon

Il fournit également un support GPU et fournit les services suivants pour Apache MXNet−

Amazon SageMaker

Il gère la formation et le déploiement des modèles Apache MXNet.

AMI AWS Deep Learning

Il fournit un environnement Conda préinstallé pour Python 2 et Python 3 avec Apache MXNet, CUDA, cuDNN, MKL-DNN et AWS Elastic Inference.

Formation dynamique sur AWS

Il fournit la formation pour la configuration EC2 manuelle expérimentale ainsi que pour la configuration semi-automatisée de CloudFormation.

Vous pouvez utiliser NVIDIA VM disponible à https://aws.amazon.com avec les services Web d'Amazon.

Google Cloud Platform

Google fournit également NVIDIA GPU cloud image qui est disponible à https://console.cloud.google.com pour travailler avec Apache MXNet.

Microsoft Azure

Microsoft Azure Marketplace fournit également NVIDIA GPU cloud image disponible à https://azuremarketplace.microsoft.com pour travailler avec Apache MXNet.

Oracle Cloud

Oracle fournit également NVIDIA GPU cloud image disponible à https://docs.cloud.oracle.com pour travailler avec Apache MXNet.

Unité centrale de traitement (CPU)

Apache MXNet fonctionne sur l'instance de processeur uniquement de chaque fournisseur de cloud. Il existe différentes méthodes pour installer telles que -

  • Instructions d'installation de Python pip.

  • Instructions Docker.

  • Option préinstallée comme Amazon Web Services qui fournit AWS Deep Learning AMI (ayant préinstallé l'environnement Conda pour Python 2 et Python 3 avec MXNet et MKL-DNN).

Installation de MXNet sur des appareils

Apprenons à installer MXNet sur des appareils.

Tarte aux framboises

Vous pouvez également exécuter Apache MXNet sur les appareils Raspberry Pi 3B car MXNet prend également en charge le système d'exploitation basé sur Respbian ARM. Afin d'exécuter MXNet en douceur sur le Raspberry Pi3, il est recommandé de disposer d'un appareil disposant de plus de 1 Go de RAM et d'une carte SD avec au moins 4 Go d'espace libre.

Voici les moyens à l'aide desquels vous pouvez créer MXNet pour le Raspberry Pi et installer également les liaisons Python pour la bibliothèque -

Installation rapide

La roue Python pré-construite peut être utilisée sur un Raspberry Pi 3B avec Stretch pour une installation rapide. L'un des problèmes importants de cette méthode est que nous devons installer plusieurs dépendances pour faire fonctionner Apache MXNet.

Installation de Docker

Vous pouvez suivre les instructions d'installation du docker, disponibles sur https://docs.docker.com/engine/install/ubuntu/pour installer Docker sur votre machine. À cette fin, nous pouvons également installer et utiliser Community Edition (CE).

Construction native (à partir de la source)

Afin d'installer MXNet à partir de la source, nous devons suivre les deux étapes suivantes -

Étape 1

Build the shared library from the Apache MXNet C++ source code

Pour créer la bibliothèque partagée sur la version Raspberry Wheezy et versions ultérieures, nous avons besoin des dépendances suivantes:

  • Git- Il est nécessaire d'extraire le code de GitHub.

  • Libblas- Il est nécessaire pour les opérations algébriques linéaires.

  • Libopencv- Il est nécessaire pour les opérations liées à la vision par ordinateur. Cependant, il est facultatif si vous souhaitez économiser votre RAM et votre espace disque.

  • C++ Compiler- Il est nécessaire pour compiler et construire le code source MXNet. Voici les compilateurs pris en charge qui prennent en charge C ++ 11−

    • G ++ (version 4.8 ou ultérieure)

    • Clang(3.9-6)

Utilisez les commandes suivantes pour installer les dépendances mentionnées ci-dessus -

sudo apt-get update
sudo apt-get -y install git cmake ninja-build build-essential g++-4.9 c++-4.9 liblapack*
libblas* libopencv*
libopenblas* python3-dev python-dev virtualenv

Ensuite, nous devons cloner le référentiel de code source MXNet. Pour cela, utilisez la commande git suivante dans votre répertoire personnel -

git clone https://github.com/apache/incubator-mxnet.git --recursive

cd incubator-mxnet

Maintenant, à l'aide des commandes suivantes, créez la bibliothèque partagée:

mkdir -p build && cd build
cmake \
-DUSE_SSE=OFF \
-DUSE_CUDA=OFF \
-DUSE_OPENCV=ON \
-DUSE_OPENMP=ON \
-DUSE_MKL_IF_AVAILABLE=OFF \
-DUSE_SIGNAL_HANDLER=ON \

-DCMAKE_BUILD_TYPE=Release \
-GNinja ..
ninja -j$(nproc)

Une fois que vous exécutez les commandes ci-dessus, il lancera le processus de construction qui prendra quelques heures pour se terminer. Vous obtiendrez un fichier nommélibmxnet.so dans le répertoire de construction.

Étape 2

Install the supported language-specific packages for Apache MXNet

Dans cette étape, nous installerons les liaisons MXNet Pythin. Pour ce faire, nous devons exécuter la commande suivante dans le répertoire MXNet -

cd python
pip install --upgrade pip
pip install -e .

Alternativement, avec la commande suivante, vous pouvez également créer un whl package installable avec pip-

ci/docker/runtime_functions.sh build_wheel python/ $(realpath build)

Périphériques NVIDIA Jetson

Vous pouvez également exécuter Apache MXNet sur des appareils NVIDIA Jetson, tels que TX2 ou Nanocar MXNet prend également en charge le système d'exploitation basé sur Ubuntu Arch64. Pour exécuter MXNet en douceur sur les appareils NVIDIA Jetson, il est nécessaire d'installer CUDA sur votre appareil Jetson.

Voici les moyens à l'aide desquels vous pouvez créer MXNet pour les appareils NVIDIA Jetson:

  • En utilisant une molette Jetson MXNet pip pour le développement Python

  • De la source

Mais, avant de créer MXNet à partir de l'une des méthodes mentionnées ci-dessus, vous devez installer les dépendances suivantes sur vos appareils Jetson -

Dépendances Python

Pour utiliser l'API Python, nous avons besoin des dépendances suivantes:

sudo apt update
sudo apt -y install \
   build-essential \
   git \
   graphviz \
   libatlas-base-dev \
   libopencv-dev \
   python-pip
sudo pip install --upgrade \
   pip \
   setuptools
sudo pip install \
   graphviz==0.8.4 \
   jupyter \
   numpy==1.15.2

Cloner le référentiel de code source MXNet

En utilisant la commande git suivante dans votre répertoire personnel, clonez le référentiel de code source MXNet -

git clone --recursive https://github.com/apache/incubator-mxnet.git mxnet

Variables d'environnement de configuration

Ajoutez ce qui suit dans votre .profile fichier dans votre répertoire personnel -

export PATH=/usr/local/cuda/bin:$PATH export MXNET_HOME=$HOME/mxnet/
export PYTHONPATH=$MXNET_HOME/python:$PYTHONPATH

Maintenant, appliquez le changement immédiatement avec la commande suivante -

source .profile

Configurer CUDA

Avant de configurer CUDA, avec nvcc, vous devez vérifier quelle version de CUDA est en cours d'exécution -

nvcc --version

Supposons que, si plusieurs versions de CUDA sont installées sur votre appareil ou ordinateur et que vous souhaitez changer de version de CUDA, utilisez ce qui suit et remplacez le lien symbolique vers la version souhaitée -

sudo rm /usr/local/cuda
sudo ln -s /usr/local/cuda-10.0 /usr/local/cuda

La commande ci-dessus passera à CUDA 10.0, qui est préinstallée sur l'appareil NVIDIA Jetson Nano.

Une fois que vous avez terminé avec les prérequis mentionnés ci-dessus, vous pouvez maintenant installer MXNet sur les appareils NVIDIA Jetson. Alors, laissez-nous comprendre les moyens à l'aide desquels vous pouvez installer MXNet−

By using a Jetson MXNet pip wheel for Python development- Si vous souhaitez utiliser une roue Python préparée, téléchargez ce qui suit sur votre Jetson et exécutez-le -

  • MXNet 1.4.0 (pour Python 3) disponible sur https://docs.docker.com

  • MXNet 1.4.0 (pour Python 2) disponible sur https://docs.docker.com

Construction native (à partir de la source)

Afin d'installer MXNet à partir de la source, nous devons suivre les deux étapes suivantes -

Étape 1

Build the shared library from the Apache MXNet C++ source code

Pour créer la bibliothèque partagée à partir du code source Apache MXNet C ++, vous pouvez soit utiliser la méthode Docker, soit le faire manuellement -

Méthode Docker

Dans cette méthode, vous devez d'abord installer Docker et pouvoir l'exécuter sans sudo (ce qui est également expliqué dans les étapes précédentes). Une fois cela fait, exécutez ce qui suit pour exécuter la compilation croisée via Docker−

$MXNET_HOME/ci/build.py -p jetson

Manuel

Dans cette méthode, vous devez modifier le Makefile (avec la commande ci-dessous) pour installer le MXNet avec des liaisons CUDA pour tirer parti des unités de traitement graphique (GPU) sur les appareils NVIDIA Jetson:

cp $MXNET_HOME/make/crosscompile.jetson.mk config.mk

Après avoir modifié le Makefile, vous devez modifier le fichier config.mk pour apporter des modifications supplémentaires au périphérique NVIDIA Jetson.

Pour cela, mettez à jour les paramètres suivants -

  • Mettez à jour le chemin CUDA: USE_CUDA_PATH = / usr / local / cuda

  • Ajoutez -gencode arch = compute-63, code = sm_62 au paramètre CUDA_ARCH.

  • Mettez à jour les paramètres NVCC: NVCCFLAGS: = -m64

  • Activez OpenCV: USE_OPENCV = 1

Maintenant, pour nous assurer que le MXNet se construit avec l'accélération de basse précision au niveau matériel de Pascal, nous devons éditer le Makefile Mshadow comme suit:

MSHADOW_CFLAGS += -DMSHADOW_USE_PASCAL=1

Enfin, à l'aide de la commande suivante, vous pouvez créer la bibliothèque Apache MXNet complète -

cd $MXNET_HOME make -j $(nproc)

Une fois que vous exécutez les commandes ci-dessus, il lancera le processus de construction qui prendra quelques heures pour se terminer. Vous obtiendrez un fichier nommélibmxnet.so dans le mxnet/lib directory.

Étape 2

Install the Apache MXNet Python Bindings

Dans cette étape, nous installerons les liaisons MXNet Python. Pour ce faire, nous devons exécuter la commande suivante dans le répertoire MXNet -

cd $MXNET_HOME/python
sudo pip install -e .

Une fois les étapes ci-dessus terminées, vous êtes maintenant prêt à exécuter MXNet sur vos appareils NVIDIA Jetson TX2 ou Nano. Il peut être vérifié avec la commande suivante -

import mxnet
mxnet.__version__

Il renverra le numéro de version si tout fonctionne correctement.

Pour soutenir la recherche et le développement d'applications Deep Learning dans de nombreux domaines, Apache MXNet nous fournit un riche écosystème de boîtes à outils, de bibliothèques et bien d'autres. Laissez-nous les explorer -

Kits d'outils

Voici quelques-unes des boîtes à outils les plus utilisées et les plus importantes fournies par MXNet -

GluonCV

Comme son nom l'indique, GluonCV est une boîte à outils Gluon pour la vision par ordinateur alimentée par MXNet. Il fournit la mise en œuvre d'algorithmes DL (Deep Learning) de pointe en vision par ordinateur (CV). Avec l'aide de la boîte à outils GluonCV, les ingénieurs, les chercheurs et les étudiants peuvent valider de nouvelles idées et apprendre facilement des CV.

Ci-dessous quelques-uns des features of GluonCV -

  • Il forme des scripts pour reproduire les résultats de pointe rapportés dans les dernières recherches.

  • Plus de 170 modèles pré-entraînés de haute qualité.

  • Adoptez un modèle de développement flexible.

  • GluonCV est facile à optimiser. Nous pouvons le déployer sans conserver le cadre DL lourd.

  • Il fournit des API soigneusement conçues qui réduisent considérablement la complexité de la mise en œuvre.

  • Soutien communautaire.

  • Implémentations faciles à comprendre.

Voici les supported applications par la boîte à outils GluonCV:

  • Classification d'image

  • Détection d'objets

  • Segmentation sémantique

  • Segmentation d'instance

  • Estimation de la pose

  • Reconnaissance des actions vidéo

Nous pouvons installer GluonCV en utilisant pip comme suit -

pip install --upgrade mxnet gluoncv

GluonNLP

Comme son nom l'indique, GluonNLP est une boîte à outils Gluon pour le traitement du langage naturel (NLP) alimenté par MXNet. Il fournit la mise en œuvre de modèles DL (Deep Learning) de pointe en PNL.

Avec l'aide de la boîte à outils GluonNLP, les ingénieurs, les chercheurs et les étudiants peuvent créer des blocs pour des pipelines et des modèles de données texte. Sur la base de ces modèles, ils peuvent rapidement prototyper les idées et le produit de la recherche.

Voici quelques-unes des fonctionnalités de GluonNLP:

  • Il forme des scripts pour reproduire les résultats de pointe rapportés dans les dernières recherches.

  • Ensemble de modèles pré-entraînés pour les tâches PNL courantes.

  • Il fournit des API soigneusement conçues qui réduisent considérablement la complexité de la mise en œuvre.

  • Soutien communautaire.

  • Il fournit également des didacticiels pour vous aider à démarrer sur de nouvelles tâches PNL.

Voici les tâches NLP que nous pouvons implémenter avec la boîte à outils GluonNLP -

  • Intégration de mots

  • Modèle de langage

  • Traduction automatique

  • Classification du texte

  • Analyse des sentiments

  • Inférence de langage naturel

  • Génération de texte

  • Analyse des dépendances

  • Reconnaissance des entités nommées

  • Classification d'intention et étiquetage des emplacements

Nous pouvons installer GluonNLP en utilisant pip comme suit -

pip install --upgrade mxnet gluonnlp

GluonTS

Comme son nom l'indique, GluonTS est une boîte à outils Gluon pour la modélisation probabiliste de séries temporelles alimentée par MXNet.

Il fournit les fonctionnalités suivantes -

  • Modèles d'apprentissage en profondeur de pointe (SOTA) prêts à être formés.

  • Les utilitaires de chargement et d'itération sur des ensembles de données chronologiques.

  • Blocs de construction pour définir votre propre modèle.

Avec l'aide de la boîte à outils GluonTS, les ingénieurs, les chercheurs et les étudiants peuvent former et évaluer n'importe lequel des modèles intégrés sur leurs propres données, expérimenter rapidement différentes solutions et proposer une solution pour leurs tâches de séries chronologiques.

Ils peuvent également utiliser les abstractions et les blocs de construction fournis pour créer des modèles de séries chronologiques personnalisés et les comparer rapidement à des algorithmes de base.

Nous pouvons installer GluonTS en utilisant pip comme suit -

pip install gluonts

GluonFR

Comme son nom l'indique, il s'agit d'une boîte à outils Apache MXNet Gluon pour FR (reconnaissance faciale). Il fournit les fonctionnalités suivantes -

  • Modèles d'apprentissage profond de pointe (SOTA) en reconnaissance faciale.

  • La mise en œuvre de SoftmaxCrossEntropyLoss, ArcLoss, TripletLoss, RingLoss, CosLoss / AMsoftmax, L2-Softmax, A-Softmax, CenterLoss, ContrastiveLoss et LGM Loss, etc.

Pour installer Gluon Face, nous avons besoin de Python 3.5 ou version ultérieure. Nous devons également d'abord installer GluonCV et MXNet comme suit -

pip install gluoncv --pre
pip install mxnet-mkl --pre --upgrade
pip install mxnet-cuXXmkl --pre –upgrade # if cuda XX is installed

Une fois que vous avez installé les dépendances, vous pouvez utiliser la commande suivante pour installer GluonFR -

From Source

pip install git+https://github.com/THUFutureLab/gluon-face.git@master

Pip

pip install gluonfr

Écosystème

Explorons maintenant les riches bibliothèques, packages et frameworks de MXNet -

Entraîneur RL

Coach, un framework Python Reinforcement Learning (RL) créé par Intel AI lab. Il permet une expérimentation facile avec des algorithmes RL de pointe. Coach RL prend en charge Apache MXNet en tant que back-end et permet une intégration simple d'un nouvel environnement à résoudre.

Afin d'étendre et de réutiliser facilement les composants existants, Coach RL a très bien découplé les composants d'apprentissage par renforcement de base tels que les algorithmes, les environnements, les architectures NN, les politiques d'exploration.

Voici les agents et les algorithmes pris en charge pour le framework Coach RL -

Agents d'optimisation de la valeur

  • Réseau Q profond (DQN)

  • Réseau Double Deep Q (DDQN)

  • Réseau Dueling Q

  • Monte Carlo mixte (MMC)

  • Apprentissage des avantages persistants (PAL)

  • Réseau catégoriel Deep Q (C51)

  • Réseau Q profond de régression quantile (QR-DQN)

  • Apprentissage N-Step Q

  • Contrôle épisodique neuronal (NEC)

  • Fonctions d'avantage normalisées (NAF)

  • Rainbow

Agents d'optimisation des politiques

  • Gradients de politique (PG)

  • Asynchronous Advantage Actor-Critic (A3C)

  • Gradients de politique déterministes profonds (DDPG)

  • Optimisation de la politique proximale (PPO)

  • Optimisation de la politique proximale tronquée (CPPO)

  • Estimation des avantages généralisés (GAE)

  • Exemple de critique d'acteur efficace avec Experience Replay (ACER)

  • Critique d'acteur doux (SAC)

  • Gradient de politique déterministe profond à double retard (TD3)

Agents généraux

  • Prédiction directe du futur (DFP)

Agents d'apprentissage d'imitation

  • Clonage comportemental (BC)

  • Apprentissage par imitation conditionnelle

Agents d'apprentissage par renforcement hiérarchique

  • Critique d'acteur hiérarchique (HAC)

Bibliothèque de graphes profonds

Deep Graph Library (DGL), développé par les équipes NYU et AWS, Shanghai, est un package Python qui fournit des implémentations faciles de Graph Neural Networks (GNN) au-dessus de MXNet. Il fournit également une implémentation facile des GNN en plus d'autres grandes bibliothèques d'apprentissage en profondeur existantes telles que PyTorch, Gluon, etc.

Deep Graph Library est un logiciel gratuit. Il est disponible sur toutes les distributions Linux ultérieures à Ubuntu 16.04, macOS X et Windows 7 ou version ultérieure. Il nécessite également la version Python 3.5 ou ultérieure.

Voici les caractéristiques de DGL -

No Migration cost - Il n'y a aucun coût de migration pour l'utilisation de DGL car il est construit sur les frameworks DL existants.

Message Passing- DGL assure la transmission des messages et dispose d'un contrôle polyvalent sur celui-ci. Le passage de message va des opérations de bas niveau telles que l'envoi le long des bords sélectionnés au contrôle de haut niveau comme les mises à jour des fonctionnalités à l'échelle du graphique.

Smooth Learning Curve - Il est assez facile d'apprendre et d'utiliser DGL car les puissantes fonctions définies par l'utilisateur sont flexibles et faciles à utiliser.

Transparent Speed Optimization - DGL offre une optimisation transparente de la vitesse en effectuant un traitement par lots automatique des calculs et une multiplication de matrice éparse.

High performance - Afin d'atteindre une efficacité maximale, DGL regroupe automatiquement l'entraînement DNN (Deep Neural Networks) sur un ou plusieurs graphiques ensemble.

Easy & friendly interface - DGL nous fournit des interfaces simples et conviviales pour l'accès aux fonctionnalités de bord ainsi que la manipulation de la structure des graphiques.

InsightFace

InsightFace, une boîte à outils d'apprentissage en profondeur pour l'analyse de visage qui fournit la mise en œuvre de l'algorithme d'analyse de visage SOTA (de pointe) dans la vision par ordinateur alimenté par MXNet. Il fournit -

  • Grand ensemble de modèles pré-entraînés de haute qualité.

  • Scripts de formation à la pointe de la technologie (SOTA).

  • InsightFace est facile à optimiser. Nous pouvons le déployer sans conserver le cadre DL lourd.

  • Il fournit des API soigneusement conçues qui réduisent considérablement la complexité de la mise en œuvre.

  • Blocs de construction pour définir votre propre modèle.

Nous pouvons installer InsightFace en utilisant pip comme suit -

pip install --upgrade insightface

Veuillez noter qu'avant d'installer InsightFace, veuillez installer le package MXNet approprié en fonction de la configuration de votre système.

Keras-MXNet

Comme nous savons que Keras est une API de réseau neuronal (NN) de haut niveau écrite en Python, Keras-MXNet nous fournit un support backend pour Keras. Il peut fonctionner sur un framework Apache MXNet DL hautes performances et évolutif.

Les fonctionnalités de Keras-MXNet sont mentionnées ci-dessous -

  • Permet aux utilisateurs un prototypage facile, fluide et rapide. Tout cela passe par la convivialité, la modularité et l'extensibilité.

  • Prend en charge à la fois CNN (réseaux de neurones convolutifs) et RNN (réseaux de neurones récurrents) ainsi que la combinaison des deux.

  • Fonctionne parfaitement sur l'unité centrale (CPU) et l'unité de traitement graphique (GPU).

  • Peut fonctionner sur un ou plusieurs GPU.

Pour travailler avec ce backend, vous devez d'abord installer keras-mxnet comme suit -

pip install keras-mxnet

Maintenant, si vous utilisez des GPU, installez MXNet avec le support CUDA 9 comme suit -

pip install mxnet-cu90

Mais si vous utilisez uniquement le processeur, installez MXNet de base comme suit -

pip install mxnet

MXBoard

MXBoard est un outil de journalisation, écrit en Python, utilisé pour enregistrer des trames de données MXNet et les afficher dans TensorBoard. En d'autres termes, le MXBoard est censé suivre l'API tensorboard-pytorch. Il prend en charge la plupart des types de données dans TensorBoard.

Certains d'entre eux sont mentionnés ci-dessous -

  • Graph

  • Scalar

  • Histogram

  • Embedding

  • Image

  • Text

  • Audio

  • Courbe de rappel de précision

MXFusion

MXFusion est une bibliothèque de programmation probabiliste modulaire avec apprentissage en profondeur. MXFusion nous permet d'exploiter pleinement la modularité, qui est une caractéristique clé des bibliothèques de deep learning, pour la programmation probabiliste. Il est simple à utiliser et fournit aux utilisateurs une interface pratique pour concevoir des modèles probabilistes et les appliquer aux problèmes du monde réel.

MXFusion est vérifié sur Python version 3.4 et plus sur MacOS et Linux OS. Pour installer MXFusion, nous devons d'abord installer les dépendances suivantes -

  • MXNet> = 1,3

  • Networkx> = 2,1

Avec l'aide de la commande pip suivante, vous pouvez installer MXFusion -

pip install mxfusion

TVM

Apache TVM, une pile de compilateurs d'apprentissage en profondeur open source de bout en bout pour les backends matériels tels que les processeurs, les GPU et les accélérateurs spécialisés, vise à combler le fossé entre les frameworks d'apprentissage en profondeur axés sur la productivité et les backends matériels orientés performances. . Avec la dernière version MXNet 1.6.0, les utilisateurs peuvent tirer parti d'Apache (incubation) TVM pour implémenter des noyaux d'opérateurs hautes performances dans le langage de programmation Python.

Apache TVM a en fait commencé comme un projet de recherche au groupe SAMPL de la Paul G.Allen School of Computer Science & Engineering, Université de Washington et il s'agit maintenant d'un effort en incubation à l'Apache Software Foundation (ASF) qui est dirigé par un OSC ( communauté open source) qui implique plusieurs industries ainsi que des institutions académiques sous la forme d'Apache.

Voici les principales caractéristiques d'Apache (incubation) TVM -

  • Simplifie l'ancien processus de développement basé sur C ++.

  • Permet de partager la même implémentation sur plusieurs backends matériels tels que CPU, GPU, etc.

  • TVM fournit la compilation de modèles DL dans divers frameworks tels que Kears, MXNet, PyTorch, Tensorflow, CoreML, DarkNet en modules minimum déployables sur divers backends matériels.

  • Il nous fournit également l'infrastructure pour générer et optimiser automatiquement les opérateurs de tenseurs avec de meilleures performances.

XFer

Xfer, un framework d'apprentissage par transfert, est écrit en Python. Il prend essentiellement un modèle MXNet et entraîne un méta-modèle ou modifie également le modèle pour un nouvel ensemble de données cible.

En termes simples, Xfer est une bibliothèque Python qui permet aux utilisateurs de transférer rapidement et facilement les connaissances stockées dans DNN (Deep Neural Networks).

Xfer peut être utilisé -

  • Pour la classification des données de format numérique arbitraire.

  • Aux cas courants d'images ou de données textuelles.

  • En tant que pipeline qui envoie des spams de l'extraction de fonctionnalités à la formation d'un repurposer (un objet qui effectue la classification dans la tâche cible).

Voici les fonctionnalités de Xfer:

  • Efficacité des ressources

  • Efficacité des données

  • Accès facile aux réseaux de neurones

  • Modélisation d'incertitude

  • Prototypage rapide

  • Utilitaires pour l'extraction de caractéristiques à partir de NN

Ce chapitre vous aidera à comprendre l'architecture du système MXNet. Commençons par découvrir les modules MXNet.

Modules MXNet

Le diagramme ci-dessous est l'architecture du système MXNet et montre les principaux modules et composants de MXNet modules and their interaction.

Dans le diagramme ci-dessus -

  • Les modules dans les cases de couleur bleue sont User Facing Modules.

  • Les modules dans les cases de couleur verte sont System Modules.

  • La flèche pleine représente une forte dépendance, c'est-à-dire s'appuie fortement sur l'interface.

  • La flèche en pointillé représente la dépendance légère, c'est-à-dire la structure de données utilisée pour la commodité et la cohérence de l'interface. En fait, il peut être remplacé par les alternatives.

Parlons plus en détail du contact avec les utilisateurs et des modules système.

Modules orientés utilisateur

Les modules destinés à l'utilisateur sont les suivants -

  • NDArray- Il fournit des programmes impératifs flexibles pour Apache MXNet. Ce sont des tableaux dynamiques et asynchrones à n dimensions.

  • KVStore- Il sert d'interface pour une synchronisation efficace des paramètres. Dans KVStore, KV signifie Key-Value. Donc, c'est une interface de magasin clé-valeur.

  • Data Loading (IO) - Ce module orienté utilisateur est utilisé pour un chargement et une augmentation efficaces des données distribuées.

  • Symbol Execution- C'est un exécuteur de graphe symbolique statique. Il fournit une exécution et une optimisation efficaces des graphes symboliques.

  • Symbol Construction - Ce module orienté utilisateur fournit à l'utilisateur un moyen de construire un graphe de calcul, c'est-à-dire une configuration réseau.

Modules système

Les modules système sont les suivants -

  • Storage Allocator - Ce module système, comme son nom l'indique, alloue et recycle efficacement les blocs de mémoire sur l'hôte, c.-à-d. CPU et différents périphériques, c.-à-d. GPU.

  • Runtime Dependency Engine - Le module du moteur de dépendance d'exécution planifie et exécute les opérations selon leur dépendance de lecture / écriture.

  • Resource Manager - Le module système Resource Manager (RM) gère les ressources globales telles que le générateur de nombres aléatoires et l'espace temporel.

  • Operator - Le module du système opérateur comprend tous les opérateurs qui définissent le calcul statique vers l'avant et le gradient, c'est-à-dire la rétropropagation.

Ici, les composants système d'Apache MXNet sont expliqués en détail. Tout d'abord, nous étudierons le moteur d'exécution dans MXNet.

Moteur d'exécution

Le moteur d'exécution d'Apache MXNet est très polyvalent. Nous pouvons l'utiliser pour l'apprentissage en profondeur ainsi que pour tout problème spécifique à un domaine: exécuter un tas de fonctions suivant leurs dépendances. Il est conçu de telle manière que les fonctions avec dépendances sont sérialisées alors que les fonctions sans dépendances peuvent être exécutées en parallèle.

Interface principale

L'API ci-dessous est l'interface principale du moteur d'exécution d'Apache MXNet -

virtual void PushSync(Fn exec_fun, Context exec_ctx,
std::vector<VarHandle> const& const_vars,
std::vector<VarHandle> const& mutate_vars) = 0;

L'API ci-dessus a les éléments suivants -

  • exec_fun - L'API d'interface principale de MXNet nous permet de pousser la fonction nommée exec_fun, ainsi que ses informations de contexte et ses dépendances, vers le moteur d'exécution.

  • exec_ctx - Les informations de contexte dans lesquelles la fonction exec_fun mentionnée ci-dessus doit être exécutée.

  • const_vars - Ce sont les variables à partir desquelles la fonction lit.

  • mutate_vars - Ce sont les variables qui doivent être modifiées.

Le moteur d'exécution fournit à son utilisateur la garantie que l'exécution de deux fonctions quelconques qui modifient une variable commune est sérialisée dans leur ordre de transmission.

Fonction

Voici le type de fonction du moteur d'exécution d'Apache MXNet -

using Fn = std::function<void(RunContext)>;

Dans la fonction ci-dessus, RunContextcontient les informations d'exécution. Les informations d'exécution doivent être déterminées par le moteur d'exécution. La syntaxe deRunContext est comme suit -

struct RunContext {
   // stream pointer which could be safely cast to
   // cudaStream_t* type
   void *stream;
};

Vous trouverez ci-dessous quelques points importants sur les fonctions du moteur d'exécution -

  • Toutes les fonctions sont exécutées par les threads internes du moteur d'exécution de MXNet.

  • Il n'est pas bon de pousser le blocage de la fonction vers le moteur d'exécution car avec cela la fonction occupera le thread d'exécution et réduira également le débit total.

Pour cela, MXNet fournit une autre fonction asynchrone comme suit -

using Callback = std::function<void()>;
using AsyncFn = std::function<void(RunContext, Callback)>;
  • Dans ce AsyncFn fonction, nous pouvons passer la partie lourde de nos threads, mais le moteur d'exécution ne considère pas la fonction comme terminée tant que nous n'appelons pas la fonction callback fonction.

Le contexte

Dans Context, nous pouvons spécifier le contexte de la fonction à exécuter dans. Cela comprend généralement les éléments suivants -

  • Si la fonction doit être exécutée sur un CPU ou un GPU.

  • Si nous spécifions GPU dans le contexte, alors quel GPU utiliser.

  • Il existe une énorme différence entre Context et RunContext. Le contexte a le type d'appareil et l'ID d'appareil, tandis que RunContext a les informations qui ne peuvent être décidées que pendant l'exécution.

VarHandle

VarHandle, utilisé pour spécifier les dépendances des fonctions, est comme un jeton (notamment fourni par le moteur d'exécution) que nous pouvons utiliser pour représenter les ressources externes que la fonction peut modifier ou utiliser.

Mais la question se pose, pourquoi devons-nous utiliser VarHandle? C'est parce que le moteur Apache MXNet est conçu pour être découplé des autres modules MXNet.

Voici quelques points importants sur VarHandle -

  • Il est léger, donc créer, supprimer ou copier une variable entraîne peu de frais d'exploitation.

  • Nous devons spécifier les variables immuables c'est-à-dire les variables qui seront utilisées dans le const_vars.

  • Nous devons spécifier les variables mutables c'est-à-dire les variables qui seront modifiées dans le mutate_vars.

  • La règle utilisée par le moteur d'exécution pour résoudre les dépendances entre les fonctions est que l'exécution de deux fonctions quelconques lorsque l'une d'elles modifie au moins une variable commune est sérialisée dans leur ordre de transmission.

  • Pour créer une nouvelle variable, nous pouvons utiliser le NewVar() API.

  • Pour supprimer une variable, nous pouvons utiliser le PushDelete API.

Comprenons son fonctionnement avec un exemple simple -

Supposons que nous ayons deux fonctions à savoir F1 et F2 et qu'elles mutent toutes les deux la variable à savoir V2. Dans ce cas, F2 est garanti pour être exécuté après F1 si F2 est poussé après F1. D'un autre côté, si F1 et F2 utilisent tous les deux V2, leur ordre d'exécution réel pourrait être aléatoire.

Poussez et attendez

Push et wait sont deux API plus utiles du moteur d'exécution.

Voici deux caractéristiques importantes de Push API:

  • Toutes les API Push sont asynchrones, ce qui signifie que l'appel d'API retourne immédiatement, que la fonction poussée soit terminée ou non.

  • L'API Push n'est pas thread-safe, ce qui signifie qu'un seul thread doit effectuer des appels d'API du moteur à la fois.

Maintenant, si nous parlons d'API Wait, les points suivants le représentent -

  • Si un utilisateur veut attendre qu'une fonction spécifique soit terminée, il doit inclure une fonction de rappel dans la fermeture. Une fois inclus, appelez la fonction à la fin de la fonction.

  • D'un autre côté, si un utilisateur veut attendre que toutes les fonctions impliquant une certaine variable se terminent, il / elle doit utiliser WaitForVar(var) API.

  • Si quelqu'un veut attendre que toutes les fonctions poussées soient terminées, utilisez le WaitForAll () API.

  • Utilisé pour spécifier les dépendances des fonctions, c'est comme un jeton.

Les opérateurs

Operator dans Apache MXNet est une classe qui contient la logique de calcul réelle ainsi que des informations auxiliaires et aide le système à effectuer l'optimisation.

Interface opérateur

Forward est l'interface opérateur principale dont la syntaxe est la suivante:

virtual void Forward(const OpContext &ctx,
const std::vector<TBlob> &in_data,
const std::vector<OpReqType> &req,
const std::vector<TBlob> &out_data,
const std::vector<TBlob> &aux_states) = 0;

La structure de OpContext, défini dans Forward() est comme suit:

struct OpContext {
   int is_train;
   RunContext run_ctx;
   std::vector<Resource> requested;
}

le OpContextdécrit l'état de l'opérateur (que ce soit en train ou en phase de test), sur quel appareil l'opérateur doit être utilisé ainsi que les ressources demandées. deux API plus utiles du moteur d'exécution.

De ce qui précède Forward interface de base, nous pouvons comprendre les ressources demandées comme suit -

  • in_data et out_data représentent les tenseurs d'entrée et de sortie.

  • req indique comment le résultat du calcul est écrit dans le out_data.

le OpReqType peut être défini comme -

enum OpReqType {
   kNullOp,
   kWriteTo,
   kWriteInplace,
   kAddTo
};

Comme Forward opérateur, nous pouvons éventuellement implémenter le Backward interface comme suit -

virtual void Backward(const OpContext &ctx,
const std::vector<TBlob> &out_grad,
const std::vector<TBlob> &in_data,
const std::vector<TBlob> &out_data,
const std::vector<OpReqType> &req,
const std::vector<TBlob> &in_grad,
const std::vector<TBlob> &aux_states);

Diverses tâches

Operator l'interface permet aux utilisateurs d'effectuer les tâches suivantes -

  • L'utilisateur peut spécifier des mises à jour sur place et réduire le coût d'allocation de mémoire

  • Afin de le rendre plus propre, l'utilisateur peut masquer certains arguments internes de Python.

  • L'utilisateur peut définir la relation entre les tenseurs et les tenseurs de sortie.

  • Pour effectuer le calcul, l'utilisateur peut acquérir un espace temporaire supplémentaire du système.

Propriété de l'opérateur

Comme nous sommes conscients que dans le réseau de neurones convolutifs (CNN), une convolution a plusieurs implémentations. Pour obtenir les meilleures performances de leur part, nous pourrions vouloir basculer entre ces différentes circonvolutions.

C'est la raison pour laquelle Apache MXNet sépare l'interface sémantique de l'opérateur de l'interface d'implémentation. Cette séparation se fait sous la forme deOperatorProperty classe qui se compose des éléments suivants -

InferShape - L'interface InferShape a deux objectifs comme indiqué ci-dessous:

  • Le premier objectif est d'indiquer au système la taille de chaque tenseur d'entrée et de sortie afin que l'espace puisse être alloué avant Forward et Backward appel.

  • Le deuxième objectif est d'effectuer une vérification de la taille pour s'assurer qu'il n'y a pas d'erreur avant de démarrer.

La syntaxe est donnée ci-dessous -

virtual bool InferShape(mxnet::ShapeVector *in_shape,
mxnet::ShapeVector *out_shape,
mxnet::ShapeVector *aux_shape) const = 0;

Request Resource- Et si votre système pouvait gérer l'espace de travail de calcul pour des opérations telles que cudnnConvolutionForward? Votre système peut effectuer des optimisations telles que la réutilisation de l'espace et bien d'autres. Ici, MXNet y parvient facilement en suivant deux interfaces -

virtual std::vector<ResourceRequest> ForwardResource(
   const mxnet::ShapeVector &in_shape) const;
virtual std::vector<ResourceRequest> BackwardResource(
   const mxnet::ShapeVector &in_shape) const;

Mais, et si le ForwardResource et BackwardResourcerenvoyer des tableaux non vides? Dans ce cas, le système offre les ressources correspondantes viactx paramètre dans le Forward et Backward interface de Operator.

Backward dependency - Apache MXNet dispose de deux signatures d'opérateurs différentes pour gérer la dépendance vers l'arrière -

void FullyConnectedForward(TBlob weight, TBlob in_data, TBlob out_data);
void FullyConnectedBackward(TBlob weight, TBlob in_data, TBlob out_grad, TBlob in_grad);
void PoolingForward(TBlob in_data, TBlob out_data);
void PoolingBackward(TBlob in_data, TBlob out_data, TBlob out_grad, TBlob in_grad);

Ici, les deux points importants à noter -

  • Le out_data dans FullyConnectedForward n'est pas utilisé par FullyConnectedBackward, et

  • PoolingBackward requiert tous les arguments de PoolingForward.

C'est pourquoi pour FullyConnectedForward, la out_datatenseur une fois consommé pourrait être libéré en toute sécurité car la fonction arrière n'en aura pas besoin. Avec l'aide de ce système, j'ai pu collecter des tenseurs le plus tôt possible.

In place Option- Apache MXNet fournit une autre interface aux utilisateurs pour économiser le coût d'allocation de mémoire. L'interface convient aux opérations élémentaires dans lesquelles les tenseurs d'entrée et de sortie ont la même forme.

Voici la syntaxe pour spécifier la mise à jour sur place -

Exemple de création d'un opérateur

Avec l'aide d'OperatorProperty, nous pouvons créer un opérateur. Pour ce faire, suivez les étapes ci-dessous -

virtual std::vector<std::pair<int, void*>> ElewiseOpProperty::ForwardInplaceOption(
   const std::vector<int> &in_data,
   const std::vector<void*> &out_data) 
const {
   return { {in_data[0], out_data[0]} };
}
virtual std::vector<std::pair<int, void*>> ElewiseOpProperty::BackwardInplaceOption(
   const std::vector<int> &out_grad,
   const std::vector<int> &in_data,
   const std::vector<int> &out_data,
   const std::vector<void*> &in_grad) 
const {
   return { {out_grad[0], in_grad[0]} }
}

Étape 1

Create Operator

Commencez par implémenter l'interface suivante dans OperatorProperty:

virtual Operator* CreateOperator(Context ctx) const = 0;

L'exemple est donné ci-dessous -

class ConvolutionOp {
   public:
      void Forward( ... ) { ... }
      void Backward( ... ) { ... }
};
class ConvolutionOpProperty : public OperatorProperty {
   public:
      Operator* CreateOperator(Context ctx) const {
         return new ConvolutionOp;
      }
};

Étape 2

Parameterize Operator

Si vous allez implémenter un opérateur de convolution, il est obligatoire de connaître la taille du noyau, la taille de la foulée, la taille du rembourrage, etc. Pourquoi, car ces paramètres doivent être passés à l'opérateur avant d'appelerForward ou backward interface.

Pour cela, nous devons définir un ConvolutionParam structure comme ci-dessous -

#include <dmlc/parameter.h>
struct ConvolutionParam : public dmlc::Parameter<ConvolutionParam> {
   mxnet::TShape kernel, stride, pad;
   uint32_t num_filter, num_group, workspace;
   bool no_bias;
};

Maintenant, nous devons mettre ça dans ConvolutionOpProperty et passez-le à l'opérateur comme suit -

class ConvolutionOp {
   public:
      ConvolutionOp(ConvolutionParam p): param_(p) {}
      void Forward( ... ) { ... }
      void Backward( ... ) { ... }
   private:
      ConvolutionParam param_;
};
class ConvolutionOpProperty : public OperatorProperty {
   public:
      void Init(const vector<pair<string, string>& kwargs) {
         // initialize param_ using kwargs
      }
      Operator* CreateOperator(Context ctx) const {
         return new ConvolutionOp(param_);
      }
   private:
      ConvolutionParam param_;
};

Étape 3

Register the Operator Property Class and the Parameter Class to Apache MXNet

Enfin, nous devons enregistrer la classe de propriété de l'opérateur et la classe de paramètre dans MXNet. Cela peut être fait à l'aide des macros suivantes -

DMLC_REGISTER_PARAMETER(ConvolutionParam);
MXNET_REGISTER_OP_PROPERTY(Convolution, ConvolutionOpProperty);

Dans la macro ci-dessus, le premier argument est la chaîne de nom et le second est le nom de la classe de propriété.

Ce chapitre fournit des informations sur l'interface de programmation d'application (API) unifiée d'opérateur dans Apache MXNet.

SimpleOp

SimpleOp est une nouvelle API d'opérateur unifiée qui unifie différents processus d'appel. Une fois invoqué, il revient aux éléments fondamentaux des opérateurs. L'opérateur unifié est spécialement conçu pour les opérations unaires et binaires. C'est parce que la plupart des opérateurs mathématiques s'occupent d'un ou deux opérandes et que plusieurs opérandes rendent l'optimisation, liée à la dépendance, utile.

Nous allons comprendre son opérateur unifié SimpleOp fonctionnant à l'aide d'un exemple. Dans cet exemple, nous allons créer un opérateur fonctionnant comme unsmooth l1 loss, qui est un mélange de pertes l1 et l2. Nous pouvons définir et écrire la perte comme indiqué ci-dessous -

loss = outside_weight .* f(inside_weight .* (data - label))
grad = outside_weight .* inside_weight .* f'(inside_weight .* (data - label))

Ici, dans l'exemple ci-dessus,

  • . * représente la multiplication par élément

  • f, f’ est la fonction de perte l1 lisse dont nous supposons qu'elle est mshadow.

Il semble impossible d'implémenter cette perte particulière en tant qu'opérateur unaire ou binaire, mais MXNet fournit à ses utilisateurs une différenciation automatique en exécution symbolique qui simplifie directement la perte en f et f '. C'est pourquoi nous pouvons certainement implémenter cette perte particulière en tant qu'opérateur unaire.

Définition des formes

Comme nous le savons, MXNet mshadow librarynécessite une allocation de mémoire explicite, nous devons donc fournir toutes les formes de données avant tout calcul. Avant de définir les fonctions et le gradient, nous devons fournir la cohérence de la forme d'entrée et la forme de sortie comme suit:

typedef mxnet::TShape (*UnaryShapeFunction)(const mxnet::TShape& src,
const EnvArguments& env);
   typedef mxnet::TShape (*BinaryShapeFunction)(const mxnet::TShape& lhs,
const mxnet::TShape& rhs,
const EnvArguments& env);

La fonction mxnet :: Tshape est utilisée pour vérifier la forme des données d'entrée et la forme des données de sortie désignées. Dans le cas où vous ne définissez pas cette fonction, la forme de sortie par défaut serait la même que la forme d'entrée. Par exemple, dans le cas d'un opérateur binaire, la forme de lhs et rhs est cochée par défaut comme étant la même.

Passons maintenant à notre smooth l1 loss example. Pour cela, nous devons définir un XPU vers cpu ou gpu dans l'implémentation de l'en-tête smooth_l1_unary-inl.h. La raison est de réutiliser le même code dans smooth_l1_unary.cc et smooth_l1_unary.cu.

#include <mxnet/operator_util.h>
   #if defined(__CUDACC__)
      #define XPU gpu
   #else
      #define XPU cpu
#endif

Comme dans notre smooth l1 loss example,la sortie a la même forme que la source, nous pouvons utiliser le comportement par défaut. Il peut s'écrire comme suit -

inline mxnet::TShape SmoothL1Shape_(const mxnet::TShape& src,const EnvArguments& env) {
   return mxnet::TShape(src);
}

Définition des fonctions

Nous pouvons créer une fonction unaire ou binaire avec une entrée comme suit -

typedef void (*UnaryFunction)(const TBlob& src,
   const EnvArguments& env,
   TBlob* ret,
   OpReqType req,
   RunContext ctx);
typedef void (*BinaryFunction)(const TBlob& lhs,
   const TBlob& rhs,
   const EnvArguments& env,
   TBlob* ret,
   OpReqType req,
   RunContext ctx);

Voici le RunContext ctx struct qui contient les informations nécessaires lors de l'exécution pour l'exécution -

struct RunContext {
   void *stream; // the stream of the device, can be NULL or Stream<gpu>* in GPU mode
   template<typename xpu> inline mshadow::Stream<xpu>* get_stream() // get mshadow stream from Context
} // namespace mxnet

Voyons maintenant comment nous pouvons écrire les résultats du calcul dans ret.

enum OpReqType {
   kNullOp, // no operation, do not write anything
   kWriteTo, // write gradient to provided space
   kWriteInplace, // perform an in-place write
   kAddTo // add to the provided space
};

Maintenant, passons à notre smooth l1 loss example. Pour cela, nous utiliserons UnaryFunction pour définir la fonction de cet opérateur comme suit:

template<typename xpu>
void SmoothL1Forward_(const TBlob& src,
   const EnvArguments& env,
   TBlob *ret,
   OpReqType req,
RunContext ctx) {
   using namespace mshadow;
   using namespace mshadow::expr;
   mshadow::Stream<xpu> *s = ctx.get_stream<xpu>();
   real_t sigma2 = env.scalar * env.scalar;
   MSHADOW_TYPE_SWITCH(ret->type_flag_, DType, {
      mshadow::Tensor<xpu, 2, DType> out = ret->get<xpu, 2, DType>(s);
      mshadow::Tensor<xpu, 2, DType> in = src.get<xpu, 2, DType>(s);
      ASSIGN_DISPATCH(out, req,
      F<mshadow_op::smooth_l1_loss>(in, ScalarExp<DType>(sigma2)));
   });
}

Définition des dégradés

Sauf Input, TBlob, et OpReqTypesont doublées, les fonctions Gradients des opérateurs binaires ont une structure similaire. Voyons ci-dessous, où nous avons créé une fonction de dégradé avec différents types d'entrée:

// depending only on out_grad
typedef void (*UnaryGradFunctionT0)(const OutputGrad& out_grad,
   const EnvArguments& env,
   TBlob* in_grad,
   OpReqType req,
   RunContext ctx);
// depending only on out_value
typedef void (*UnaryGradFunctionT1)(const OutputGrad& out_grad,
   const OutputValue& out_value,
   const EnvArguments& env,
   TBlob* in_grad,
   OpReqType req,
   RunContext ctx);
// depending only on in_data
typedef void (*UnaryGradFunctionT2)(const OutputGrad& out_grad,
   const Input0& in_data0,
   const EnvArguments& env,
   TBlob* in_grad,
   OpReqType req,
   RunContext ctx);

Tel que défini ci-dessus Input0, Input, OutputValue, et OutputGrad tous partagent la structure de GradientFunctionArgument. Il est défini comme suit -

struct GradFunctionArgument {
   TBlob data;
}

Passons maintenant à notre smooth l1 loss example. Pour que cela active la règle de la chaîne du gradient, nous devons multiplierout_grad du haut au résultat de in_grad.

template<typename xpu>
void SmoothL1BackwardUseIn_(const OutputGrad& out_grad, const Input0& in_data0,
   const EnvArguments& env,
   TBlob *in_grad,
   OpReqType req,
   RunContext ctx) {
   using namespace mshadow;
   using namespace mshadow::expr;
   mshadow::Stream<xpu> *s = ctx.get_stream<xpu>();
   real_t sigma2 = env.scalar * env.scalar;
      MSHADOW_TYPE_SWITCH(in_grad->type_flag_, DType, {
      mshadow::Tensor<xpu, 2, DType> src = in_data0.data.get<xpu, 2, DType>(s);
      mshadow::Tensor<xpu, 2, DType> ograd = out_grad.data.get<xpu, 2, DType>(s);
      mshadow::Tensor<xpu, 2, DType> igrad = in_grad->get<xpu, 2, DType>(s);
      ASSIGN_DISPATCH(igrad, req,
      ograd * F<mshadow_op::smooth_l1_gradient>(src, ScalarExp<DType>(sigma2)));
   });
}

Enregistrer SimpleOp sur MXNet

Une fois que nous avons créé la forme, la fonction et le dégradé, nous devons les restaurer à la fois dans un opérateur NDArray et dans un opérateur symbolique. Pour cela, nous pouvons utiliser la macro d'enregistrement comme suit -

MXNET_REGISTER_SIMPLE_OP(Name, DEV)
   .set_shape_function(Shape)
   .set_function(DEV::kDevMask, Function<XPU>, SimpleOpInplaceOption)
   .set_gradient(DEV::kDevMask, Gradient<XPU>, SimpleOpInplaceOption)
   .describe("description");

le SimpleOpInplaceOption peut être défini comme suit -

enum SimpleOpInplaceOption {
   kNoInplace, // do not allow inplace in arguments
   kInplaceInOut, // allow inplace in with out (unary)
   kInplaceOutIn, // allow inplace out_grad with in_grad (unary)
   kInplaceLhsOut, // allow inplace left operand with out (binary)

   kInplaceOutLhs // allow inplace out_grad with lhs_grad (binary)
};

Passons maintenant à notre smooth l1 loss example. Pour cela, nous avons une fonction de gradient qui s'appuie sur des données d'entrée afin que la fonction ne puisse pas être écrite en place.

MXNET_REGISTER_SIMPLE_OP(smooth_l1, XPU)
.set_function(XPU::kDevMask, SmoothL1Forward_<XPU>, kNoInplace)
.set_gradient(XPU::kDevMask, SmoothL1BackwardUseIn_<XPU>, kInplaceOutIn)
.set_enable_scalar(true)
.describe("Calculate Smooth L1 Loss(lhs, scalar)");

SimpleOp sur EnvArguments

Comme nous le savons, certaines opérations peuvent nécessiter les éléments suivants:

  • Un scalaire comme entrée telle qu'une échelle de gradient

  • Un ensemble d'arguments de mots clés contrôlant le comportement

  • Un espace temporaire pour accélérer les calculs.

L'avantage d'utiliser EnvArguments est qu'il fournit des arguments et des ressources supplémentaires pour rendre les calculs plus évolutifs et plus efficaces.

Exemple

Définissons d'abord la structure comme ci-dessous -

struct EnvArguments {
   real_t scalar; // scalar argument, if enabled
   std::vector<std::pair<std::string, std::string> > kwargs; // keyword arguments
   std::vector<Resource> resource; // pointer to the resources requested
};

Ensuite, nous devons demander des ressources supplémentaires telles que mshadow::Random<xpu> et espace mémoire temporaire de EnvArguments.resource. Cela peut être fait comme suit -

struct ResourceRequest {
   enum Type { // Resource type, indicating what the pointer type is
      kRandom, // mshadow::Random<xpu> object
      kTempSpace // A dynamic temp space that can be arbitrary size
   };
   Type type; // type of resources
};

Maintenant, l'enregistrement demandera la demande de ressource déclarée à partir de mxnet::ResourceManager. Après cela, il placera les ressources dans std::vector<Resource> resource in EnvAgruments.

Nous pouvons accéder aux ressources à l'aide du code suivant -

auto tmp_space_res = env.resources[0].get_space(some_shape, some_stream);
auto rand_res = env.resources[0].get_random(some_stream);

Si vous voyez dans notre exemple de perte l1 lisse, une entrée scalaire est nécessaire pour marquer le point de retournement d'une fonction de perte. C'est pourquoi dans le processus d'inscription, nous utilisonsset_enable_scalar(true), et env.scalar dans les déclarations de fonction et de gradient.

Opération de tenseur de bâtiment

Ici se pose la question de savoir pourquoi nous devons créer des opérations tensorielles? Les raisons sont les suivantes -

  • Le calcul utilise la bibliothèque mshadow et nous n'avons parfois pas de fonctions facilement disponibles.

  • Si une opération n'est pas effectuée de manière élémentaire telle que la perte et le gradient softmax.

Exemple

Ici, nous utilisons l'exemple de perte l1 lisse ci-dessus. Nous allons créer deux mappeurs, à savoir les cas scalaires de perte et de gradient l1 lisses:

namespace mshadow_op {
   struct smooth_l1_loss {
      // a is x, b is sigma2
      MSHADOW_XINLINE static real_t Map(real_t a, real_t b) {
         if (a > 1.0f / b) {
            return a - 0.5f / b;
         } else if (a < -1.0f / b) {
            return -a - 0.5f / b;
         } else {
            return 0.5f * a * a * b;
         }
      }
   };
}

Ce chapitre concerne la formation distribuée dans Apache MXNet. Commençons par comprendre quels sont les modes de calcul dans MXNet.

Modes de calcul

MXNet, une bibliothèque ML multilingue, propose à ses utilisateurs les deux modes de calcul suivants:

Mode impératif

Ce mode de calcul expose une interface comme l'API NumPy. Par exemple, dans MXNet, utilisez le code impératif suivant pour construire un tenseur de zéros à la fois sur le CPU et le GPU -

import mxnet as mx
tensor_cpu = mx.nd.zeros((100,), ctx=mx.cpu())
tensor_gpu= mx.nd.zeros((100,), ctx=mx.gpu(0))

Comme nous le voyons dans le code ci-dessus, MXNets spécifie l'emplacement où tenir le tenseur, soit dans le processeur ou le périphérique GPU. Dans l'exemple ci-dessus, il se trouve à l'emplacement 0. MXNet réalise une utilisation incroyable de l'appareil, car tous les calculs se font paresseusement au lieu d'être instantanément.

Mode symbolique

Bien que le mode impératif soit assez utile, mais l'un des inconvénients de ce mode est sa rigidité, c'est-à-dire que tous les calculs doivent être connus à l'avance avec des structures de données prédéfinies.

D'autre part, le mode symbolique expose un graphe de calcul comme TensorFlow. Il supprime l'inconvénient de l'API impérative en permettant à MXNet de travailler avec des symboles ou des variables au lieu de structures de données fixes / prédéfinies. Ensuite, les symboles peuvent être interprétés comme un ensemble d'opérations comme suit -

import mxnet as mx
x = mx.sym.Variable(“X”)
y = mx.sym.Variable(“Y”)
z = (x+y)
m = z/100

Types de parallélisme

Apache MXNet prend en charge la formation distribuée. Cela nous permet d'exploiter plusieurs machines pour une formation plus rapide et efficace.

Voici les deux façons dont nous pouvons répartir la charge de travail de la formation d'un NN sur plusieurs appareils, CPU ou GPU -

Parallélisme des données

Dans ce type de parallélisme, chaque appareil stocke une copie complète du modèle et fonctionne avec une partie différente de l'ensemble de données. Les appareils mettent également à jour un modèle partagé collectivement. Nous pouvons localiser tous les appareils sur une seule machine ou sur plusieurs machines.

Parallélisme de modèle

C'est un autre type de parallélisme, qui est pratique lorsque les modèles sont si volumineux qu'ils ne rentrent pas dans la mémoire de l'appareil. Dans le parallélisme de modèle, différents périphériques se voient attribuer la tâche d'apprendre différentes parties du modèle. Le point important à noter ici est qu'actuellement, Apache MXNet ne prend en charge le parallélisme de modèle que sur une seule machine.

Fonctionnement de la formation distribuée

Les concepts donnés ci-dessous sont la clé pour comprendre le fonctionnement de la formation distribuée dans Apache MXNet -

Types de processus

Les processus communiquent entre eux pour accomplir la formation d'un modèle. Apache MXNet a les trois processus suivants -

Ouvrier

Le travail du nœud de travail consiste à effectuer une formation sur un lot d'échantillons de formation. Les nœuds de travail extrairont les poids du serveur avant de traiter chaque lot. Les nœuds Worker enverront des dégradés au serveur, une fois le lot traité.

Serveur

MXNet peut avoir plusieurs serveurs pour stocker les paramètres du modèle et pour communiquer avec les nœuds de travail.

Planificateur

Le rôle du planificateur est de configurer le cluster, ce qui inclut l'attente des messages que chaque nœud est arrivé et quel port le nœud écoute. Après avoir configuré le cluster, le planificateur informe tous les processus de chaque autre nœud du cluster. C'est parce que les processus peuvent communiquer entre eux. Il n'y a qu'un seul planificateur.

Magasin KV

KV stores signifie Key-Valueboutique. C'est un composant essentiel utilisé pour la formation multi-appareils. C'est important car, la communication des paramètres entre les appareils sur une seule ou entre plusieurs machines est transmise via un ou plusieurs serveurs avec un KVStore pour les paramètres. Comprenons le fonctionnement de KVStore à l'aide des points suivants -

  • Chaque valeur dans KVStore est représentée par un key et un value.

  • Chaque tableau de paramètres du réseau se voit attribuer un key et les poids de ce tableau de paramètres sont référencés par value.

  • Après cela, les nœuds de travail pushdégradés après le traitement d'un lot. Ils aussipull poids mis à jour avant de traiter un nouveau lot.

La notion de serveur KVStore n'existe que pendant l'entraînement distribué et le mode distribué de celui-ci est activé en appelant mxnet.kvstore.create fonction avec un argument chaîne contenant le mot dist -

kv = mxnet.kvstore.create(‘dist_sync’)

Distribution des clés

Il n'est pas nécessaire que tous les serveurs stockent tous les paramètres du tableau ou des clés, mais ils sont répartis sur différents serveurs. Une telle distribution de clés sur différents serveurs est gérée de manière transparente par le KVStore et la décision de savoir quel serveur stocke une clé spécifique est prise au hasard.

KVStore, comme indiqué ci-dessus, garantit que chaque fois que la clé est tirée, sa demande est envoyée à ce serveur, qui a la valeur correspondante. Et si la valeur d'une clé est élevée? Dans ce cas, il peut être partagé entre différents serveurs.

Diviser les données d'entraînement

En tant qu'utilisateurs, nous voulons que chaque machine travaille sur différentes parties de l'ensemble de données, en particulier, lors de l'exécution d'un entraînement distribué en mode parallèle de données. Nous savons que, pour diviser un lot d'échantillons fournis par l'itérateur de données pour la formation parallèle de données sur un seul travailleur, nous pouvons utilisermxnet.gluon.utils.split_and_load puis, chargez chaque partie du lot sur l'appareil qui le traitera davantage.

En revanche, en cas de formation distribuée, au début, nous devons diviser l'ensemble de données en ndifférentes parties de sorte que chaque travailleur obtient une partie différente. Une fois obtenu, chaque travailleur peut alors utilisersplit_and_loadpour diviser à nouveau cette partie de l'ensemble de données entre différents appareils sur une seule machine. Tout cela se passe par l'itérateur de données.mxnet.io.MNISTIterator et mxnet.io.ImageRecordIter sont deux de ces itérateurs dans MXNet qui prennent en charge cette fonctionnalité.

Mise à jour des poids

Pour mettre à jour les poids, KVStore prend en charge les deux modes suivants -

  • La première méthode regroupe les gradients et met à jour les poids en utilisant ces gradients.

  • Dans la seconde méthode, le serveur agrège uniquement les dégradés.

Si vous utilisez Gluon, il existe une option pour choisir entre les méthodes indiquées ci-dessus en passant update_on_kvstorevariable. Comprenons-le en créant letrainer objet comme suit -

trainer = gluon.Trainer(net.collect_params(), optimizer='sgd',
   optimizer_params={'learning_rate': opt.lr,
      'wd': opt.wd,
      'momentum': opt.momentum,
      'multi_precision': True},
      kvstore=kv,
   update_on_kvstore=True)

Modes de formation distribuée

Si la chaîne de création KVStore contient le mot dist, cela signifie que la formation distribuée est activée. Voici différents modes de formation distribuée qui peuvent être activés en utilisant différents types de KVStore -

dist_sync

Comme son nom l'indique, il désigne un entraînement distribué synchrone. En cela, tous les travailleurs utilisent le même ensemble synchronisé de paramètres de modèle au début de chaque lot.

L'inconvénient de ce mode est qu'après chaque lot, le serveur doit attendre de recevoir des dégradés de chaque worker avant de mettre à jour les paramètres du modèle. Cela signifie que si un travailleur tombe en panne, cela arrêtera la progression de tous les travailleurs.

dist_async

Comme son nom l'indique, il désigne un entraînement distribué synchrone. En cela, le serveur reçoit des dégradés d'un travailleur et met immédiatement à jour son magasin. Le serveur utilise le magasin mis à jour pour répondre à toute autre extraction.

L'avantage, par rapport à dist_sync mode, est qu'un travailleur qui termine le traitement d'un lot peut extraire les paramètres actuels du serveur et démarrer le lot suivant. Le travailleur peut le faire, même si l'autre travailleur n'a pas encore terminé le traitement du lot précédent. Il est également plus rapide que le mode dist_sync car il peut prendre plus d'époques pour converger sans aucun coût de synchronisation.

dist_sync_device

Ce mode est le même que dist_syncmode. La seule différence est que, lorsque plusieurs GPU sont utilisés sur chaque nœuddist_sync_device agrège les gradients et met à jour les poids sur le GPU alors que, dist_sync agrège les gradients et met à jour les poids sur la mémoire du processeur.

Cela réduit les communications coûteuses entre le GPU et le CPU. C'est pourquoi, c'est plus rapide quedist_sync. L'inconvénient est qu'il augmente l'utilisation de la mémoire sur le GPU.

dist_async_device

Ce mode fonctionne de la même manière que dist_sync_device mode, mais en mode asynchrone.

Dans ce chapitre, nous découvrirons les packages Python disponibles dans Apache MXNet.

Packages MXNet Python importants

MXNet a les packages Python importants suivants dont nous discuterons un par un -

  • Autograd (différenciation automatique)

  • NDArray

  • KVStore

  • Gluon

  • Visualization

Commençons par Autograd Package Python pour Apache MXNet.

Autograd

Autograd signifie automatic differentiationutilisé pour rétropropropager les gradients de la métrique de perte à chacun des paramètres. Parallèlement à la rétropropagation, il utilise une approche de programmation dynamique pour calculer efficacement les gradients. Elle est également appelée différenciation automatique en mode inverse. Cette technique est très efficace dans les situations de «fan-in» où de nombreux paramètres affectent une seule métrique de perte.

Que sont les dégradés?

Les dégradés sont les fondamentaux du processus de formation des réseaux neuronaux. Ils nous disent essentiellement comment modifier les paramètres du réseau pour améliorer ses performances.

Comme on le sait, les réseaux de neurones (NN) sont composés d'opérateurs tels que sommes, produit, convolutions, etc. Ces opérateurs, pour leurs calculs, utilisent des paramètres tels que les poids dans les noyaux de convolution. Nous devrions avoir à trouver les valeurs optimales pour ces paramètres et les gradients nous montrent le chemin et nous conduisent également à la solution.

Nous nous intéressons à l'effet du changement d'un paramètre sur les performances du réseau et les gradients nous indiquent à quel point une variable donnée augmente ou diminue lorsque nous changeons une variable dont elle dépend. Les performances sont généralement définies en utilisant une métrique de perte que nous essayons de minimiser. Par exemple, pour la régression, nous pourrions essayer de minimiserL2 perte entre nos prédictions et la valeur exacte, alors que pour la classification, nous pourrions minimiser cross-entropy loss.

Une fois que nous calculons le gradient de chaque paramètre par rapport à la perte, nous pouvons alors utiliser un optimiseur, tel que la descente de gradient stochastique.

Comment calculer les dégradés?

Nous avons les options suivantes pour calculer les dégradés -

  • Symbolic Differentiation- La toute première option est la différenciation symbolique, qui calcule les formules pour chaque gradient. L'inconvénient de cette méthode est qu'elle conduira rapidement à des formules incroyablement longues à mesure que le réseau s'approfondit et que les opérateurs deviennent plus complexes.

  • Finite Differencing- Une autre option consiste à utiliser la différenciation finie qui essaie de légères différences sur chaque paramètre et voit comment la métrique de perte répond. L'inconvénient de cette méthode est qu'elle serait coûteuse en calcul et pourrait avoir une faible précision numérique.

  • Automatic differentiation- La solution aux inconvénients des méthodes ci-dessus est d'utiliser la différenciation automatique pour rétropropropager les gradients de la métrique de perte vers chacun des paramètres. La propagation nous permet une approche de programmation dynamique pour calculer efficacement les gradients. Cette méthode est également appelée différenciation automatique en mode inverse.

Différenciation automatique (autograd)

Ici, nous allons comprendre en détail le fonctionnement de l'autogradation. Cela fonctionne essentiellement en deux étapes -

Stage 1 - Cette étape s'appelle ‘Forward Pass’de la formation. Comme son nom l'indique, à cette étape, il crée l'enregistrement de l'opérateur utilisé par le réseau pour faire des prédictions et calculer la métrique de perte.

Stage 2 - Cette étape s'appelle ‘Backward Pass’de la formation. Comme son nom l'indique, à ce stade, il fonctionne à rebours à travers ce disque. À reculons, il évalue les dérivées partielles de chaque opérateur, jusqu'au paramètre réseau.

Avantages de l'autograd

Voici les avantages de l'utilisation de la différenciation automatique (autograd) -

  • Flexible- La flexibilité, qu'elle nous donne lors de la définition de notre réseau, est l'un des énormes avantages de l'utilisation d'autograd. Nous pouvons changer les opérations à chaque itération. Ceux-ci sont appelés les graphes dynamiques, qui sont beaucoup plus complexes à implémenter dans des frameworks nécessitant un graphe statique. Autograd, même dans de tels cas, pourra toujours propager correctement les dégradés.

  • Automatic- Autograd est automatique, c'est-à-dire que les complexités de la procédure de rétropropagation sont prises en charge par lui pour vous. Nous avons juste besoin de spécifier les gradients qui nous intéressent à calculer.

  • Efficient - Autogard calcule les dégradés très efficacement.

  • Can use native Python control flow operators- Nous pouvons utiliser les opérateurs de flux de contrôle Python natifs tels que la condition if et la boucle while. L'autograde sera toujours en mesure de rétropropropager les dégradés de manière efficace et correcte.

Utilisation d'autograd dans MXNet Gluon

Ici, à l'aide d'un exemple, nous verrons comment nous pouvons utiliser autograd dans MXNet Gluon.

Exemple d'implémentation

Dans l'exemple suivant, nous allons implémenter le modèle de régression à deux couches. Après la mise en œuvre, nous utiliserons autograd pour calculer automatiquement le gradient de la perte en référence à chacun des paramètres de poids -

Importez d'abord l'autogrard et les autres packages requis comme suit -

from mxnet import autograd
import mxnet as mx
from mxnet.gluon.nn import HybridSequential, Dense
from mxnet.gluon.loss import L2Loss

Maintenant, nous devons définir le réseau comme suit -

N_net = HybridSequential()
N_net.add(Dense(units=3))
N_net.add(Dense(units=1))
N_net.initialize()

Nous devons maintenant définir la perte comme suit -

loss_function = L2Loss()

Ensuite, nous devons créer les données factices comme suit -

x = mx.nd.array([[0.5, 0.9]])
y = mx.nd.array([[1.5]])

Nous sommes maintenant prêts pour notre premier passage avant à travers le réseau. Nous voulons qu'autograd enregistre le graphe de calcul afin de pouvoir calculer les gradients. Pour cela, nous devons exécuter le code réseau dans le cadre deautograd.record contexte comme suit -

with autograd.record():
   y_hat = N_net(x)
   loss = loss_function(y_hat, y)

Maintenant, nous sommes prêts pour la passe en arrière, que nous commençons par appeler la méthode en arrière sur la quantité d'intérêt. La quantité d'intérêt dans notre exemple est la perte car nous essayons de calculer le gradient de perte en référence aux paramètres -

loss.backward()

Maintenant, nous avons des gradients pour chaque paramètre du réseau, qui seront utilisés par l'optimiseur pour mettre à jour la valeur du paramètre pour améliorer les performances. Voyons les dégradés de la 1ère couche comme suit -

N_net[0].weight.grad()

Output

La sortie est la suivante -

[[-0.00470527 -0.00846948]
[-0.03640365 -0.06552657]
[ 0.00800354 0.01440637]]
<NDArray 3x2 @cpu(0)>

Exemple d'implémentation complet

Vous trouverez ci-dessous l'exemple complet de mise en œuvre.

from mxnet import autograd
import mxnet as mx
from mxnet.gluon.nn import HybridSequential, Dense
from mxnet.gluon.loss import L2Loss
N_net = HybridSequential()
N_net.add(Dense(units=3))
N_net.add(Dense(units=1))
N_net.initialize()
loss_function = L2Loss()
x = mx.nd.array([[0.5, 0.9]])
y = mx.nd.array([[1.5]])
with autograd.record():
y_hat = N_net(x)
loss = loss_function(y_hat, y)
loss.backward()
N_net[0].weight.grad()

Dans ce chapitre, nous discuterons du format de tableau multidimensionnel de MXNet appelé ndarray.

Gestion des données avec NDArray

Tout d'abord, nous allons voir comment nous pouvons gérer les données avec NDArray. Voici les conditions préalables pour le même -

Conditions préalables

Pour comprendre comment nous pouvons gérer les données avec ce format de tableau multidimensionnel, nous devons remplir les conditions préalables suivantes:

  • MXNet installé dans un environnement Python

  • Python 2.7.x ou Python 3.x

Exemple d'implémentation

Comprenons les fonctionnalités de base à l'aide d'un exemple donné ci-dessous -

Tout d'abord, nous devons importer MXNet et ndarray à partir de MXNet comme suit -

import mxnet as mx
from mxnet import nd

Une fois que nous avons importé les bibliothèques nécessaires, nous utiliserons les fonctionnalités de base suivantes:

Un simple tableau 1-D avec une liste python

Example

x = nd.array([1,2,3,4,5,6,7,8,9,10])
print(x)

Output

La sortie est comme mentionné ci-dessous -

[ 1. 2. 3. 4. 5. 6. 7. 8. 9. 10.]
<NDArray 10 @cpu(0)>

Un tableau 2-D avec une liste python

Example

y = nd.array([[1,2,3,4,5,6,7,8,9,10], [1,2,3,4,5,6,7,8,9,10], [1,2,3,4,5,6,7,8,9,10]])
print(y)

Output

La sortie est comme indiqué ci-dessous -

[[ 1. 2. 3. 4. 5. 6. 7. 8. 9. 10.]
[ 1. 2. 3. 4. 5. 6. 7. 8. 9. 10.]
[ 1. 2. 3. 4. 5. 6. 7. 8. 9. 10.]]
<NDArray 3x10 @cpu(0)>

Créer un NDArray sans aucune initialisation

Ici, nous allons créer une matrice avec 3 lignes et 4 colonnes en utilisant .emptyfonction. Nous utiliserons également.full fonction, qui prendra un opérateur supplémentaire pour la valeur que vous voulez remplir dans le tableau.

Example

x = nd.empty((3, 4))
print(x)
x = nd.full((3,4), 8)
print(x)

Output

La sortie est donnée ci-dessous -

[[0.000e+00 0.000e+00 0.000e+00 0.000e+00]
 [0.000e+00 0.000e+00 2.887e-42 0.000e+00]
 [0.000e+00 0.000e+00 0.000e+00 0.000e+00]]
<NDArray 3x4 @cpu(0)>

[[8. 8. 8. 8.]
 [8. 8. 8. 8.]
 [8. 8. 8. 8.]]
<NDArray 3x4 @cpu(0)>

Matrice de tous les zéros avec la fonction .zeros

Example

x = nd.zeros((3, 8))
print(x)

Output

La sortie est la suivante -

[[0. 0. 0. 0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0. 0. 0. 0.]]
<NDArray 3x8 @cpu(0)>

Matrice de tous avec la fonction .ones

Example

x = nd.ones((3, 8))
print(x)

Output

La sortie est mentionnée ci-dessous -

[[1. 1. 1. 1. 1. 1. 1. 1.]
   [1. 1. 1. 1. 1. 1. 1. 1.]
   [1. 1. 1. 1. 1. 1. 1. 1.]]
<NDArray 3x8 @cpu(0)>

Création d'un tableau dont les valeurs sont échantillonnées au hasard

Example

y = nd.random_normal(0, 1, shape=(3, 4))
print(y)

Output

La sortie est donnée ci-dessous -

[[ 1.2673576 -2.0345826 -0.32537818 -1.4583491 ]
 [-0.11176403 1.3606371 -0.7889914 -0.17639421]
 [-0.2532185 -0.42614475 -0.12548696 1.4022992 ]]
<NDArray 3x4 @cpu(0)>

Recherche de la dimension de chaque NDArray

Example

y.shape

Output

La sortie est la suivante -

(3, 4)

Recherche de la taille de chaque NDArray

Example

y.size

Output

12

Recherche du type de données de chaque NDArray

Example

y.dtype

Output

numpy.float32

Opérations NDArray

Dans cette section, nous vous présenterons les opérations de matrice de MXNet. NDArray prend en charge un grand nombre d'opérations mathématiques standard ainsi que sur place.

Opérations mathématiques standard

Voici les opérations mathématiques standard prises en charge par NDArray -

Ajout par élément

Tout d'abord, nous devons importer MXNet et ndarray à partir de MXNet comme suit:

import mxnet as mx
from mxnet import nd
x = nd.ones((3, 5))
y = nd.random_normal(0, 1, shape=(3, 5))
print('x=', x)
print('y=', y)
x = x + y
print('x = x + y, x=', x)

Output

La sortie est donnée ici -

x=
[[1. 1. 1. 1. 1.]
[1. 1. 1. 1. 1.]
[1. 1. 1. 1. 1.]]
<NDArray 3x5 @cpu(0)>
y=
[[-1.0554522 -1.3118273 -0.14674698 0.641493 -0.73820823]
[ 2.031364 0.5932667 0.10228804 1.179526 -0.5444829 ]
[-0.34249446 1.1086396 1.2756858 -1.8332436 -0.5289873 ]]
<NDArray 3x5 @cpu(0)>
x = x + y, x=
[[-0.05545223 -0.3118273 0.853253 1.6414931 0.26179177]
[ 3.031364 1.5932667 1.102288 2.1795259 0.4555171 ]
[ 0.6575055 2.1086397 2.2756858 -0.8332436 0.4710127 ]]
<NDArray 3x5 @cpu(0)>

Multiplication par élément

Example

x = nd.array([1, 2, 3, 4])
y = nd.array([2, 2, 2, 1])
x * y

Output

Vous verrez la sortie suivante -

[2. 4. 6. 4.]
<NDArray 4 @cpu(0)>

Exponentiation

Example

nd.exp(x)

Output

Lorsque vous exécutez le code, vous verrez la sortie suivante:

[ 2.7182817 7.389056 20.085537 54.59815 ]
<NDArray 4 @cpu(0)>

Matrice transposée pour calculer un produit matrice-matrice

Example

nd.dot(x, y.T)

Output

Ci-dessous est la sortie du code -

[16.]
<NDArray 1 @cpu(0)>

Opérations sur place

Chaque fois que, dans l'exemple ci-dessus, nous avons exécuté une opération, nous avons alloué une nouvelle mémoire pour héberger son résultat.

Par exemple, si nous écrivons A = A + B, nous déréférencerons la matrice vers laquelle A pointait et la dirigerons à la place vers la mémoire nouvellement allouée. Comprenons-le avec l'exemple donné ci-dessous, en utilisant la fonction id () de Python -

print('y=', y)
print('id(y):', id(y))
y = y + x
print('after y=y+x, y=', y)
print('id(y):', id(y))

Output

Lors de l'exécution, vous recevrez la sortie suivante -

y=
[2. 2. 2. 1.]
<NDArray 4 @cpu(0)>
id(y): 2438905634376
after y=y+x, y=
[3. 4. 5. 5.]
<NDArray 4 @cpu(0)>
id(y): 2438905685664

En fait, nous pouvons également affecter le résultat à un tableau précédemment alloué comme suit -

print('x=', x)
z = nd.zeros_like(x)
print('z is zeros_like x, z=', z)
print('id(z):', id(z))
print('y=', y)
z[:] = x + y
print('z[:] = x + y, z=', z)
print('id(z) is the same as before:', id(z))

Output

La sortie est indiquée ci-dessous -

x=
[1. 2. 3. 4.]
<NDArray 4 @cpu(0)>
z is zeros_like x, z=
[0. 0. 0. 0.]
<NDArray 4 @cpu(0)>
id(z): 2438905790760
y=
[3. 4. 5. 5.]
<NDArray 4 @cpu(0)>
z[:] = x + y, z=
[4. 6. 8. 9.]
<NDArray 4 @cpu(0)>
id(z) is the same as before: 2438905790760

À partir de la sortie ci-dessus, nous pouvons voir que x + y allouera toujours un tampon temporaire pour stocker le résultat avant de le copier dans z. Alors maintenant, nous pouvons effectuer des opérations sur place pour mieux utiliser la mémoire et éviter la mémoire tampon temporaire. Pour ce faire, nous allons spécifier l'argument de mot-clé out que chaque opérateur prend en charge comme suit -

print('x=', x, 'is in id(x):', id(x))
print('y=', y, 'is in id(y):', id(y))
print('z=', z, 'is in id(z):', id(z))
nd.elemwise_add(x, y, out=z)
print('after nd.elemwise_add(x, y, out=z), x=', x, 'is in id(x):', id(x))
print('after nd.elemwise_add(x, y, out=z), y=', y, 'is in id(y):', id(y))
print('after nd.elemwise_add(x, y, out=z), z=', z, 'is in id(z):', id(z))

Output

En exécutant le programme ci-dessus, vous obtiendrez le résultat suivant -

x=
[1. 2. 3. 4.]
<NDArray 4 @cpu(0)> is in id(x): 2438905791152
y=
[3. 4. 5. 5.]
<NDArray 4 @cpu(0)> is in id(y): 2438905685664
z=
[4. 6. 8. 9.]
<NDArray 4 @cpu(0)> is in id(z): 2438905790760
after nd.elemwise_add(x, y, out=z), x=
[1. 2. 3. 4.]
<NDArray 4 @cpu(0)> is in id(x): 2438905791152
after nd.elemwise_add(x, y, out=z), y=
[3. 4. 5. 5.]
<NDArray 4 @cpu(0)> is in id(y): 2438905685664
after nd.elemwise_add(x, y, out=z), z=
[4. 6. 8. 9.]
<NDArray 4 @cpu(0)> is in id(z): 2438905790760

Contextes NDArray

Dans Apache MXNet, chaque tableau a un contexte et un contexte peut être le processeur, tandis que d'autres contextes peuvent être plusieurs GPU. Les choses peuvent être encore pires lorsque nous déployons le travail sur plusieurs serveurs. C'est pourquoi nous devons attribuer intelligemment des tableaux aux contextes. Cela minimisera le temps passé à transférer des données entre les appareils.

Par exemple, essayez d'initialiser un tableau comme suit -

from mxnet import nd
z = nd.ones(shape=(3,3), ctx=mx.cpu(0))
print(z)

Output

Lorsque vous exécutez le code ci-dessus, vous devriez voir la sortie suivante -

[[1. 1. 1.]
 [1. 1. 1.]
 [1. 1. 1.]]
<NDArray 3x3 @cpu(0)>

Nous pouvons copier le NDArray donné d'un contexte vers un autre contexte en utilisant la méthode copyto () comme suit -

x_gpu = x.copyto(gpu(0))
print(x_gpu)

Tableau NumPy et NDArray

Nous sommes tous familiers avec les tableaux NumPy, mais Apache MXNet propose sa propre implémentation de tableau nommée NDArray. En fait, il a été initialement conçu pour être similaire à NumPy mais il y a une différence clé -

La principale différence réside dans la manière dont les calculs sont exécutés dans NumPy et NDArray. Chaque manipulation de NDArray dans MXNet est effectuée de manière asynchrone et non bloquante, ce qui signifie que, lorsque nous écrivons du code comme c = a * b, la fonction est poussée vers leExecution Engine, qui lancera le calcul.

Ici, a et b sont tous deux des NDArrays. L'avantage de son utilisation est que la fonction revient immédiatement en arrière et que le thread utilisateur peut continuer l'exécution malgré le fait que le calcul précédent n'est peut-être pas encore terminé.

Fonctionnement du moteur d'exécution

Si nous parlons du fonctionnement du moteur d'exécution, il construit le graphe de calcul. Le graphe de calcul peut réorganiser ou combiner certains calculs, mais il respecte toujours l'ordre des dépendances.

Par exemple, s'il y a d'autres manipulations avec 'X' effectuées plus tard dans le code de programmation, le moteur d'exécution commencera à les faire une fois que le résultat de 'X' sera disponible. Le moteur d'exécution gérera certains travaux importants pour les utilisateurs, tels que l'écriture de rappels pour démarrer l'exécution du code suivant.

Dans Apache MXNet, avec l'aide de NDArray, pour obtenir le résultat du calcul, il suffit d'accéder à la variable résultante. Le flux du code sera bloqué jusqu'à ce que les résultats du calcul soient affectés à la variable résultante. De cette façon, il augmente les performances du code tout en prenant en charge le mode de programmation impératif.

Conversion de NDArray en NumPy Array

Apprenons comment convertir NDArray en NumPy Array dans MXNet.

Combining higher-level operator with the help of few lower-level operators

Parfois, nous pouvons assembler un opérateur de niveau supérieur en utilisant les opérateurs existants. L'un des meilleurs exemples en est lenp.full_like()opérateur, qui n'est pas présent dans l'API NDArray. Il peut facilement être remplacé par une combinaison d'opérateurs existants comme suit:

from mxnet import nd
import numpy as np
np_x = np.full_like(a=np.arange(7, dtype=int), fill_value=15)
nd_x = nd.ones(shape=(7,)) * 15
np.array_equal(np_x, nd_x.asnumpy())

Output

Nous obtiendrons la sortie similaire comme suit -

True

Finding similar operator with different name and/or signature

Parmi tous les opérateurs, certains d'entre eux ont un nom légèrement différent, mais ils sont similaires en termes de fonctionnalités. Un exemple de ceci estnd.ravel_index() avec np.ravel()les fonctions. De la même manière, certains opérateurs peuvent avoir des noms similaires, mais ils ont des signatures différentes. Un exemple de ceci estnp.split() et nd.split() sont similaires.

Comprenons-le avec l'exemple de programmation suivant:

def pad_array123(data, max_length):
data_expanded = data.reshape(1, 1, 1, data.shape[0])
data_padded = nd.pad(data_expanded,
mode='constant',
pad_width=[0, 0, 0, 0, 0, 0, 0, max_length - data.shape[0]],
constant_value=0)
data_reshaped_back = data_padded.reshape(max_length)
return data_reshaped_back
pad_array123(nd.array([1, 2, 3]), max_length=10)

Output

La sortie est indiquée ci-dessous -

[1. 2. 3. 0. 0. 0. 0. 0. 0. 0.]
<NDArray 10 @cpu(0)>

Minimiser l'impact du blocage des appels

Dans certains cas, nous devons utiliser soit .asnumpy() ou .asscalar()méthodes, mais cela forcera MXNet à bloquer l'exécution, jusqu'à ce que le résultat puisse être récupéré. Nous pouvons minimiser l'impact d'un blocage d'appel en appelant.asnumpy() ou .asscalar() méthodes dans le moment, quand on pense que le calcul de cette valeur est déjà fait.

Exemple d'implémentation

Example

from __future__ import print_function
import mxnet as mx
from mxnet import gluon, nd, autograd
from mxnet.ndarray import NDArray
from mxnet.gluon import HybridBlock
import numpy as np

class LossBuffer(object):
   """
   Simple buffer for storing loss value
   """
   
   def __init__(self):
      self._loss = None

   def new_loss(self, loss):
      ret = self._loss
      self._loss = loss
      return ret

      @property
      def loss(self):
         return self._loss

net = gluon.nn.Dense(10)
ce = gluon.loss.SoftmaxCELoss()
net.initialize()
data = nd.random.uniform(shape=(1024, 100))
label = nd.array(np.random.randint(0, 10, (1024,)), dtype='int32')
train_dataset = gluon.data.ArrayDataset(data, label)
train_data = gluon.data.DataLoader(train_dataset, batch_size=128, shuffle=True, num_workers=2)
trainer = gluon.Trainer(net.collect_params(), optimizer='sgd')
loss_buffer = LossBuffer()
for data, label in train_data:
   with autograd.record():
      out = net(data)
      # This call saves new loss and returns previous loss
      prev_loss = loss_buffer.new_loss(ce(out, label))
   loss_buffer.loss.backward()
   trainer.step(data.shape[0])
   if prev_loss is not None:
      print("Loss: {}".format(np.mean(prev_loss.asnumpy())))

Output

Le résultat est cité ci-dessous:

Loss: 2.3373236656188965
Loss: 2.3656985759735107
Loss: 2.3613128662109375
Loss: 2.3197104930877686
Loss: 2.3054862022399902
Loss: 2.329197406768799
Loss: 2.318927526473999

Un autre package MXNet Python le plus important est Gluon. Dans ce chapitre, nous discuterons de ce package. Gluon fournit une API claire, concise et simple pour les projets DL. Il permet à Apache MXNet de prototyper, de construire et de former des modèles DL sans perdre la vitesse de formation.

Blocs

Les blocs constituent la base de conceptions de réseaux plus complexes. Dans un réseau de neurones, à mesure que la complexité du réseau de neurones augmente, nous devons passer de la conception de couches uniques à des couches entières de neurones. Par exemple, la conception NN comme ResNet-152 a un très bon degré de régularité en se composant deblocks de couches répétées.

Exemple

Dans l'exemple donné ci-dessous, nous écrirons du code un bloc simple, à savoir un bloc pour un perceptron multicouche.

from mxnet import nd
from mxnet.gluon import nn
x = nd.random.uniform(shape=(2, 20))
N_net = nn.Sequential()
N_net.add(nn.Dense(256, activation='relu'))
N_net.add(nn.Dense(10))
N_net.initialize()
N_net(x)

Output

Cela produit la sortie suivante:

[[ 0.09543004 0.04614332 -0.00286655 -0.07790346 -0.05130241 0.02942038
0.08696645 -0.0190793 -0.04122177 0.05088576]
[ 0.0769287 0.03099706 0.00856576 -0.044672 -0.06926838 0.09132431
0.06786592 -0.06187843 -0.03436674 0.04234696]]
<NDArray 2x10 @cpu(0)>

Étapes nécessaires pour passer de la définition des couches à la définition des blocs d'une ou plusieurs couches -

Step 1 - Bloquer prendre les données comme entrée.

Step 2- Désormais, les blocs stockent l'état sous forme de paramètres. Par exemple, dans l'exemple de codage ci-dessus, le bloc contient deux couches cachées et nous avons besoin d'un emplacement pour stocker les paramètres.

Step 3- Le bloc suivant invoquera la fonction avant pour effectuer la propagation avant. Il est également appelé calcul direct. Dans le cadre du premier appel de transfert, les blocs initialisent les paramètres de manière paresseuse.

Step 4- Enfin, les blocs invoqueront la fonction arrière et calculeront le gradient en référence à leur entrée. En règle générale, cette étape est effectuée automatiquement.

Bloc séquentiel

Un bloc séquentiel est un type spécial de bloc dans lequel les données circulent à travers une séquence de blocs. En cela, chaque bloc appliqué à la sortie d'un bloc précédent, le premier bloc étant appliqué aux données d'entrée elles-mêmes.

Voyons comment sequential travaux de classe -

from mxnet import nd
from mxnet.gluon import nn
class MySequential(nn.Block):
   def __init__(self, **kwargs):
      super(MySequential, self).__init__(**kwargs)

   def add(self, block):
      self._children[block.name] = block
   def forward(self, x):
   for block in self._children.values():
      x = block(x)
   return x
x = nd.random.uniform(shape=(2, 20))
N_net = MySequential()
N_net.add(nn.Dense(256, activation
='relu'))
N_net.add(nn.Dense(10))
N_net.initialize()
N_net(x)

Output

La sortie est donnée ici -

[[ 0.09543004 0.04614332 -0.00286655 -0.07790346 -0.05130241 0.02942038
0.08696645 -0.0190793 -0.04122177 0.05088576]
[ 0.0769287 0.03099706 0.00856576 -0.044672 -0.06926838 0.09132431
0.06786592 -0.06187843 -0.03436674 0.04234696]]
<NDArray 2x10 @cpu(0)>

Bloc personnalisé

On peut facilement aller au-delà de la concaténation avec bloc séquentiel tel que défini ci-dessus. Mais, si nous voulons faire des personnalisations, alors leBlockclass nous fournit également les fonctionnalités requises. La classe Block a un constructeur de modèle fourni dans le module nn. Nous pouvons hériter de ce constructeur de modèle pour définir le modèle que nous voulons.

Dans l'exemple suivant, le MLP class remplace le __init__ et les fonctions avancées de la classe Block.

Voyons comment cela fonctionne.

class MLP(nn.Block):

   def __init__(self, **kwargs):
      super(MLP, self).__init__(**kwargs)
      self.hidden = nn.Dense(256, activation='relu') # Hidden layer
      self.output = nn.Dense(10) # Output layer


   def forward(self, x):
      hidden_out = self.hidden(x)
      return self.output(hidden_out)
x = nd.random.uniform(shape=(2, 20))
N_net = MLP()
N_net.initialize()
N_net(x)

Output

Lorsque vous exécutez le code, vous verrez la sortie suivante:

[[ 0.07787763 0.00216403 0.01682201 0.03059879 -0.00702019 0.01668715
0.04822846 0.0039432 -0.09300035 -0.04494302]
[ 0.08891078 -0.00625484 -0.01619131 0.0380718 -0.01451489 0.02006172
0.0303478 0.02463485 -0.07605448 -0.04389168]]
<NDArray 2x10 @cpu(0)>

Calques personnalisés

L'API Gluon d'Apache MXNet est fournie avec un nombre modeste de couches prédéfinies. Mais encore à un moment donné, nous pouvons constater qu'une nouvelle couche est nécessaire. Nous pouvons facilement ajouter une nouvelle couche dans l'API Gluon. Dans cette section, nous verrons comment créer un nouveau calque à partir de zéro.

Le calque personnalisé le plus simple

Pour créer une nouvelle couche dans l'API Gluon, nous devons créer une classe hérite de la classe Block qui fournit les fonctionnalités les plus basiques. Nous pouvons en hériter toutes les couches prédéfinies directement ou via d'autres sous-classes.

Pour créer la nouvelle couche, la seule méthode d'instance à implémenter est forward (self, x). Cette méthode définit ce que notre couche va faire exactement pendant la propagation vers l'avant. Comme indiqué précédemment, le passage de rétro-propagation des blocs sera effectué automatiquement par Apache MXNet lui-même.

Exemple

Dans l'exemple ci-dessous, nous allons définir un nouveau calque. Nous mettrons également en œuvreforward() méthode pour normaliser les données d'entrée en les ajustant dans une plage de [0, 1].

from __future__ import print_function
import mxnet as mx
from mxnet import nd, gluon, autograd
from mxnet.gluon.nn import Dense
mx.random.seed(1)
class NormalizationLayer(gluon.Block):
   def __init__(self):
      super(NormalizationLayer, self).__init__()

   def forward(self, x):
      return (x - nd.min(x)) / (nd.max(x) - nd.min(x))
x = nd.random.uniform(shape=(2, 20))
N_net = NormalizationLayer()
N_net.initialize()
N_net(x)

Output

En exécutant le programme ci-dessus, vous obtiendrez le résultat suivant -

[[0.5216355 0.03835821 0.02284337 0.5945146 0.17334817 0.69329053
0.7782702 1. 0.5508242 0. 0.07058554 0.3677264
0.4366546 0.44362497 0.7192635 0.37616986 0.6728799 0.7032008

 0.46907538 0.63514024]
[0.9157533 0.7667402 0.08980197   0.03593295 0.16176797 0.27679572
 0.07331014 0.3905285 0.6513384 0.02713427 0.05523694 0.12147208
 0.45582628 0.8139887 0.91629887 0.36665893 0.07873632 0.78268915
 0.63404864 0.46638715]]
 <NDArray 2x20 @cpu(0)>

L'hybridation

Il peut être défini comme un processus utilisé par Apache MXNet pour créer un graphe symbolique d'un calcul direct. L'hybridation permet à MXNet d'augmenter les performances de calcul en optimisant le graphe symbolique de calcul. Plutôt que d'hériter directement deBlock, en fait, nous pouvons constater que lors de l'implémentation de couches existantes, un bloc hérite d'un HybridBlock.

Voici les raisons à cela -

  • Allows us to write custom layers: HybridBlock nous permet d'écrire des couches personnalisées qui peuvent ensuite être utilisées dans la programmation impérative et symbolique.

  • Increase computation performance- HybridBlock optimise le graphe symbolique de calcul qui permet à MXNet d'augmenter les performances de calcul.

Exemple

Dans cet exemple, nous réécrirons notre exemple de couche, créé ci-dessus, en utilisant HybridBlock:

class NormalizationHybridLayer(gluon.HybridBlock):
   def __init__(self):
      super(NormalizationHybridLayer, self).__init__()

   def hybrid_forward(self, F, x):
      return F.broadcast_div(F.broadcast_sub(x, F.min(x)), (F.broadcast_sub(F.max(x), F.min(x))))

layer_hybd = NormalizationHybridLayer()
layer_hybd(nd.array([1, 2, 3, 4, 5, 6], ctx=mx.cpu()))

Output

La sortie est indiquée ci-dessous:

[0. 0.2 0.4 0.6 0.8 1. ]
<NDArray 6 @cpu(0)>

L'hybridation n'a rien à voir avec le calcul sur GPU et on peut entraîner des réseaux hybrides ou non hybrides sur CPU et GPU.

Différence entre Block et HybridBlock

Si nous comparons les Block Classe et HybridBlock, nous verrons que HybridBlock a déjà son forward() méthode mise en œuvre. HybridBlock définit un hybrid_forward()méthode qui doit être implémentée lors de la création des couches. L'argument F crée la principale différence entreforward() et hybrid_forward(). Dans la communauté MXNet, l'argument F est appelé backend. F peut faire référence àmxnet.ndarray API (utilisé pour la programmation impérative) ou mxnet.symbol API (utilisé pour la programmation symbolique).

Comment ajouter une couche personnalisée à un réseau?

Au lieu d'utiliser des calques personnalisés séparément, ces calques sont utilisés avec des calques prédéfinis. Nous pouvons utiliser soitSequential ou HybridSequentialconteneurs à partir d'un réseau neuronal séquentiel. Comme indiqué précédemment,Sequential conteneur hérite de Block et HybridSequential hériter de HybridBlock respectivement.

Exemple

Dans l'exemple ci-dessous, nous allons créer un réseau de neurones simple avec une couche personnalisée. La sortie deDense (5) couche sera l'entrée de NormalizationHybridLayer. La sortie deNormalizationHybridLayer deviendra l'entrée de Dense (1) couche.

net = gluon.nn.HybridSequential()
with net.name_scope():
net.add(Dense(5))
net.add(NormalizationHybridLayer())
net.add(Dense(1))
net.initialize(mx.init.Xavier(magnitude=2.24))
net.hybridize()
input = nd.random_uniform(low=-10, high=10, shape=(10, 2))
net(input)

Output

Vous verrez la sortie suivante -

[[-1.1272651]
 [-1.2299833]
 [-1.0662932]
 [-1.1805027]
 [-1.3382034]
 [-1.2081106]
 [-1.1263978]
 [-1.2524893]
 
 [-1.1044774]

 [-1.316593 ]]
<NDArray 10x1 @cpu(0)>

Paramètres de calque personnalisés

Dans un réseau neuronal, une couche est associée à un ensemble de paramètres. Nous les référons parfois comme des poids, qui est l'état interne d'une couche. Ces paramètres jouent différents rôles -

  • Parfois, ce sont ceux que nous voulons apprendre lors de l'étape de rétropropagation.

  • Parfois, ce ne sont que des constantes que nous voulons utiliser lors de la passe avant.

Si nous parlons du concept de programmation, ces paramètres (poids) d'un bloc sont stockés et accessibles via ParameterDict classe qui facilite leur initialisation, leur mise à jour, leur sauvegarde et leur chargement.

Exemple

Dans l'exemple ci-dessous, nous définirons deux ensembles de paramètres suivants -

  • Parameter weights- Ceci peut être entraîné et sa forme est inconnue pendant la phase de construction. Il sera déduit lors du premier passage de propagation vers l'avant.

  • Parameter scale- C'est une constante dont la valeur ne change pas. Contrairement aux poids des paramètres, sa forme est définie lors de la construction.

class NormalizationHybridLayer(gluon.HybridBlock):
   def __init__(self, hidden_units, scales):
      super(NormalizationHybridLayer, self).__init__()
      with self.name_scope():
      self.weights = self.params.get('weights',
      shape=(hidden_units, 0),
      allow_deferred_init=True)
      self.scales = self.params.get('scales',
         shape=scales.shape,
         init=mx.init.Constant(scales.asnumpy()),
         differentiable=False)
      def hybrid_forward(self, F, x, weights, scales):
         normalized_data = F.broadcast_div(F.broadcast_sub(x, F.min(x)),
         (F.broadcast_sub(F.max(x), F.min(x))))
         weighted_data = F.FullyConnected(normalized_data, weights, num_hidden=self.weights.shape[0], no_bias=True)
         scaled_data = F.broadcast_mul(scales, weighted_data)
return scaled_data

Ce chapitre traite des packages python KVStore et de la visualisation.

Paquet KVStore

KV stores signifie magasin de valeurs clés. C'est un composant essentiel utilisé pour la formation multi-appareils. C'est important car, la communication des paramètres entre les appareils sur une seule ou entre plusieurs machines est transmise via un ou plusieurs serveurs avec un KVStore pour les paramètres.

Comprenons le fonctionnement de KVStore à l'aide des points suivants:

  • Chaque valeur dans KVStore est représentée par un key et un value.

  • Chaque tableau de paramètres du réseau se voit attribuer un key et les poids de ce tableau de paramètres sont référencés par value.

  • Après cela, les nœuds de travail pushdégradés après le traitement d'un lot. Ils aussipull poids mis à jour avant de traiter un nouveau lot.

En termes simples, nous pouvons dire que KVStore est un lieu de partage de données où chaque appareil peut insérer des données et extraire des données.

Données Push-In et Pull-Out

KVStore peut être considéré comme un objet unique partagé sur différents appareils tels que des GPU et des ordinateurs, où chaque appareil est capable de pousser des données et d'extraire des données.

Voici les étapes de mise en œuvre qui doivent être suivies par les appareils pour pousser les données et les extraire:

Étapes de mise en œuvre

Initialisation- La première étape consiste à initialiser les valeurs. Ici, pour notre exemple, nous allons initialiser une paire (int, NDArray) paire dans KVStrore et ensuite extraire les valeurs -

import mxnet as mx
kv = mx.kv.create('local') # create a local KVStore.
shape = (3,3)
kv.init(3, mx.nd.ones(shape)*2)
a = mx.nd.zeros(shape)
kv.pull(3, out = a)
print(a.asnumpy())

Output

Cela produit la sortie suivante -

[[2. 2. 2.]
[2. 2. 2.]
[2. 2. 2.]]

Push, Aggregate, and Update - Une fois initialisé, nous pouvons pousser une nouvelle valeur dans KVStore avec la même forme à la clé -

kv.push(3, mx.nd.ones(shape)*8)
kv.pull(3, out = a)
print(a.asnumpy())

Output

La sortie est donnée ci-dessous -

[[8. 8. 8.]
 [8. 8. 8.]
 [8. 8. 8.]]

Les données utilisées pour pousser peuvent être stockées sur n'importe quel appareil tel que des GPU ou des ordinateurs. Nous pouvons également pousser plusieurs valeurs dans la même clé. Dans ce cas, le KVStore additionnera d'abord toutes ces valeurs, puis transmettra la valeur agrégée comme suit -

contexts = [mx.cpu(i) for i in range(4)]
b = [mx.nd.ones(shape, ctx) for ctx in contexts]
kv.push(3, b)
kv.pull(3, out = a)
print(a.asnumpy())

Output

Vous verrez la sortie suivante -

[[4. 4. 4.]
 [4. 4. 4.]
 [4. 4. 4.]]

Pour chaque push que vous avez appliqué, KVStore combinera la valeur poussée avec la valeur déjà stockée. Cela se fera à l'aide d'un programme de mise à jour. Ici, le programme de mise à jour par défaut est ASSIGN.

def update(key, input, stored):
   print("update on key: %d" % key)
   
   stored += input * 2
kv.set_updater(update)
kv.pull(3, out=a)
print(a.asnumpy())

Output

Lorsque vous exécutez le code ci-dessus, vous devriez voir la sortie suivante -

[[4. 4. 4.]
 [4. 4. 4.]
 [4. 4. 4.]]

Example

kv.push(3, mx.nd.ones(shape))
kv.pull(3, out=a)
print(a.asnumpy())

Output

Ci-dessous est la sortie du code -

update on key: 3
[[6. 6. 6.]
 [6. 6. 6.]
 [6. 6. 6.]]

Pull - Comme pour Push, nous pouvons également tirer la valeur sur plusieurs appareils avec un seul appel comme suit -

b = [mx.nd.ones(shape, ctx) for ctx in contexts]
kv.pull(3, out = b)
print(b[1].asnumpy())

Output

La sortie est indiquée ci-dessous -

[[6. 6. 6.]
 [6. 6. 6.]
 [6. 6. 6.]]

Exemple d'implémentation complet

Vous trouverez ci-dessous l'exemple complet de mise en œuvre -

import mxnet as mx
kv = mx.kv.create('local')
shape = (3,3)
kv.init(3, mx.nd.ones(shape)*2)
a = mx.nd.zeros(shape)
kv.pull(3, out = a)
print(a.asnumpy())
kv.push(3, mx.nd.ones(shape)*8)
kv.pull(3, out = a) # pull out the value
print(a.asnumpy())
contexts = [mx.cpu(i) for i in range(4)]
b = [mx.nd.ones(shape, ctx) for ctx in contexts]
kv.push(3, b)
kv.pull(3, out = a)
print(a.asnumpy())
def update(key, input, stored):
   print("update on key: %d" % key)
   stored += input * 2
kv._set_updater(update)
kv.pull(3, out=a)
print(a.asnumpy())
kv.push(3, mx.nd.ones(shape))
kv.pull(3, out=a)
print(a.asnumpy())
b = [mx.nd.ones(shape, ctx) for ctx in contexts]
kv.pull(3, out = b)
print(b[1].asnumpy())

Gestion des paires clé-valeur

Toutes les opérations que nous avons implémentées ci-dessus impliquent une seule clé, mais KVStore fournit également une interface pour a list of key-value pairs -

Pour un seul appareil

Voici un exemple pour montrer une interface KVStore pour une liste de paires clé-valeur pour un seul appareil -

keys = [5, 7, 9]
kv.init(keys, [mx.nd.ones(shape)]*len(keys))
kv.push(keys, [mx.nd.ones(shape)]*len(keys))
b = [mx.nd.zeros(shape)]*len(keys)
kv.pull(keys, out = b)
print(b[1].asnumpy())

Output

Vous recevrez la sortie suivante -

update on key: 5
update on key: 7
update on key: 9
[[3. 3. 3.]
 [3. 3. 3.]
 [3. 3. 3.]]

Pour plusieurs appareils

Voici un exemple pour montrer une interface KVStore pour une liste de paires clé-valeur pour plusieurs appareils -

b = [[mx.nd.ones(shape, ctx) for ctx in contexts]] * len(keys)
kv.push(keys, b)
kv.pull(keys, out = b)
print(b[1][1].asnumpy())

Output

Vous verrez la sortie suivante -

update on key: 5
update on key: 7
update on key: 9
[[11. 11. 11.]
 [11. 11. 11.]
 [11. 11. 11.]]

Package de visualisation

Le package de visualisation est le package Apache MXNet utilisé pour représenter le réseau neuronal (NN) sous la forme d'un graphe de calcul composé de nœuds et d'arêtes.

Visualisez le réseau neuronal

Dans l'exemple ci-dessous, nous utiliserons mx.viz.plot_networkpour visualiser le réseau neuronal. Les éléments suivants sont les prérequis pour cela -

Prerequisites

  • Cahier Jupyter

  • Bibliothèque Graphviz

Exemple d'implémentation

Dans l'exemple ci-dessous, nous allons visualiser un échantillon NN pour la factorisation matricielle linéaire -

import mxnet as mx
user = mx.symbol.Variable('user')
item = mx.symbol.Variable('item')
score = mx.symbol.Variable('score')

# Set the dummy dimensions
k = 64
max_user = 100
max_item = 50

# The user feature lookup
user = mx.symbol.Embedding(data = user, input_dim = max_user, output_dim = k)

# The item feature lookup
item = mx.symbol.Embedding(data = item, input_dim = max_item, output_dim = k)

# predict by the inner product and then do sum
N_net = user * item
N_net = mx.symbol.sum_axis(data = N_net, axis = 1)
N_net = mx.symbol.Flatten(data = N_net)

# Defining the loss layer
N_net = mx.symbol.LinearRegressionOutput(data = N_net, label = score)

# Visualize the network
mx.viz.plot_network(N_net)

Ce chapitre explique la bibliothèque ndarray disponible dans Apache MXNet.

Mxnet.ndarray

La bibliothèque NDArray d'Apache MXNet définit le noyau DS (structures de données) pour tous les calculs mathématiques. Deux tâches fondamentales de NDArray sont les suivantes:

  • Il prend en charge une exécution rapide sur une large gamme de configurations matérielles.

  • Il met automatiquement en parallèle plusieurs opérations sur le matériel disponible.

L'exemple donné ci-dessous montre comment créer un NDArray en utilisant un 'tableau' 1-D et 2-D à partir d'une liste Python régulière -

import mxnet as mx
from mxnet import nd

x = nd.array([1,2,3,4,5,6,7,8,9,10])
print(x)

Output

La sortie est donnée ci-dessous:

[ 1. 2. 3. 4. 5. 6. 7. 8. 9. 10.]
<NDArray 10 @cpu(0)>

Example

y = nd.array([[1,2,3,4,5,6,7,8,9,10], [1,2,3,4,5,6,7,8,9,10], [1,2,3,4,5,6,7,8,9,10]])
print(y)

Output

Cela produit la sortie suivante -

[[ 1. 2. 3. 4. 5. 6. 7. 8. 9. 10.]
 [ 1. 2. 3. 4. 5. 6. 7. 8. 9. 10.]
 [ 1. 2. 3. 4. 5. 6. 7. 8. 9. 10.]]
<NDArray 3x10 @cpu(0)>

Voyons maintenant en détail les classes, les fonctions et les paramètres de l'API ndarray de MXNet.

Des classes

Le tableau suivant comprend les classes de l'API ndarray de MXNet -

Classe Définition
CachedOp (sym [, indicateurs]) Il est utilisé pour le handle d'opérateur mis en cache.
NDArray (handle [, accessible en écriture]) Il est utilisé comme un objet de tableau qui représente un tableau homogène et multidimensionnel d'éléments de taille fixe.

Fonctions et leurs paramètres

Voici quelques-unes des fonctions importantes et leurs paramètres couverts par l'API mxnet.ndarray -

Fonction et ses paramètres Définition
Activation([données, type_act, sortie, nom]) Il applique une fonction d'activation élément par élément à l'entrée. Il prend en charge les fonctions d'activation relu, sigmoid, tanh, softrelu, softsign.
BatchNorm([data, gamma, beta, moving_mean,…]) Il est utilisé pour la normalisation des lots. Cette fonction normalise un lot de données par la moyenne et la variance. Il applique une échelle gamma et un décalage bêta.
BilinearSampler([données, grille, cudnn_off,…])

Cette fonction applique un échantillonnage bilinéaire à la carte d'entités en entrée. En fait, c'est la clé des «Réseaux de Transformateurs Spatiaux».

Si vous êtes familier avec la fonction de remappage dans OpenCV, l'utilisation de cette fonction est assez similaire à cela. La seule différence est qu'il a la passe arrière.

BlockGrad ([données, sortie, nom]) Comme son nom l'indique, cette fonction arrête le calcul du gradient. Il empêche essentiellement le gradient accumulé des entrées de traverser cet opérateur dans le sens inverse.
cast ([données, type, sortie, nom]) Cette fonction convertira tous les éléments de l'entrée dans un nouveau type.

Exemples de mise en œuvre

Dans l'exemple ci-dessous, nous utiliserons la fonction BilinierSampler () pour zoomer deux fois sur les données et décaler les données horizontalement de -1 pixel -

import mxnet as mx
from mxnet import nd
data = nd.array([[[[2, 5, 3, 6],
   [1, 8, 7, 9],
   [0, 4, 1, 8],
   [2, 0, 3, 4]]]])
affine_matrix = nd.array([[2, 0, 0],
   [0, 2, 0]])

affine_matrix = nd.reshape(affine_matrix, shape=(1, 6))

grid = nd.GridGenerator(data=affine_matrix, transform_type='affine', target_shape=(4, 4))

output = nd.BilinearSampler(data, grid)

Output

Lorsque vous exécutez le code ci-dessus, vous devriez voir la sortie suivante:

[[[[0. 0. 0. 0. ]
   [0. 4.0000005 6.25 0. ]
   [0. 1.5 4. 0. ]
   [0. 0. 0. 0. ]]]]
<NDArray 1x1x4x4 @cpu(0)>

La sortie ci-dessus montre le zoom arrière des données deux fois.

Voici un exemple de décalage des données de -1 pixel -

import mxnet as mx
from mxnet import nd
data = nd.array([[[[2, 5, 3, 6],
   [1, 8, 7, 9],
   [0, 4, 1, 8],
   [2, 0, 3, 4]]]])
warp_matrix = nd.array([[[[1, 1, 1, 1],
   [1, 1, 1, 1],
   [1, 1, 1, 1],
   [1, 1, 1, 1]],
   [[0, 0, 0, 0],
   [0, 0, 0, 0],
   [0, 0, 0, 0],
   [0, 0, 0, 0]]]])
grid = nd.GridGenerator(data=warp_matrix, transform_type='warp')
output = nd.BilinearSampler(data, grid)

Output

La sortie est indiquée ci-dessous -

[[[[5. 3. 6. 0.]
[8. 7. 9. 0.]
[4. 1. 8. 0.]
[0. 3. 4. 0.]]]]
<NDArray 1x1x4x4 @cpu(0)>

De même, l'exemple suivant montre l'utilisation de la fonction cast () -

nd.cast(nd.array([300, 10.1, 15.4, -1, -2]), dtype='uint8')

Output

Lors de l'exécution, vous recevrez la sortie suivante -

[ 44 10 15 255 254]
<NDArray 5 @cpu(0)>

ndarray.contrib

L'API Contrib NDArray est définie dans le package ndarray.contrib. Il fournit généralement de nombreuses API expérimentales utiles pour les nouvelles fonctionnalités. Cette API fonctionne comme un endroit pour la communauté où ils peuvent essayer les nouvelles fonctionnalités. Le contributeur de la fonctionnalité recevra également les commentaires.

Fonctions et leurs paramètres

Voici quelques-unes des fonctions importantes et leurs paramètres couverts par mxnet.ndarray.contrib API -

Fonction et ses paramètres Définition
rand_zipfian(true_classes, num_sampled,…) Cette fonction tire des échantillons aléatoires à partir d'une distribution approximativement Zipfienne. La distribution de base de cette fonction est la distribution Zipfian. Cette fonction échantillonne aléatoirement les candidats num_sampled et les éléments de sampled_candidates sont tirés de la distribution de base donnée ci-dessus.
foreach(corps, données, init_states) Comme son nom l'indique, cette fonction exécute une boucle for avec un calcul défini par l'utilisateur sur NDArrays sur la dimension 0. Cette fonction simule une boucle for et le corps a le calcul pour une itération de la boucle for.
while_loop (cond, func, loop_vars [,…]) Comme son nom l'indique, cette fonction exécute une boucle while avec un calcul et une condition de boucle définis par l'utilisateur. Cette fonction simule une boucle while qui effectue un calcul personnalisé si la condition est satisfaite.
cond(pred, then_func, else_func) Comme son nom l'indique, cette fonction exécute un if-then-else en utilisant une condition et un calcul définis par l'utilisateur. Cette fonction simule une branche de type if qui choisit de faire l'un des deux calculs personnalisés selon la condition spécifiée.
isinf(Les données) Cette fonction effectue un contrôle élément par élément pour déterminer si le NDArray contient un élément infini ou non.
getnnz([données, axe, sortie, nom]) Cette fonction nous donne le nombre de valeurs stockées pour un tenseur clairsemé. Il comprend également des zéros explicites. Il ne prend en charge que la matrice CSR sur le processeur.
requantize ([données, plage_min, plage_max,…]) Cette fonction requantise les données données qui sont quantifiées dans int32 et les seuils correspondants, dans int8 en utilisant les seuils min et max calculés à l'exécution ou à partir de l'étalonnage.

Exemples de mise en œuvre

Dans l'exemple ci-dessous, nous utiliserons la fonction rand_zipfian pour tirer des échantillons aléatoires à partir d'une distribution approximativement Zipfienne -

import mxnet as mx
from mxnet import nd
trueclass = mx.nd.array([2])
samples, exp_count_true, exp_count_sample = mx.nd.contrib.rand_zipfian(trueclass, 3, 4)
samples

Output

Vous verrez la sortie suivante -

[0 0 1]
<NDArray 3 @cpu(0)>

Example

exp_count_true

Output

La sortie est donnée ci-dessous:

[0.53624076]
<NDArray 1 @cpu(0)>

Example

exp_count_sample

Output

Cela produit la sortie suivante:

[1.29202967 1.29202967 0.75578891]
<NDArray 3 @cpu(0)>

Dans l'exemple ci-dessous, nous utiliserons la fonction while_loop pour exécuter une boucle while pour un calcul défini par l'utilisateur et une condition de boucle:

cond = lambda i, s: i <= 7
func = lambda i, s: ([i + s], [i + 1, s + i])
loop_var = (mx.nd.array([0], dtype="int64"), mx.nd.array([1], dtype="int64"))
outputs, states = mx.nd.contrib.while_loop(cond, func, loop_vars, max_iterations=10)
outputs

Output

La sortie est indiquée ci-dessous -

[
[[       1]
 [      2]
 [      4]
 [      7]
 [     11]
 [     16]
 [     22]
 [     29]
 [3152434450384]
 [     257]]
<NDArray 10x1 @cpu(0)>]

Example

States

Output

Cela produit la sortie suivante -

[
[8]
<NDArray 1 @cpu(0)>,
[29]
<NDArray 1 @cpu(0)>]

ndarray.image

L'API Image NDArray est définie dans le package ndarray.image. Comme son nom l'indique, il est généralement utilisé pour les images et leurs caractéristiques.

Fonctions et leurs paramètres

Voici quelques-unes des fonctions importantes et leurs paramètres couverts par mxnet.ndarray.image API-

Fonction et ses paramètres Définition
adjust_lighting([données, alpha, sortie, nom]) Comme son nom l'indique, cette fonction ajuste le niveau d'éclairage de l'entrée. Il suit le style AlexNet.
crop([données, x, y, largeur, hauteur, sortie, nom]) Avec l'aide de cette fonction, nous pouvons recadrer une image NDArray de forme (H x L x C) ou (N x H x L x C) à la taille donnée par l'utilisateur.
normalize([données, moyenne, std, sortie, nom]) Il normalisera un tenseur de forme (C x H x L) ou (N x C x H x L) avec mean et standard deviation(SD).
random_crop ([data, xrange, yrange, width,…]) Semblable à crop (), il recadre au hasard une image NDArray de forme (H x L x C) ou (N x H x L x C) à la taille donnée par l'utilisateur. Il suréchantillonnera le résultat si src est plus petit que la taille.
random_lighting([données, alpha_std, sortie, nom]) Comme son nom l'indique, cette fonction ajoute le bruit PCA de manière aléatoire. Il suit également le style AlexNet.
random_resized_crop([data, xrange, yrange,…]) Il recadre également une image au hasard NDArray de forme (H x L x C) ou (N x H x L x C) à la taille donnée. Il suréchantillonnera le résultat, si src est plus petit que la taille. Cela randomisera également la zone et l'aspect rationnel.
resize([données, taille, keep_ratio, interp,…]) Comme son nom l'indique, cette fonction redimensionnera une image NDArray de forme (H x L x C) ou (N x H x L x C) à la taille donnée par l'utilisateur.
to_tensor([données, sortie, nom]) Il convertit une image NDArray de forme (H x L x C) ou (N x H x L x C) avec les valeurs dans l'intervalle [0, 255] en un tenseur NDArray de forme (C x H x L) ou ( N x C x H x L) avec les valeurs dans la plage [0, 1].

Exemples de mise en œuvre

Dans l'exemple ci-dessous, nous utiliserons la fonction to_tensor pour convertir l'image NDArray de forme (H x L x C) ou (N x H x L x C) avec les valeurs dans l'intervalle [0, 255] en un tenseur NDArray de forme (C x H x L) ou (N x C x H x L) avec les valeurs dans la plage [0, 1].

import numpy as np
img = mx.nd.random.uniform(0, 255, (4, 2, 3)).astype(dtype=np.uint8)
mx.nd.image.to_tensor(img)

Output

Vous verrez la sortie suivante -

[[[0.972549 0.5058824 ]
   [0.6039216 0.01960784]
   [0.28235295 0.35686275]
   [0.11764706 0.8784314 ]]

[[0.8745098 0.9764706 ]
   [0.4509804 0.03529412]
   [0.9764706 0.29411766]
   [0.6862745 0.4117647 ]]

[[0.46666667 0.05490196]
   [0.7372549 0.4392157 ]
   [0.11764706 0.47843137]
   [0.31764707 0.91764706]]]
<NDArray 3x4x2 @cpu(0)>

Example

img = mx.nd.random.uniform(0, 255, (2, 4, 2, 3)).astype(dtype=np.uint8)

mx.nd.image.to_tensor(img)

Output

Lorsque vous exécutez le code, vous verrez la sortie suivante -

[[[[0.0627451 0.5647059 ]
[0.2627451 0.9137255 ]
[0.57254905 0.27450982]
[0.6666667 0.64705884]]
[[0.21568628 0.5647059 ]
[0.5058824 0.09019608]
[0.08235294 0.31764707]
[0.8392157 0.7137255 ]]
[[0.6901961 0.8627451 ]
[0.52156866 0.91764706]
[0.9254902 0.00784314]
[0.12941177 0.8392157 ]]]
[[[0.28627452 0.39607844]
[0.01960784 0.36862746]
[0.6745098 0.7019608 ]
[0.9607843 0.7529412 ]]
[[0.2627451 0.58431375]
[0.16470589 0.00392157]
[0.5686275 0.73333335]
[0.43137255 0.57254905]]
[[0.18039216 0.54901963]
[0.827451 0.14509805]
[0.26666668 0.28627452]
[0.24705882 0.39607844]]]]
<NDArgt;ray 2x3x4x2 @cpu(0)>

Dans l'exemple ci-dessous, nous utiliserons la fonction normalize normaliser un tenseur de forme (C x H x L) ou (N x C x H x L) avec mean et standard deviation(SD).

img = mx.nd.random.uniform(0, 1, (3, 4, 2))

mx.nd.image.normalize(img, mean=(0, 1, 2), std=(3, 2, 1))

Output

Cela produit la sortie suivante -

[[[ 0.29391178 0.3218054 ]
[ 0.23084386 0.19615503]
[ 0.24175143 0.21988946]
[ 0.16710812 0.1777354 ]]
[[-0.02195817 -0.3847335 ]
[-0.17800489 -0.30256534]
[-0.28807247 -0.19059572]
[-0.19680339 -0.26256624]]
[[-1.9808068 -1.5298678 ]
[-1.6984252 -1.2839255 ]
[-1.3398265 -1.712009 ]
[-1.7099224 -1.6165378 ]]]
<NDArray 3x4x2 @cpu(0)>

Example

img = mx.nd.random.uniform(0, 1, (2, 3, 4, 2))

mx.nd.image.normalize(img, mean=(0, 1, 2), std=(3, 2, 1))

Output

Lorsque vous exécutez le code ci-dessus, vous devriez voir la sortie suivante -

[[[[ 2.0600514e-01 2.4972327e-01]
[ 1.4292289e-01 2.9281738e-01]
[ 4.5158025e-02 3.4287784e-02]
[ 9.9427439e-02 3.0791296e-02]]
[[-2.1501756e-01 -3.2297665e-01]
[-2.0456362e-01 -2.2409186e-01]
[-2.1283737e-01 -4.8318747e-01]
[-1.7339960e-01 -1.5519112e-02]]
[[-1.3478968e+00 -1.6790028e+00]
[-1.5685816e+00 -1.7787373e+00]
[-1.1034534e+00 -1.8587360e+00]
[-1.6324382e+00 -1.9027401e+00]]]
[[[ 1.4528830e-01 3.2801408e-01]
[ 2.9730779e-01 8.6780310e-02]
[ 2.6873133e-01 1.7900752e-01]
[ 2.3462953e-01 1.4930873e-01]]
[[-4.4988656e-01 -4.5021546e-01]
[-4.0258706e-02 -3.2384416e-01]
[-1.4287934e-01 -2.6537544e-01]
[-5.7649612e-04 -7.9429924e-02]]
[[-1.8505517e+00 -1.0953522e+00]
[-1.1318740e+00 -1.9624406e+00]
[-1.8375070e+00 -1.4916846e+00]
[-1.3844404e+00 -1.8331525e+00]]]]
<NDArray 2x3x4x2 @cpu(0)>

ndarray.random

L'API Random NDArray est définie dans le package ndarray.random. Comme son nom l'indique, il s'agit de l'API NDArray du générateur de distribution aléatoire de MXNet.

Fonctions et leurs paramètres

Voici quelques-unes des fonctions importantes et leurs paramètres couverts par mxnet.ndarray.random API -

Fonction et ses paramètres Définition
uniforme ([faible, élevé, forme, type d, ctx, sortie]) Il génère des échantillons aléatoires à partir d'une distribution uniforme.
normal ([loc, scale, shape, dtype, ctx, out]) Il génère des échantillons aléatoires à partir d'une distribution normale (gaussienne).
randn (* forme, ** kwargs) Il génère des échantillons aléatoires à partir d'une distribution normale (gaussienne).
exponentielle ([scale, shape, dtype, ctx, out]) Il génère des échantillons à partir d'une distribution exponentielle.
gamma ([alpha, beta, shape, dtype, ctx, out]) Il génère des échantillons aléatoires à partir d'une distribution gamma.
multinomial (data [, shape, get_prob, out, dtype]) Il génère un échantillonnage simultané à partir de plusieurs distributions multinomiales.
négatif_binomial ([k, p, forme, dtype, ctx, sortie]) Il génère des échantillons aléatoires à partir d'une distribution binomiale négative.
generalized_negative_binomial ([mu, alpha,…]) Il génère des échantillons aléatoires à partir d'une distribution binomiale négative généralisée.
aléatoire (données, ** kwargs) Il mélange les éléments au hasard.
randint (faible, élevé [, forme, type, ctx, sortie]) Il génère des échantillons aléatoires à partir d'une distribution uniforme discrète.
exponential_like ([data, lam, out, name]) Il génère des échantillons aléatoires à partir d'une distribution exponentielle en fonction de la forme du tableau d'entrée.
gamma_like ([données, alpha, bêta, sortie, nom]) Il génère des échantillons aléatoires à partir d'une distribution gamma en fonction de la forme du tableau d'entrée.
generalized_negative_binomial_like ([données,…]) Il génère des échantillons aléatoires à partir d'une distribution binomiale négative généralisée, en fonction de la forme du tableau d'entrée.
negatif_binomial_like ([données, k, p, sortie, nom]) Il génère des échantillons aléatoires à partir d'une distribution binomiale négative, en fonction de la forme du tableau d'entrée.
normal_like ([data, loc, scale, out, name]) Il génère des échantillons aléatoires à partir d'une distribution normale (gaussienne), en fonction de la forme du tableau d'entrée.
poisson_like ([données, lam, out, nom]) Il génère des échantillons aléatoires à partir d'une distribution de Poisson, en fonction de la forme du tableau d'entrée.
uniform_like ([données, faible, élevé, sortie, nom]) Il génère des échantillons aléatoires à partir d'une distribution uniforme, en fonction de la forme du tableau d'entrée.

Exemples de mise en œuvre

Dans l'exemple ci-dessous, nous allons tirer des échantillons aléatoires à partir d'une distribution uniforme. Pour cela, nous utiliserons la fonctionuniform().

mx.nd.random.uniform(0, 1)

Output

La sortie est mentionnée ci-dessous -

[0.12381998]
<NDArray 1 @cpu(0)>

Example

mx.nd.random.uniform(-1, 1, shape=(2,))

Output

La sortie est donnée ci-dessous -

[0.558102 0.69601643]
<NDArray 2 @cpu(0)>

Example

low = mx.nd.array([1,2,3])
high = mx.nd.array([2,3,4])
mx.nd.random.uniform(low, high, shape=2)

Output

Vous verrez la sortie suivante -

[[1.8649333 1.8073189]
 [2.4113967 2.5691009]
 [3.1399727 3.4071832]]
<NDArray 3x2 @cpu(0)>

Dans l'exemple ci-dessous, nous allons tirer des échantillons aléatoires à partir d'une distribution binomiale négative généralisée. Pour cela, nous utiliserons la fonctiongeneralized_negative_binomial().

mx.nd.random.generalized_negative_binomial(10, 0.5)

Output

Lorsque vous exécutez le code ci-dessus, vous devriez voir la sortie suivante -

[1.]
<NDArray 1 @cpu(0)>

Example

mx.nd.random.generalized_negative_binomial(10, 0.5, shape=(2,))

Output

La sortie est donnée ici -

[16. 23.]
<NDArray 2 @cpu(0)>

Example

mu = mx.nd.array([1,2,3])
alpha = mx.nd.array([0.2,0.4,0.6])
mx.nd.random.generalized_negative_binomial(mu, alpha, shape=2)

Output

Ci-dessous est la sortie du code -

[[0. 0.]
 [4. 1.]
 [9. 3.]]
<NDArray 3x2 @cpu(0)>

ndarray.utils

L'API NDArray de l'utilitaire est définie dans le package ndarray.utils. Comme son nom l'indique, il fournit les fonctions utilitaires pour NDArray et BaseSparseNDArray.

Fonctions et leurs paramètres

Voici quelques-unes des fonctions importantes et leurs paramètres couverts par mxnet.ndarray.utils API -

Fonction et ses paramètres Définition
zéros (forme [, ctx, dtype, stype]) Cette fonction renverra un nouveau tableau de forme et de type donnés, rempli de zéros.
vide (forme [, ctx, dtype, stype]) Il retournera un nouveau tableau de forme et de type donnés, sans initialiser les entrées.
array (source_array [, ctx, dtype]) Comme son nom l'indique, cette fonction créera un tableau à partir de n'importe quel objet exposant l'interface du tableau.
charge (fname) Il chargera un tableau à partir du fichier.
load_frombuffer (buf) Comme son nom l'indique, cette fonction chargera un dictionnaire ou une liste de tableaux à partir d'un tampon
save (fname, données) Cette fonction enregistrera une liste de tableaux ou un dict de str-> array dans un fichier.

Exemples de mise en œuvre

Dans l'exemple ci-dessous, nous allons retourner un nouveau tableau de forme et de type donnés, rempli de zéros. Pour cela, nous utiliserons la fonctionzeros().

mx.nd.zeros((1,2), mx.cpu(), stype='csr')

Output

Cela produit la sortie suivante -

<CSRNDArray 1x2 @cpu(0)>

Example

mx.nd.zeros((1,2), mx.cpu(), 'float16', stype='row_sparse').asnumpy()

Output

Vous recevrez la sortie suivante -

array([[0., 0.]], dtype=float16)

Dans l'exemple ci-dessous, nous allons enregistrer une liste de tableaux et un dictionnaire de chaînes. Pour cela, nous utiliserons la fonctionsave().

Example

x = mx.nd.zeros((2,3))
y = mx.nd.ones((1,4))
mx.nd.save('list', [x,y])
mx.nd.save('dict', {'x':x, 'y':y})
mx.nd.load('list')

Output

Lors de l'exécution, vous recevrez la sortie suivante -

[
[[0. 0. 0.]
[0. 0. 0.]]
<NDArray 2x3 @cpu(0)>,
[[1. 1. 1. 1.]]
<NDArray 1x4 @cpu(0)>]

Example

mx.nd.load('my_dict')

Output

La sortie est indiquée ci-dessous -

{'x':
[[0. 0. 0.]
[0. 0. 0.]]
<NDArray 2x3 @cpu(0)>, 'y':
[[1. 1. 1. 1.]]
<NDArray 1x4 @cpu(0)>}

Comme nous l'avons déjà mentionné dans les chapitres précédents, MXNet Gluon fournit une API claire, concise et simple pour les projets DL. Il permet à Apache MXNet de prototyper, de construire et de former des modèles DL sans perdre la vitesse de formation.

Modules de base

Apprenons les modules de base de Apache MXNet Python Application Programming Interface (API) gluon.

gluon.nn

Gluon fournit un grand nombre de couches NN intégrées dans le module gluon.nn. C'est la raison pour laquelle il s'appelle le module principal.

Méthodes et leurs paramètres

Voici quelques-unes des méthodes importantes et leurs paramètres couverts par mxnet.gluon.nn module de base -

Méthodes et ses paramètres Définition
Activation (activation, ** kwargs) Comme son nom l'indique, cette méthode applique une fonction d'activation à l'entrée.
AvgPool1D ([pool_size, strides, padding,…]) Il s'agit d'une opération de mise en commun moyenne pour les données temporelles.
AvgPool2D ([pool_size, strides, padding,…]) Il s'agit d'une opération de mise en commun moyenne pour les données spatiales.
AvgPool3D ([pool_size, strides, padding,…]) Il s'agit d'une opération de mise en commun moyenne pour les données 3D. Les données peuvent être spatiales ou spatio-temporelles.
BatchNorm ([axe, momentum, epsilon, centre,…]) Il représente la couche de normalisation par lots.
BatchNormReLU ([axe, momentum, epsilon,…]) Il représente également la couche de normalisation par lots mais avec la fonction d'activation Relu.
Bloquer ([préfixe, paramètres]) Il donne la classe de base pour toutes les couches et modèles de réseau neuronal.
Conv1D (canaux, kernel_size [, foulées,…]) Cette méthode est utilisée pour la couche de convolution 1D. Par exemple, la convolution temporelle.
Conv1DTranspose (canaux, kernel_size [,…]) Cette méthode est utilisée pour la couche de convolution 1D transposée.
Conv2D (canaux, kernel_size [, foulées,…]) Cette méthode est utilisée pour la couche de convolution 2D. Par exemple, convolution spatiale sur les images).
Conv2DTranspose (canaux, kernel_size [,…]) Cette méthode est utilisée pour la couche de convolution 2D transposée.
Conv3D (canaux, kernel_size [, foulées,…]) Cette méthode est utilisée pour la couche de convolution 3D. Par exemple, la convolution spatiale sur les volumes.
Conv3DTranspose (canaux, kernel_size [,…]) Cette méthode est utilisée pour la couche de convolution 3D transposée.
Dense (unités [, activation, use_bias,…]) Cette méthode représente votre couche NN régulière densément connectée.
Abandon (taux [, axes]) Comme son nom l'indique, la méthode applique Dropout à l'entrée.
ELU ([alpha]) Cette méthode est utilisée pour l'unité linéaire exponentielle (ELU).
Incorporation (input_dim, output_dim [, dtype,…]) Il transforme les entiers non négatifs en vecteurs denses de taille fixe.
Aplatir (** kwargs) Cette méthode aplatit l'entrée en 2D.
GELU (** kwargs) Cette méthode est utilisée pour l'unité linéaire exponentielle gaussienne (GELU).
GlobalAvgPool1D ([mise en page]) Avec l'aide de cette méthode, nous pouvons effectuer une opération de mise en commun moyenne globale pour les données temporelles.
GlobalAvgPool2D ([mise en page]) Avec l'aide de cette méthode, nous pouvons effectuer une opération de mise en commun moyenne globale pour les données spatiales.
GlobalAvgPool3D ([mise en page]) Avec l'aide de cette méthode, nous pouvons effectuer une opération de mise en commun moyenne globale pour les données 3-D.
GlobalMaxPool1D ([mise en page]) Avec l'aide de cette méthode, nous pouvons effectuer une opération de mise en commun globale maximale pour les données 1D.
GlobalMaxPool2D ([mise en page]) Avec l'aide de cette méthode, nous pouvons effectuer une opération de mise en commun globale maximale pour les données 2D.
GlobalMaxPool3D ([mise en page]) Avec l'aide de cette méthode, nous pouvons effectuer une opération de mise en commun globale maximale pour les données 3-D.
GroupNorm ([num_groups, epsilon, centre,…]) Cette méthode applique la normalisation de groupe au tableau d'entrée nD.
HybridBlock ([préfixe, paramètres]) Cette méthode prend en charge le transfert avec les deux Symbol et NDArray.
HybridLambda(fonction [, préfixe]) Avec l'aide de cette méthode, nous pouvons envelopper un opérateur ou une expression en tant qu'objet HybridBlock.
HybridSequential ([préfixe, paramètres]) Il empile les HybridBlocks de manière séquentielle.
InstanceNorm ([axe, epsilon, centre, échelle,…]) Cette méthode applique la normalisation d'instance au tableau d'entrée nD.

Exemples de mise en œuvre

Dans l'exemple ci-dessous, nous allons utiliser Block () qui donne la classe de base pour toutes les couches et modèles de réseau neuronal.

from mxnet.gluon import Block, nn
class Model(Block):
   def __init__(self, **kwargs):
      super(Model, self).__init__(**kwargs)
      # use name_scope to give child Blocks appropriate names.
      with self.name_scope():
         self.dense0 = nn.Dense(20)
         self.dense1 = nn.Dense(20)
   def forward(self, x):

      x = mx.nd.relu(self.dense0(x))
      return mx.nd.relu(self.dense1(x))

model = Model()
model.initialize(ctx=mx.cpu(0))
model(mx.nd.zeros((5, 5), ctx=mx.cpu(0)))

Output

Vous verrez la sortie suivante -

[[0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]]
<NDArray 5x20 @cpu(0)*gt;

Dans l'exemple ci-dessous, nous allons utiliser HybridBlock () qui prend en charge le transfert avec Symbol et NDArray.

import mxnet as mx
from mxnet.gluon import HybridBlock, nn


class Model(HybridBlock):
   def __init__(self, **kwargs):
      super(Model, self).__init__(**kwargs)
      # use name_scope to give child Blocks appropriate names.
      with self.name_scope():
         self.dense0 = nn.Dense(20)
         self.dense1 = nn.Dense(20)

   def forward(self, x):
      x = nd.relu(self.dense0(x))
      return nd.relu(self.dense1(x))
model = Model()
model.initialize(ctx=mx.cpu(0))

model.hybridize()
model(mx.nd.zeros((5, 5), ctx=mx.cpu(0)))

Output

La sortie est mentionnée ci-dessous -

[[0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]]
<NDArray 5x20 @cpu(0)>

gluon.rnn

Gluon fournit un grand nombre de recurrent neural network(RNN) dans le module gluon.rnn. C'est la raison pour laquelle on l'appelle le module principal.

Méthodes et leurs paramètres

Voici quelques-unes des méthodes importantes et leurs paramètres couverts par mxnet.gluon.nn module de base:

Méthodes et ses paramètres Définition
BidirectionalCell (l_cell, r_cell [,…]) Il est utilisé pour la cellule de réseau neuronal récurrent bidirectionnel (RNN).
DropoutCell (taux [, axes, préfixe, paramètres]) Cette méthode appliquera le décrochage sur l'entrée donnée.
GRU (hidden_size [, num_layers, layout,…]) Il applique un RNN d'unité récurrente à grille multicouche (GRU) à une séquence d'entrée donnée.
GRUCell (hidden_size [,…]) Il est utilisé pour la cellule de réseau GRU (Gated Rectified Unit).
HybridRecurrentCell ([préfixe, paramètres]) Cette méthode prend en charge l'hybridation.
HybridSequentialRNNCell ([préfixe, paramètres]) Avec l'aide de cette méthode, nous pouvons empiler séquentiellement plusieurs cellules HybridRNN.
LSTM (hidden_size [, num_layers, layout,…]) 0 Il applique un RNN de mémoire à long terme (LSTM) multicouche à une séquence d'entrée donnée.
LSTMCell (hidden_size [,…]) Il est utilisé pour la cellule de réseau de mémoire à long terme (LSTM).
ModifierCell (cellule_base) C'est la classe de base pour les cellules de modificateur.
RNN (hidden_size [, num_layers, activation,…]) Il applique un Elman RNN multicouche avec tanh ou ReLU non-linéarité à une séquence d'entrée donnée.
RNNCell (hidden_size [, activation,…]) Il est utilisé pour la cellule de réseau neuronal récurrent Elman RNN.
RecurrentCell ([prefix, params]) Il représente la classe de base abstraite pour les cellules RNN.
SequentialRNNCell ([prefix, params]) Avec l'aide de cette méthode, nous pouvons empiler séquentiellement plusieurs cellules RNN.
ZoneoutCell (base_cell [, zoneout_outputs,…]) Cette méthode applique Zoneout sur la cellule de base.

Exemples de mise en œuvre

Dans l'exemple ci-dessous, nous allons utiliser GRU () qui applique un RNN d'unité récurrente à grille multicouche (GRU) à une séquence d'entrée donnée.

layer = mx.gluon.rnn.GRU(100, 3)
layer.initialize()
input_seq = mx.nd.random.uniform(shape=(5, 3, 10))
out_seq = layer(input_seq)
h0 = mx.nd.random.uniform(shape=(3, 3, 100))
out_seq, hn = layer(input_seq, h0)
out_seq

Output

Cela produit la sortie suivante -

[[[ 1.50152072e-01 5.19012511e-01 1.02390535e-01 ... 4.35803324e-01
1.30406499e-01 3.30152437e-02]
[ 2.91542172e-01 1.02243155e-01 1.73325196e-01 ... 5.65296151e-02
1.76546033e-02 1.66693389e-01]
[ 2.22257316e-01 3.76294643e-01 2.11277917e-01 ... 2.28903517e-01
3.43954474e-01 1.52770668e-01]]


[[ 1.40634328e-01 2.93247789e-01 5.50393537e-02 ... 2.30207980e-01
6.61415309e-02 2.70989928e-02]
[ 1.11081995e-01 7.20834285e-02 1.08342394e-01 ... 2.28330195e-02
6.79589901e-03 1.25501186e-01]
[ 1.15944080e-01 2.41565228e-01 1.18612610e-01 ... 1.14908054e-01
1.61080107e-01 1.15969211e-01]]
………………………….

Example

hn

Output

Cela produit la sortie suivante -

[[[-6.08105101e-02 3.86217088e-02   6.64453954e-03 8.18805695e-02
3.85607071e-02 -1.36945639e-02 7.45836645e-03 -5.46515081e-03
9.49622393e-02 6.39371723e-02 -6.37890724e-03 3.82240303e-02
9.11015049e-02 -2.01375950e-02 -7.29381144e-02 6.93765879e-02
2.71829776e-02 -6.64435029e-02 -8.45306814e-02 -1.03075653e-01
6.72040805e-02 -7.06537142e-02 -3.93818803e-02 5.16211614e-03
-4.79770005e-02 1.10734522e-01 1.56721435e-02 -6.93409378e-03
1.16915874e-01 -7.95962065e-02 -3.06530762e-02 8.42394680e-02
7.60370195e-02 2.17055440e-01 9.85361822e-03 1.16660878e-01
4.08297703e-02 1.24978097e-02 8.25245082e-02 2.28673983e-02
-7.88266212e-02 -8.04114193e-02 9.28791538e-02 -5.70827350e-03
-4.46166918e-02 -6.41122833e-02 1.80885363e-02 -2.37745279e-03
4.37298454e-02 1.28888980e-01 -3.07202265e-02 2.50503756e-02
4.00907174e-02 3.37077095e-03 -1.78839862e-02 8.90695080e-02
6.30150884e-02 1.11416787e-01 2.12221760e-02 -1.13236710e-01
5.39616570e-02 7.80710578e-02 -2.28817668e-02 1.92073174e-02
………………………….

Dans l'exemple ci-dessous, nous allons utiliser LSTM () qui applique un RNN de mémoire à long-court terme (LSTM) à une séquence d'entrée donnée.

layer = mx.gluon.rnn.LSTM(100, 3)
layer.initialize()

input_seq = mx.nd.random.uniform(shape=(5, 3, 10))
out_seq = layer(input_seq)
h0 = mx.nd.random.uniform(shape=(3, 3, 100))
c0 = mx.nd.random.uniform(shape=(3, 3, 100))
out_seq, hn = layer(input_seq,[h0,c0])
out_seq

Output

La sortie est mentionnée ci-dessous -

[[[ 9.00025964e-02 3.96071747e-02 1.83841765e-01 ... 3.95872220e-02
1.25569820e-01 2.15555862e-01]
[ 1.55962542e-01 -3.10300849e-02 1.76772922e-01 ... 1.92474753e-01
2.30574399e-01 2.81707942e-02]
[ 7.83204585e-02 6.53361529e-03 1.27262697e-01 ... 9.97719541e-02
1.28254429e-01 7.55299702e-02]]
[[ 4.41036932e-02 1.35250352e-02 9.87644792e-02 ... 5.89378644e-03
5.23949116e-02 1.00922674e-01]
[ 8.59075040e-02 -1.67027581e-02 9.69351009e-02 ... 1.17763653e-01
9.71239135e-02 2.25218050e-02]
[ 4.34580036e-02 7.62207608e-04 6.37005866e-02 ... 6.14888743e-02
5.96345589e-02 4.72368896e-02]]
……………

Example

hn

Output

Lorsque vous exécutez le code, vous verrez la sortie suivante -

[
[[[ 2.21408084e-02 1.42750628e-02 9.53067932e-03 -1.22849066e-02
1.78788435e-02 5.99269159e-02 5.65306023e-02 6.42553642e-02
6.56616641e-03 9.80876666e-03 -1.15729487e-02 5.98640442e-02
-7.21173314e-03 -2.78371759e-02 -1.90690923e-02 2.21447181e-02
8.38765781e-03 -1.38521893e-02 -9.06938594e-03 1.21346042e-02
6.06449470e-02 -3.77471633e-02 5.65885007e-02 6.63008019e-02
-7.34188128e-03 6.46054149e-02 3.19911093e-02 4.11194898e-02
4.43960279e-02 4.92892228e-02 1.74766723e-02 3.40303481e-02
-5.23341820e-03 2.68163737e-02 -9.43402853e-03 -4.11836170e-02
1.55221792e-02 -5.05655073e-02 4.24557598e-03 -3.40388380e-02
……………………

Modules de formation

Les modules de formation de Gluon sont les suivants -

gluon.loss

Dans mxnet.gluon.lossmodule, Gluon fournit une fonction de perte prédéfinie. Fondamentalement, il a les pertes pour la formation du réseau neuronal. C'est la raison pour laquelle on l'appelle le module de formation.

Méthodes et leurs paramètres

Voici quelques-unes des méthodes importantes et leurs paramètres couverts par mxnet.gluon.loss module de formation:

Méthodes et ses paramètres Définition
Perte (poids, batch_axis, ** kwargs) Cela sert de classe de base pour la perte.
L2Loss ([poids, batch_axis]) Il calcule l'erreur quadratique moyenne (MSE) entre label et prediction(pred).
L1Loss ([poids, axe_batch]) Il calcule l'erreur absolue moyenne (MAE) entre label et pred.
SigmoidBinaryCrossEntropyLoss ([…]) Cette méthode est utilisée pour la perte d'entropie croisée pour la classification binaire.
SigmoïdeBCELoss Cette méthode est utilisée pour la perte d'entropie croisée pour la classification binaire.
SoftmaxCrossEntropyLoss ([axe,…]) Il calcule la perte d'entropie croisée softmax (CEL).
SoftmaxCELoss Il calcule également la perte d'entropie croisée softmax.
KLDivLoss ([from_logits, axe, poids,…]) Il est utilisé pour la perte de divergence Kullback-Leibler.
CTCLoss ([layout, label_layout, weight]) Il est utilisé pour la perte de classification temporelle connexionniste (TCL).
HuberLoss ([rho, poids, batch_axis]) Il calcule la perte L1 lissée. La perte L1 lissée sera égale à la perte L1 si l'erreur absolue dépasse rho mais est égale à la perte L2 dans le cas contraire.
HingeLoss ([margin, weight, batch_axis]) Cette méthode calcule la fonction de perte de charnière souvent utilisée dans les SVM:
SquaredHingeLoss ([margin, weight, batch_axis]) Cette méthode calcule la fonction de perte de marge souple utilisée dans les SVM:
LogisticLoss ([weight, batch_axis, label_format]) Cette méthode calcule la perte logistique.
TripletLoss ([margin, weight, batch_axis]) Cette méthode calcule la perte de triplets en fonction de trois tenseurs d'entrée et d'une marge positive.
PoissonNLLLoss ([poids, from_logits,…]) La fonction calcule la perte de probabilité du log négatif.
CosineEmbeddingLoss ([weight, batch_axis, margin]) La fonction calcule la distance cosinus entre les vecteurs.
SDMLLoss ([paramètre_lissage, poids,…]) Cette méthode calcule la perte d'apprentissage métrique profond lissé par lots (SDML) en fonction de deux tenseurs d'entrée et d'une perte SDM de poids de lissage. Il apprend la similitude entre les échantillons appariés en utilisant des échantillons non appariés dans le minibatch comme exemples potentiellement négatifs.

Exemple

Comme nous savons que mxnet.gluon.loss.losscalculera l'EQM (erreur quadratique moyenne) entre l'étiquette et la prédiction (préd). Cela se fait à l'aide de la formule suivante:

gluon.parameter

mxnet.gluon.parameter est un conteneur qui contient les paramètres c'est-à-dire les poids des blocs.

Méthodes et leurs paramètres

Voici quelques-unes des méthodes importantes et leurs paramètres couverts par mxnet.gluon.parameter module de formation -

Méthodes et ses paramètres Définition
cast (dtype) Cette méthode convertit les données et le gradient de ce paramètre en un nouveau type de données.
données ([ctx]) Cette méthode retournera une copie de ce paramètre sur un contexte.
grad ([ctx]) Cette méthode renverra un tampon de gradient pour ce paramètre sur un contexte.
initialiser ([init, ctx, default_init,…]) Cette méthode initialisera les tableaux de paramètres et de gradient.
list_ctx () Cette méthode retournera une liste de contextes sur lesquels ce paramètre est initialisé.
list_data () Cette méthode retournera des copies de ce paramètre dans tous les contextes. Cela se fera dans le même ordre que la création.
list_grad () Cette méthode retournera des tampons de dégradé sur tous les contextes. Cela se fera dans le même ordre quevalues().
list_row_sparse_data (id_ligne) Cette méthode retournera des copies du paramètre 'row_sparse' sur tous les contextes. Cela se fera dans le même ordre que la création.
reset_ctx (ctx) Cette méthode réaffectera le paramètre à d'autres contextes.
row_sparse_data (row_id) Cette méthode retournera une copie du paramètre 'row_sparse' dans le même contexte que celui de row_id.
set_data (données) Cette méthode définira la valeur de ce paramètre sur tous les contextes.
var () Cette méthode renverra un symbole représentant ce paramètre.
zero_grad () Cette méthode définira le tampon de dégradé sur tous les contextes sur 0.

Exemple d'implémentation

Dans l'exemple ci-dessous, nous initialiserons les paramètres et les tableaux de gradients en utilisant la méthode initialize () comme suit -

weight = mx.gluon.Parameter('weight', shape=(2, 2))
weight.initialize(ctx=mx.cpu(0))
weight.data()

Output

La sortie est mentionnée ci-dessous -

[[-0.0256899 0.06511251]
[-0.00243821 -0.00123186]]
<NDArray 2x2 @cpu(0)>

Example

weight.grad()

Output

La sortie est donnée ci-dessous -

[[0. 0.]
[0. 0.]]
<NDArray 2x2 @cpu(0)>

Example

weight.initialize(ctx=[mx.gpu(0), mx.gpu(1)])
weight.data(mx.gpu(0))

Output

Vous verrez la sortie suivante -

[[-0.00873779 -0.02834515]
 [ 0.05484822 -0.06206018]]
<NDArray 2x2 @gpu(0)>

Example

weight.data(mx.gpu(1))

Output

Lorsque vous exécutez le code ci-dessus, vous devriez voir la sortie suivante -

[[-0.00873779 -0.02834515]
 [ 0.05484822 -0.06206018]]
<NDArray 2x2 @gpu(1)>

gluon.trainer

mxnet.gluon.trainer applique un optimiseur sur un ensemble de paramètres. Il doit être utilisé avec autograd.

Méthodes et leurs paramètres

Voici quelques-unes des méthodes importantes et leurs paramètres couverts par mxnet.gluon.trainer module de formation -

Méthodes et ses paramètres Définition
allreduce_grads () Cette méthode réduira les gradients de différents contextes pour chaque paramètre (poids).
load_states (fname) Comme son nom l'indique, cette méthode chargera les états du formateur.
save_states (fname) Comme son nom l'indique, cette méthode enregistrera les états du formateur.
set_learning_rate (lr) Cette méthode définira un nouveau taux d'apprentissage de l'optimiseur.
étape (batch_size [, ignore_stale_grad]) Cette méthode fera une étape de mise à jour des paramètres. Il devrait être appelé aprèsautograd.backward() et en dehors de record() portée.
mise à jour (batch_size [, ignore_stale_grad]) Cette méthode fera également une étape de mise à jour des paramètres. Il devrait être appelé aprèsautograd.backward() et en dehors de record() scope et après trainer.update ().

Modules de données

Les modules de données de Gluon sont expliqués ci-dessous -

gluon.data

Gluon fournit un grand nombre d'utilitaires de jeu de données intégrés dans le module gluon.data. C'est la raison pour laquelle on l'appelle le module de données.

Classes et leurs paramètres

Voici quelques-unes des méthodes importantes et leurs paramètres couverts par le module principal mxnet.gluon.data. Ces méthodes sont généralement liées aux ensembles de données, à l'échantillonnage et à DataLoader.

Base de données
Méthodes et ses paramètres Définition
ArrayDataset (* args) Cette méthode représente un ensemble de données qui combine deux ou plus de deux objets de type ensemble de données. Par exemple, des ensembles de données, des listes, des tableaux, etc.
BatchSampler (échantillonneur, batch_size [, last_batch]) Cette méthode passe par-dessus une autre Sampler. Une fois emballé, il renvoie les mini lots d'échantillons.
DataLoader (ensemble de données [, batch_size, shuffle,…]) Similaire à BatchSampler, mais cette méthode charge les données d'un ensemble de données. Une fois chargé, il renvoie les mini lots de données.
Cela représente la classe de l'ensemble de données abstrait.
FilterSampler (fn, jeu de données) Cette méthode représente les exemples d'éléments d'un Dataset pour lesquels fn (fonction) renvoie True.
RandomSampler (longueur) Cette méthode représente des échantillons d'éléments de [0, longueur) au hasard sans remplacement.
RecordFileDataset (nom de fichier) Il représente un ensemble de données enveloppant un fichier RecordIO. L'extension du fichier est.rec.
Échantillonneur Il s'agit de la classe de base des échantillonneurs.
SequentialSampler (longueur [, début]) Il représente les éléments de l'échantillon de l'ensemble [début, début + longueur) séquentiellement.
Il représente les éléments de l'échantillon de l'ensemble [début, début + longueur) séquentiellement. Cela représente l'encapsuleur de jeu de données simple, en particulier pour les listes et les tableaux.

Exemples de mise en œuvre

Dans l'exemple ci-dessous, nous allons utiliser gluon.data.BatchSampler()API, qui englobe un autre échantillonneur. Il renvoie les mini lots d'échantillons.

import mxnet as mx
from mxnet.gluon import data
sampler = mx.gluon.data.SequentialSampler(15)
batch_sampler = mx.gluon.data.BatchSampler(sampler, 4, 'keep')
list(batch_sampler)

Output

La sortie est mentionnée ci-dessous -

[[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11], [12, 13, 14]]

gluon.data.vision.datasets

Gluon fournit un grand nombre de fonctions d'ensemble de données de vision prédéfinies dans gluon.data.vision.datasets module.

Classes et leurs paramètres

MXNet nous fournit des ensembles de données utiles et importants, dont les classes et les paramètres sont donnés ci-dessous -

Classes et ses paramètres Définition
MNIST ([racine, train, transformation]) Ceci est un ensemble de données utile nous fournissant les chiffres manuscrits. L'URL de l'ensemble de données MNIST est http://yann.lecun.com/exdb/mnist
FashionMNIST ([root, train, transformer]) Cet ensemble de données se compose d'images d'articles de Zalando constituées de produits de mode. Il s'agit d'un remplacement instantané de l'ensemble de données MNIST original. Vous pouvez obtenir cet ensemble de données sur https://github.com/zalandoresearch/fashion-mnist
CIFAR10 ([root, train, transform]) Il s'agit d'un ensemble de données de classification d'images de https://www.cs.toronto.edu/~kriz/cifar.html. Dans cet ensemble de données, chaque échantillon est une image de forme (32, 32, 3).
CIFAR100 ([root, fine_label, train, transform]) Il s'agit de l'ensemble de données de classification d'image CIFAR100 de https://www.cs.toronto.edu/~kriz/cifar.html. Il a également chaque échantillon est une image avec une forme (32, 32, 3).
ImageRecordDataset (nom de fichier [, indicateur, transformation]) Cet ensemble de données est enveloppé sur un fichier RecordIO qui contient des images. Dans ce chaque échantillon est une image avec son étiquette correspondante.
ImageFolderDataset (racine [, indicateur, transformation]) Il s'agit d'un ensemble de données pour le chargement de fichiers image stockés dans une structure de dossiers.
ImageListDataset ([racine, imglist, indicateur]) Il s'agit d'un ensemble de données pour le chargement de fichiers image spécifiés par une liste d'entrées.

Exemple

Dans l'exemple ci-dessous, nous allons montrer l'utilisation de ImageListDataset (), qui est utilisé pour charger des fichiers image qui sont spécifiés par une liste d'entrées -

# written to text file *.lst

0 0 root/cat/0001.jpg
1 0 root/cat/xxxa.jpg
2 0 root/cat/yyyb.jpg
3 1 root/dog/123.jpg
4 1 root/dog/023.jpg
5 1 root/dog/wwww.jpg

# A pure list, each item is a list [imagelabel: float or list of float, imgpath]

[[0, root/cat/0001.jpg]
[0, root/cat/xxxa.jpg]
[0, root/cat/yyyb.jpg]
[1, root/dog/123.jpg]
[1, root/dog/023.jpg]
[1, root/dog/wwww.jpg]]

Modules utilitaires

Les modules utilitaires de Gluon sont les suivants -

gluon.utils

Gluon fournit un grand nombre d'optimiseurs d'utilitaires de parallélisation intégrés dans le module gluon.utils. Il fournit une variété d'utilitaires pour la formation. C'est la raison pour laquelle il s'appelle le module utilitaire.

Fonctions et leurs paramètres

Voici les fonctions et leurs paramètres constitués par ce module utilitaire nommé gluon.utils −

Fonctions et ses paramètres Définition
split_data (données, num_slice [, batch_axis,…]) Cette fonction est généralement utilisée pour le parallélisme des données et chaque tranche est envoyée à un périphérique, à savoir le GPU. Il divise un NDArray ennum_slice tranche le long batch_axis.
split_and_load (données, ctx_list [, batch_axis,…]) Cette fonction divise un NDArray en len(ctx_list) tranche le long batch_axis. La seule différence avec la fonction split_data () ci-dessus est que, elle charge également chaque tranche dans un contexte dans ctx_list.
clip_global_norm (tableaux, max_norm [,…]) Le travail de cette fonction est de redimensionner les NDArrays de telle sorte que la somme de leur norme 2 soit inférieure à max_norm.
check_sha1 (nom de fichier, sha1_hash) Cette fonction vérifie si le hachage sha1 du contenu du fichier correspond ou non au hachage attendu.
télécharger (url [, chemin, écraser, sha1_hash,…]) Comme son nom l'indique, cette fonction téléchargera une URL donnée.
replace_file (src, dst) Cette fonction implémentera atomic os.replace. ce sera fait avec Linux et OSX.

Ce chapitre traite de l'API d'autograd et d'initialisation dans MXNet.

mxnet.autograd

Il s'agit de l'API autograd de MXNet pour NDArray. Il a la classe suivante -

Classe: Fonction ()

Il est utilisé pour la différenciation personnalisée en autograd. Il peut être écrit commemxnet.autograd.Function. Si, pour une raison quelconque, l'utilisateur ne souhaite pas utiliser les gradients calculés par la règle de chaîne par défaut, il peut utiliser la classe Function de mxnet.autograd pour personnaliser la différenciation pour le calcul. Il a deux méthodes à savoir Forward () et Backward ().

Comprenons le fonctionnement de cette classe à l'aide des points suivants -

  • Tout d'abord, nous devons définir notre calcul dans la méthode forward.

  • Ensuite, nous devons fournir la différenciation personnalisée dans la méthode descendante.

  • Maintenant, pendant le calcul du gradient, au lieu de la fonction arrière définie par l'utilisateur, mxnet.autograd utilisera la fonction arrière définie par l'utilisateur. Nous pouvons également transtyper en tableau numpy et en arrière pour certaines opérations en avant comme en arrière.

Example

Avant d'utiliser la classe mxnet.autograd.function, définissons une fonction sigmoïde stable avec des méthodes vers l'arrière et vers l'avant comme suit -

class sigmoid(mx.autograd.Function):
   def forward(self, x):
      y = 1 / (1 + mx.nd.exp(-x))
      self.save_for_backward(y)
      return y
   
   def backward(self, dy):
      y, = self.saved_tensors
      return dy * y * (1-y)

Maintenant, la classe de fonction peut être utilisée comme suit -

func = sigmoid()
x = mx.nd.random.uniform(shape=(10,))
x.attach_grad()
with mx.autograd.record():
m = func(x)
m.backward()
dx_grad = x.grad.asnumpy()
dx_grad

Output

Lorsque vous exécutez le code, vous verrez la sortie suivante -

array([0.21458015, 0.21291625, 0.23330082, 0.2361367 , 0.23086983,
0.24060014, 0.20326573, 0.21093895, 0.24968489, 0.24301809],
dtype=float32)

Méthodes et leurs paramètres

Voici les méthodes et leurs paramètres de la classe mxnet.autogard.function -

Méthodes et ses paramètres Définition
avant (heads [, head_grads, hold_graph,…]) Cette méthode est utilisée pour le calcul direct.
en arrière (heads [, head_grads, hold_graph,…]) Cette méthode est utilisée pour le calcul en arrière. Il calcule les gradients des têtes par rapport aux variables précédemment marquées. Cette méthode prend autant d'entrées que de sortie de l'avant. Il renvoie également autant de NDArray que d'entrées de transfert.
get_symbol (x) Cette méthode est utilisée pour récupérer l'historique de calcul enregistré comme Symbol.
grad (heads, variables [, head_grads,…]) Cette méthode calcule les gradients des têtes par rapport aux variables. Une fois calculés, au lieu d'être stockés dans variable.grad, les gradients seront renvoyés en tant que nouveaux NDArrays.
is_recording () Avec l'aide de cette méthode, nous pouvons obtenir le statut de l'enregistrement et non de l'enregistrement.
is_training () Avec l'aide de cette méthode, nous pouvons obtenir un statut sur la formation et les prévisions.
mark_variables (variables, gradients [, grad_reqs]) Cette méthode marquera les NDArrays comme des variables pour calculer le gradient pour l'autogradation. Cette méthode est la même que la fonction .attach_grad () dans une variable mais la seule différence est qu'avec cet appel, nous pouvons définir le gradient sur n'importe quelle valeur.
pause ([train_mode]) Cette méthode retourne un contexte de portée à utiliser dans l'instruction «with» pour les codes qui n'ont pas besoin de calculer des gradients.
prédire_mode () Cette méthode retourne un contexte de portée à utiliser dans l'instruction 'with' dans laquelle le comportement de transmission avant est défini sur le mode d'inférence et sans modifier les états d'enregistrement.
record ([train_mode]) Il renverra un autograd enregistrement du contexte de portée à utiliser dans l'instruction «with» et capture le code qui nécessite des gradients à calculer.
set_recording (is_recording) Similaire à is_recoring (), avec l'aide de cette méthode, nous pouvons obtenir l'état de l'enregistrement et non de l'enregistrement.
set_training (is_training) Similaire à is_traininig (), avec l'aide de cette méthode, nous pouvons définir le statut sur entraînement ou prédiction.
train_mode () Cette méthode renverra un contexte de portée à utiliser dans l'instruction 'with' dans laquelle le comportement de passage avant est défini sur le mode d'apprentissage et sans modifier les états d'enregistrement.

Exemple d'implémentation

Dans l'exemple ci-dessous, nous utiliserons la méthode mxnet.autograd.grad () pour calculer le gradient de tête par rapport aux variables -

x = mx.nd.ones((2,))
x.attach_grad()
with mx.autograd.record():
z = mx.nd.elemwise_add(mx.nd.exp(x), x)
dx_grad = mx.autograd.grad(z, [x], create_graph=True)
dx_grad

Output

La sortie est mentionnée ci-dessous -

[
[3.7182817 3.7182817]
<NDArray 2 @cpu(0)>]

Nous pouvons utiliser la méthode mxnet.autograd.predict_mode () pour renvoyer une portée à utiliser dans l'instruction 'with' -

with mx.autograd.record():
y = model(x)
with mx.autograd.predict_mode():
y = sampling(y)
backward([y])

mxnet.intializer

Il s'agit de l'API de MXNet pour l'initialiseur de pesée. Il a les classes suivantes -

Classes et leurs paramètres

Voici les méthodes et leurs paramètres de mxnet.autogard.function classe:

Classes et ses paramètres Définition
Bilinéaire () Avec l'aide de cette classe, nous pouvons initialiser le poids pour les couches de suréchantillonnage.
Constante (valeur) Cette classe initialise les poids à une valeur donnée. La valeur peut être un scalaire ou un NDArray qui correspond à la forme du paramètre à définir.
FusedRNN (init, num_hidden, num_layers, mode) Comme son nom l'indique, cette classe initialise les paramètres des couches fusionnées du réseau neuronal récurrent (RNN).
InitDesc Il agit comme le descripteur du modèle d'initialisation.
Initialiseur (** kwargs) Il s'agit de la classe de base d'un initialiseur.
LSTMBias ([forget_bias]) Cette classe initialise tous les biais d'un LSTMCell à 0,0 mais à l'exception de la porte Oublier dont le biais est défini sur une valeur personnalisée.
Load (param [, default_init, verbose]) Cette classe initialise les variables en chargeant des données à partir d'un fichier ou d'un dictionnaire.
MSRAPrelu ([type_facteur, pente]) Comme son nom l'indique, cette classe Initialise le poids selon un papier MSRA.
Mixte (modèles, initialiseurs) Il initialise les paramètres à l'aide de plusieurs initialiseurs.
Normal ([sigma]) La classe Normal () initialise les poids avec des valeurs aléatoires échantillonnées à partir d'une distribution normale avec une moyenne de zéro et un écart type (SD) de sigma.
Une() Il initialise les poids du paramètre à un.
Orthogonal ([scale, rand_type]) Comme son nom l'indique, cette classe initialise le poids en tant que matrice orthogonale.
Uniforme ([échelle]) Il initialise les poids avec des valeurs aléatoires qui sont uniformément échantillonnées dans une plage donnée.
Xavier ([rnd_type, factor_type, magnitude]) Il renvoie en fait un initialiseur qui effectue l'initialisation «Xavier» pour les poids.
Zéro() Il initialise les poids du paramètre à zéro.

Exemple d'implémentation

Dans l'exemple ci-dessous, nous utiliserons la classe mxnet.init.Normal () pour créer un initialiseur et récupérer ses paramètres -

init = mx.init.Normal(0.8)
init.dumps()

Output

La sortie est donnée ci-dessous -

'["normal", {"sigma": 0.8}]'

Example

init = mx.init.Xavier(factor_type="in", magnitude=2.45)
init.dumps()

Output

La sortie est indiquée ci-dessous -

'["xavier", {"rnd_type": "uniform", "factor_type": "in", "magnitude": 2.45}]'

Dans l'exemple ci-dessous, nous utiliserons la classe mxnet.initializer.Mixed () pour initialiser les paramètres à l'aide de plusieurs initialiseurs -

init = mx.initializer.Mixed(['bias', '.*'], [mx.init.Zero(),
mx.init.Uniform(0.1)])
module.init_params(init)

for dictionary in module.get_params():
for key in dictionary:
print(key)
print(dictionary[key].asnumpy())

Output

La sortie est indiquée ci-dessous -

fullyconnected1_weight
[[ 0.0097627 0.01856892 0.04303787]]
fullyconnected1_bias
[ 0.]

Dans ce chapitre, nous découvrirons une interface dans MXNet appelée Symbol.

Mxnet.ndarray

L'API Symbol d'Apache MXNet est une interface pour la programmation symbolique. Symbol API propose l'utilisation des éléments suivants -

  • Graphiques informatiques

  • Utilisation de la mémoire réduite

  • Optimisation des fonctions de pré-utilisation

L'exemple donné ci-dessous montre comment créer une expression simple en utilisant l'API Symbol de MXNet -

Un NDArray en utilisant un 'tableau' 1-D et 2-D à partir d'une liste Python régulière -

import mxnet as mx
# Two placeholders namely x and y will be created with mx.sym.variable
x = mx.sym.Variable('x')
y = mx.sym.Variable('y')
# The symbol here is constructed using the plus ‘+’ operator.
z = x + y

Output

Vous verrez la sortie suivante -

<Symbol _plus0>

Example

(x, y, z)

Output

La sortie est donnée ci-dessous -

(<Symbol x>, <Symbol y>, <Symbol _plus0>)

Voyons maintenant en détail les classes, les fonctions et les paramètres de l'API ndarray de MXNet.

Des classes

Le tableau suivant comprend les classes de Symbol API de MXNet -

Classe Définition
Symbole (poignée) Cette classe à savoir symbol est le graphe symbolique d'Apache MXNet.

Fonctions et leurs paramètres

Voici quelques-unes des fonctions importantes et leurs paramètres couverts par l'API mxnet.Symbol -

Fonction et ses paramètres Définition
Activation ([data, act_type, out, name]) Il applique une fonction d'activation élément par élément à l'entrée. Elle supporterelu, sigmoid, tanh, softrelu, softsign fonctions d'activation.
BatchNorm ([data, gamma, beta, moving_mean,…]) Il est utilisé pour la normalisation des lots. Cette fonction normalise un lot de données par la moyenne et la variance. Il applique une échellegamma et offset beta.
BilinearSampler ([données, grille, cudnn_off,…]) Cette fonction applique un échantillonnage bilinéaire à la carte d'entités en entrée. En fait, c'est la clé des «Réseaux de Transformateurs Spatiaux». Si vous êtes familier avec la fonction de remappage dans OpenCV, l'utilisation de cette fonction est assez similaire à cela. La seule différence est qu'il a la passe arrière.
BlockGrad ([données, sortie, nom]) Comme son nom l'indique, cette fonction arrête le calcul du gradient. Il empêche essentiellement le gradient accumulé des entrées de traverser cet opérateur dans le sens inverse.
cast ([données, type, sortie, nom]) Cette fonction convertira tous les éléments de l'entrée dans un nouveau type.
Cette fonction convertira tous les éléments de l'entrée dans un nouveau type. Cette fonction, comme son nom est spécifié, retourne un nouveau symbole de forme et de type donnés, rempli de zéros.
uns (forme [, dtype]) Cette fonction, comme le nom spécifié, renvoie un nouveau symbole de forme et de type donnés, rempli de uns.
plein (forme, val [, dtype]) Cette fonction, comme le nom spécifié, renvoie un nouveau tableau de forme et de type donnés, rempli avec la valeur donnée val.
organiser (démarrer [, arrêter, avancer, répéter,…]) Il renverra des valeurs régulièrement espacées dans un intervalle donné. Les valeurs sont générées dans un intervalle semi-ouvert [démarrage, arrêt) ce qui signifie que l'intervalle comprendstart mais exclut stop.
linspace (start, stop, num [, endpoint, name,…]) Il renverra des nombres régulièrement espacés dans un intervalle spécifié. Similaire à la fonction arrange (), les valeurs sont générées dans un intervalle à moitié ouvert [start, stop), ce qui signifie que l'intervalle comprendstart mais exclut stop.
histogramme (a [, bins, range]) Comme son nom l'indique, cette fonction calculera l'histogramme des données d'entrée.
puissance (base, exp) Comme son nom l'indique, cette fonction retournera le résultat élément par élément de base élément élevé aux pouvoirs de expélément. Les deux entrées, c'est-à-dire base et exp, peuvent être symboliques ou scalaires. Notez ici que la diffusion n'est pas autorisée. Vous pouvez utiliserbroadcast_pow si vous souhaitez utiliser la fonction de diffusion.
SoftmaxActivation ([données, mode, nom, attr, sortie]) Cette fonction applique l'activation softmax à l'entrée. Il est destiné aux couches internes. Il est en fait obsolète, nous pouvons utilisersoftmax() au lieu.

Exemples de mise en œuvre

Dans l'exemple ci-dessous, nous utiliserons la fonction power() qui retournera le résultat élément par élément de l'élément de base élevé aux puissances de l'élément exp:

import mxnet as mx
mx.sym.power(3, 5)

Output

Vous verrez la sortie suivante -

243

Example

x = mx.sym.Variable('x')
y = mx.sym.Variable('y')
z = mx.sym.power(x, 3)
z.eval(x=mx.nd.array([1,2]))[0].asnumpy()

Output

Cela produit la sortie suivante -

array([1., 8.], dtype=float32)

Example

z = mx.sym.power(4, y)
z.eval(y=mx.nd.array([2,3]))[0].asnumpy()

Output

Lorsque vous exécutez le code ci-dessus, vous devriez voir la sortie suivante -

array([16., 64.], dtype=float32)

Example

z = mx.sym.power(x, y)
z.eval(x=mx.nd.array([4,5]), y=mx.nd.array([2,3]))[0].asnumpy()

Output

La sortie est mentionnée ci-dessous -

array([ 16., 125.], dtype=float32)

Dans l'exemple ci-dessous, nous utiliserons la fonction SoftmaxActivation() (or softmax()) qui sera appliqué à l'entrée et est destiné aux couches internes.

input_data = mx.nd.array([[2., 0.9, -0.5, 4., 8.], [4., -.7, 9., 2., 0.9]])
soft_max_act = mx.nd.softmax(input_data)
print (soft_max_act.asnumpy())

Output

Vous verrez la sortie suivante -

[[2.4258138e-03 8.0748333e-04 1.9912292e-04 1.7924475e-02 9.7864312e-01]
[6.6843745e-03 6.0796250e-05 9.9204916e-01 9.0463174e-04 3.0112563e-04]]

symbole.contrib

L'API Contrib NDArray est définie dans le package symbol.contrib. Il fournit généralement de nombreuses API expérimentales utiles pour les nouvelles fonctionnalités. Cette API fonctionne comme un endroit pour la communauté où ils peuvent essayer les nouvelles fonctionnalités. Le contributeur de la fonctionnalité recevra également les commentaires.

Fonctions et leurs paramètres

Voici quelques-unes des fonctions importantes et leurs paramètres couverts par mxnet.symbol.contrib API -

Fonction et ses paramètres Définition
rand_zipfian (true_classes, num_sampled,…) Cette fonction tire des échantillons aléatoires à partir d'une distribution approximativement Zipfienne. La distribution de base de cette fonction est la distribution Zipfian. Cette fonction échantillonne aléatoirement les candidats num_sampled et les éléments de sampled_candidates sont tirés de la distribution de base donnée ci-dessus.
foreach (corps, données, init_states) Comme son nom l'indique, cette fonction exécute une boucle avec un calcul défini par l'utilisateur sur NDArrays sur la dimension 0. Cette fonction simule une boucle for et le corps a le calcul pour une itération de la boucle for.
while_loop (cond, func, loop_vars [,…]) Comme son nom l'indique, cette fonction exécute une boucle while avec un calcul et une condition de boucle définis par l'utilisateur. Cette fonction simule une boucle while qui effectue un calcul personnalisé si la condition est satisfaite.
cond (pred, then_func, else_func) Comme son nom l'indique, cette fonction exécute un if-then-else en utilisant une condition et un calcul définis par l'utilisateur. Cette fonction simule une branche de type if qui choisit de faire l'un des deux calculs personnalisés selon la condition spécifiée.
getnnz ([données, axe, sortie, nom]) Cette fonction nous donne le nombre de valeurs stockées pour un tenseur clairsemé. Il comprend également des zéros explicites. Il ne prend en charge que la matrice CSR sur le processeur.
requantize ([données, plage_min, plage_max,…]) Cette fonction requantise les données données qui sont quantifiées dans int32 et les seuils correspondants, dans int8 en utilisant les seuils min et max calculés à l'exécution ou à partir de l'étalonnage.
index_copy ([ancien_tenseur, vecteur_index,…]) Cette fonction copie les éléments d'un new_tensor into the old_tensor by selecting the indices in the order given in index. The output of this operator will be a new tensor that contains the rest elements of old tensor and the copied elements of new tensor.
interleaved_matmul_encdec_qk ([requêtes,…]) Cet opérateur calcule la multiplication matricielle entre les projections de requêtes et de clés en utilisation attention multi-têtes comme encodeur-décodeur. La condition est que les entrées doivent être un tenseur de projections de requêtes qui suit le layout: (seq_length, batch_size, num_heads *, head_dim).

Exemples de mise en œuvre

Dans l'exemple ci-dessous, nous utiliserons la fonction rand_zipfian pour tirer des échantillons aléatoires à partir d'une distribution approximativement Zipfienne -

import mxnet as mx
true_cls = mx.sym.Variable('true_cls')
samples, exp_count_true, exp_count_sample = mx.sym.contrib.rand_zipfian(true_cls, 5, 6)
samples.eval(true_cls=mx.nd.array([3]))[0].asnumpy()

Output

Vous verrez la sortie suivante -

array([4, 0, 2, 1, 5], dtype=int64)

Example

exp_count_true.eval(true_cls=mx.nd.array([3]))[0].asnumpy()

Output

La sortie est mentionnée ci-dessous -

array([0.57336551])

Example

exp_count_sample.eval(true_cls=mx.nd.array([3]))[0].asnumpy()

Output

Vous verrez la sortie suivante -

array([1.78103594, 0.46847373, 1.04183923, 0.57336551, 1.04183923])

Dans l'exemple ci-dessous, nous utiliserons la fonction while_loop pour exécuter une boucle while pour un calcul défini par l'utilisateur et une condition de boucle -

cond = lambda i, s: i <= 7
func = lambda i, s: ([i + s], [i + 1, s + i])
loop_vars = (mx.sym.var('i'), mx.sym.var('s'))
outputs, states = mx.sym.contrib.while_loop(cond, func, loop_vars, max_iterations=10)
print(outputs)

Output

La sortie est donnée ci-dessous:

[<Symbol _while_loop0>]

Example

Print(States)

Output

Cela produit la sortie suivante -

[<Symbol _while_loop0>, <Symbol _while_loop0>]

Dans l'exemple ci-dessous, nous utiliserons la fonction index_copy qui copie les éléments de new_tensor dans le old_tensor.

import mxnet as mx
a = mx.nd.zeros((6,3))
b = mx.nd.array([[1,2,3],[4,5,6],[7,8,9]])
index = mx.nd.array([0,4,2])
mx.nd.contrib.index_copy(a, index, b)

Output

Lorsque vous exécutez le code ci-dessus, vous devriez voir la sortie suivante -

[[1. 2. 3.]
[0. 0. 0.]
[7. 8. 9.]
[0. 0. 0.]
[4. 5. 6.]
[0. 0. 0.]]
<NDArray 6x3 @cpu(0)>

symbol.image

L'API Image Symbol est définie dans le package symbol.image. Comme son nom l'indique, il est généralement utilisé pour les images et leurs caractéristiques.

Fonctions et leurs paramètres

Voici quelques-unes des fonctions importantes et leurs paramètres couverts par mxnet.symbol.image API -

Fonction et ses paramètres Définition
Adjust_lighting ([données, alpha, sortie, nom]) Comme son nom l'indique, cette fonction ajuste le niveau d'éclairage de l'entrée. Il suit le style AlexNet.
rognage ([données, x, y, largeur, hauteur, extérieur, nom]) Avec l'aide de cette fonction, nous pouvons recadrer une image NDArray de forme (H x L x C) ou (N x H x L x C) à la taille donnée par l'utilisateur.
normaliser ([données, moyenne, std, sortie, nom]) Il normalisera un tenseur de forme (C x H x L) ou (N x C x H x L) avec mean et standard deviation(SD).
random_crop ([data, xrange, yrange, width,…]) Semblable à crop (), il recadre au hasard une image NDArray de forme (H x L x C) ou (N x H x L x C) à la taille donnée par l'utilisateur. Il suréchantillonnera le résultat sisrc est plus petit que le size.
random_lighting([données, alpha_std, sortie, nom]) Comme son nom l'indique, cette fonction ajoute le bruit PCA de manière aléatoire. Il suit également le style AlexNet.
random_resized_crop ([data, xrange, yrange,…]) Il recadre également une image au hasard NDArray de forme (H x L x C) ou (N x H x L x C) à la taille donnée. Il suréchantillonnera le résultat si src est plus petit que la taille. Cela randomisera également la zone et l'aspect rationnel.
redimensionner ([données, taille, keep_ratio, interp,…]) Comme son nom l'indique, cette fonction redimensionnera une image NDArray de forme (H x L x C) ou (N x H x L x C) à la taille donnée par l'utilisateur.
to_tensor ([données, sortie, nom]) Il convertit une image NDArray de forme (H x L x C) ou (N x H x L x C) avec les valeurs dans l'intervalle [0, 255] en un tenseur NDArray de forme (C x H x L) ou ( N x C x H x L) avec les valeurs dans la plage [0, 1].

Exemples de mise en œuvre

Dans l'exemple ci-dessous, nous utiliserons la fonction to_tensor pour convertir l'image NDArray de forme (H x L x C) ou (N x H x L x C) avec les valeurs dans l'intervalle [0, 255] en un tenseur NDArray de forme (C x H x L) ou (N x C x H x L) avec les valeurs dans la plage [0, 1].

import numpy as np

img = mx.sym.random.uniform(0, 255, (4, 2, 3)).astype(dtype=np.uint8)

mx.sym.image.to_tensor(img)

Output

La sortie est indiquée ci-dessous -

<Symbol to_tensor4>

Example

img = mx.sym.random.uniform(0, 255, (2, 4, 2, 3)).astype(dtype=np.uint8)

mx.sym.image.to_tensor(img)

Output

La sortie est mentionnée ci-dessous:

<Symbol to_tensor5>

Dans l'exemple ci-dessous, nous utiliserons la fonction normalize () pour normaliser un tenseur de forme (C x H x W) ou (N x C x H x W) avec mean et standard deviation(SD).

img = mx.sym.random.uniform(0, 1, (3, 4, 2))

mx.sym.image.normalize(img, mean=(0, 1, 2), std=(3, 2, 1))

Output

Ci-dessous est la sortie du code -

<Symbol normalize0>

Example

img = mx.sym.random.uniform(0, 1, (2, 3, 4, 2))

mx.sym.image.normalize(img, mean=(0, 1, 2), std=(3, 2, 1))

Output

La sortie est indiquée ci-dessous -

<Symbol normalize1>

symbole aléatoire

L'API Random Symbol est définie dans le package symbol.random. Comme son nom l'indique, il s'agit du générateur de distribution aléatoire Symbol API de MXNet.

Fonctions et leurs paramètres

Voici quelques-unes des fonctions importantes et leurs paramètres couverts par mxnet.symbol.random API -

Fonction et ses paramètres Définition
uniforme ([faible, élevé, forme, type d, ctx, sortie]) Il génère des échantillons aléatoires à partir d'une distribution uniforme.
normal ([loc, scale, shape, dtype, ctx, out]) Il génère des échantillons aléatoires à partir d'une distribution normale (gaussienne).
randn (* forme, ** kwargs) Il génère des échantillons aléatoires à partir d'une distribution normale (gaussienne).
poisson ([lam, forme, type d, ctx, sortie]) Il génère des échantillons aléatoires à partir d'une distribution de Poisson.
exponentielle ([scale, shape, dtype, ctx, out]) Il génère des échantillons à partir d'une distribution exponentielle.
gamma ([alpha, beta, shape, dtype, ctx, out]) Il génère des échantillons aléatoires à partir d'une distribution gamma.
multinomial (data [, shape, get_prob, out, dtype]) Il génère un échantillonnage simultané à partir de plusieurs distributions multinomiales.
négatif_binomial ([k, p, forme, dtype, ctx, sortie]) Il génère des échantillons aléatoires à partir d'une distribution binomiale négative.
generalized_negative_binomial ([mu, alpha,…]) Il génère des échantillons aléatoires à partir d'une distribution binomiale négative généralisée.
aléatoire (données, ** kwargs) Il mélange les éléments au hasard.
randint (faible, élevé [, forme, type, ctx, sortie]) Il génère des échantillons aléatoires à partir d'une distribution uniforme discrète.
exponential_like ([data, lam, out, name]) Il génère des échantillons aléatoires à partir d'une distribution exponentielle en fonction de la forme du tableau d'entrée.
gamma_like ([données, alpha, bêta, sortie, nom]) Il génère des échantillons aléatoires à partir d'une distribution gamma en fonction de la forme du tableau d'entrée.
generalized_negative_binomial_like ([données,…]) Il génère des échantillons aléatoires à partir d'une distribution binomiale négative généralisée en fonction de la forme du tableau d'entrée.
negatif_binomial_like ([données, k, p, sortie, nom]) Il génère des échantillons aléatoires à partir d'une distribution binomiale négative en fonction de la forme du tableau d'entrée.
normal_like ([data, loc, scale, out, name]) Il génère des échantillons aléatoires à partir d'une distribution normale (gaussienne) en fonction de la forme du tableau d'entrée.
poisson_like ([données, lam, out, nom]) Il génère des échantillons aléatoires à partir d'une distribution de Poisson en fonction de la forme du tableau d'entrée.
uniform_like ([données, faible, élevé, sortie, nom]) Il génère des échantillons aléatoires à partir d'une distribution uniforme en fonction de la forme du tableau d'entrée.

Exemples de mise en œuvre

Dans l'exemple ci-dessous, nous allons mélanger les éléments de manière aléatoire en utilisant la fonction shuffle (). Il mélangera le tableau le long du premier axe.

data = mx.nd.array([[0, 1, 2], [3, 4, 5], [6, 7, 8],[9,10,11]])
x = mx.sym.Variable('x')
y = mx.sym.random.shuffle(x)
y.eval(x=data)

Output

Vous verrez la sortie suivante:

[
[[ 9. 10. 11.]
[ 0. 1. 2.]
[ 6. 7. 8.]
[ 3. 4. 5.]]
<NDArray 4x3 @cpu(0)>]

Example

y.eval(x=data)

Output

Lorsque vous exécutez le code ci-dessus, vous devriez voir la sortie suivante -

[
[[ 6. 7. 8.]
[ 0. 1. 2.]
[ 3. 4. 5.]
[ 9. 10. 11.]]
<NDArray 4x3 @cpu(0)>]

Dans l'exemple ci-dessous, nous allons tirer des échantillons aléatoires à partir d'une distribution binomiale négative généralisée. Pour cela, nous utiliserons la fonctiongeneralized_negative_binomial().

mx.sym.random.generalized_negative_binomial(10, 0.1)

Output

La sortie est donnée ci-dessous -

<Symbol _random_generalized_negative_binomial0>

symbol.sparse

L'API Sparse Symbol est définie dans le package mxnet.symbol.sparse. Comme son nom l'indique, il fournit des graphiques de réseau neuronal clairsemés et une différenciation automatique sur le processeur.

Fonctions et leurs paramètres

Voici quelques-unes des fonctions importantes (comprend les routines de création de symboles, les routines de manipulation de symboles, les fonctions mathématiques, la fonction trigonométrique, les fonctions hyberboliques, les fonctions de réduction, l'arrondi, les puissances, le réseau neuronal) et leurs paramètres couverts par mxnet.symbol.sparse API -

Fonction et ses paramètres Définition
ElementWiseSum (* args, ** kwargs) Cette fonction ajoutera tous les arguments d'entrée par élément. Par exemple, _ (1,2,… = 1 + 2 + ⋯ +). Ici, nous pouvons voir que add_n est potentiellement plus efficace que d'appeler add par n fois.
Incorporation ([données, poids, input_dim,…]) Il mappera les indices entiers sur des représentations vectorielles, c'est-à-dire des plongements. Il mappe en fait les mots sur des vecteurs à valeur réelle dans un espace de grande dimension, appelé embeddings de mots.
LinearRegressionOutput ([données, étiquette,…]) Il calcule et optimise la perte au carré lors de la propagation vers l'arrière en ne donnant que les données de sortie pendant la propagation vers l'avant.
LogisticRegressionOutput ([données, étiquette,…]) Applique une fonction logistique également appelée fonction sigmoïde à l'entrée. La fonction est calculée comme 1/1 + exp (−x).
MAERegressionOutput ([données, étiquette,…]) Cet opérateur calcule l'erreur absolue moyenne de l'entrée. MAE est en fait une mesure de risque correspondant à la valeur attendue de l'erreur absolue.
abs ([données, nom, attr, sortie]) Comme son nom l'indique, cette fonction retournera la valeur absolue élément par élément de l'entrée.
adagrad_update ([poids, diplôme, historique, lr,…]) C'est une fonction de mise à jour pour AdaGrad optimizer.
adam_update ([poids, grad, moyenne, var, lr,…]) C'est une fonction de mise à jour pour Adam optimizer.
add_n (* args, ** kwargs) Comme son nom l'indique, il ajoutera tous les arguments d'entrée élément par élément.
arccos ([données, nom, attr, sortie]) Cette fonction renvoie le cosinus inverse élément par élément du tableau d'entrée.
point ([lhs, rhs, transpose_a, transpose_b,…]) Comme son nom l'indique, il donnera le produit scalaire de deux tableaux. Cela dépendra de la dimension du tableau d'entrée: 1-D: produit interne des vecteurs 2-D: multiplication matricielle ND: un produit de somme sur le dernier axe de la première entrée et le premier axe de la deuxième entrée.
elemwise_add ([lhs, rhs, nom, attr, sortie]) Comme son nom l'indique, il sera add arguments élément par élément.
elemwise_div ([lhs, rhs, nom, attr, sortie]) Comme son nom l'indique, il sera divide arguments élément par élément.
elemwise_mul ([lhs, rhs, nom, attr, sortie]) Comme son nom l'indique, il sera Multiply arguments élément par élément.
elemwise_sub ([lhs, rhs, nom, attr, sortie]) Comme son nom l'indique, il soustrayera les arguments par élément.
exp ([données, nom, attr, sortie]) Cette fonction retournera la valeur exponentielle élément par élément de l'entrée donnée.
sgd_update ([poids, grad, lr, wd,…]) Il agit comme une fonction de mise à jour pour l'optimiseur Stochastic Gradient Descent.
sigmoïde ([données, nom, attr, sortie]) Comme son nom l'indique, il calculera sigmoid de x élément par élément.
signe ([données, nom, attr, sortie]) Il renverra le signe élémentaire de l'entrée donnée.
sin ([données, nom, attr, sortie]) Comme son nom l'indique, cette fonction calcule le sinus élément par élément du tableau d'entrée donné.

Exemple d'implémentation

Dans l'exemple ci-dessous, nous allons mélanger les éléments au hasard en utilisant ElementWiseSum()fonction. Il mappera les indices entiers sur des représentations vectorielles, c'est-à-dire des embeddings de mots.

input_dim = 4
output_dim = 5

Example

/* Here every row in weight matrix y represents a word. So, y = (w0,w1,w2,w3)
y = [[ 0., 1., 2., 3., 4.],
[ 5., 6., 7., 8., 9.],
[ 10., 11., 12., 13., 14.],
[ 15., 16., 17., 18., 19.]]
/* Here input array x represents n-grams(2-gram). So, x = [(w1,w3), (w0,w2)]
x = [[ 1., 3.],
[ 0., 2.]]
/* Now, Mapped input x to its vector representation y.
Embedding(x, y, 4, 5) = [[[ 5., 6., 7., 8., 9.],
[ 15., 16., 17., 18., 19.]],
[[ 0., 1., 2., 3., 4.],
[ 10., 11., 12., 13., 14.]]]

L'API du module d'Apache MXNet est comme un modèle FeedForward et il est plus facile de composer comme le module Torch. Il se compose des classes suivantes -

BaseModule ([enregistreur])

Il représente la classe de base d'un module. Un module peut être considéré comme un composant de calcul ou une machine de calcul. Le travail d'un module est d'exécuter des passes avant et arrière. Il met également à jour les paramètres d'un modèle.

Méthodes

Le tableau suivant montre les méthodes consistant en BaseModule class-

Cette méthode obtiendra les états de tous les appareils
Méthodes Définition
en arrière ([out_grads]) Comme son nom l'indique, cette méthode implémente le backward calcul.
bind (data_shapes [, label_shapes,…]) Il lie les symboles pour construire des exécuteurs et c'est nécessaire avant de pouvoir effectuer le calcul avec le module.
fit (train_data [, eval_data, eval_metric,…]) Cette méthode entraîne les paramètres du module.
forward (data_batch [, is_train]) Comme son nom l'indique, cette méthode implémente le calcul Forward. Cette méthode prend en charge les lots de données avec différentes formes telles que différentes tailles de lots ou différentes tailles d'image.
forward_backward (data_batch) C'est une fonction pratique, comme son nom l'indique, qui appelle à la fois en avant et en arrière.
get_input_grads ([merge_multi_context]) Cette méthode obtiendra les gradients vers les entrées qui sont calculées dans le calcul inverse précédent.
get_outputs ([merge_multi_context]) Comme son nom l'indique, cette méthode obtiendra les sorties du calcul direct précédent.
get_params () Il obtient les paramètres en particulier ceux qui sont potentiellement des copies des paramètres réels utilisés pour faire le calcul sur l'appareil.
get_states ([merge_multi_context])
init_optimizer ([kvstore, optimiseur,…]) Cette méthode installe et initialise les optimiseurs. Il initialise égalementkvstore pour distribuer la formation.
init_params ([initialiseur, arg_params,…]) Comme son nom l'indique, cette méthode initialisera les paramètres et les états auxiliaires.
install_monitor (mon) Cette méthode installera le moniteur sur tous les exécuteurs.
iter_predict (eval_data [, num_batch, reset,…]) Cette méthode itérera sur les prédictions.
load_params (fname) Comme son nom l'indique, il chargera les paramètres du modèle à partir du fichier.
prédire (eval_data [, num_batch,…]) Il exécutera la prédiction et collectera également les sorties.
préparer (data_batch [, sparse_row_id_fn]) L'opérateur prépare le module pour traiter un lot de données donné.
save_params (fname) Comme son nom l'indique, cette fonction enregistrera les paramètres du modèle dans un fichier.
score (eval_data, eval_metric [, num_batch,…]) Il exécute la prédiction sur eval_data et évalue également les performances en fonction du eval_metric.
set_params (arg_params, aux_params [,…]) Cette méthode attribuera les valeurs de paramètre et d'état aux.
set_states ([états, valeur]) Cette méthode, comme son nom l'indique, définit la valeur des états.
mettre à jour() Cette méthode met à jour les paramètres donnés en fonction de l'optimiseur installé. Il met également à jour les dégradés calculés dans le précédent lot avant-arrière.
update_metric (eval_metric, labels [, pre_sliced]) Cette méthode, comme son nom l'indique, évalue et accumule la métrique d'évaluation sur les sorties du dernier calcul direct.
en arrière ([out_grads]) Comme son nom l'indique, cette méthode implémente le backward calcul.
bind (data_shapes [, label_shapes,…]) Il configure les compartiments et lie l'exécuteur à la clé de compartiment par défaut. Cette méthode représente la liaison pour unBucketingModule.
forward (data_batch [, is_train]) Comme son nom l'indique, cette méthode implémente le calcul Forward. Cette méthode prend en charge les lots de données avec différentes formes telles que différentes tailles de lots ou différentes tailles d'image.
get_input_grads ([merge_multi_context]) Cette méthode obtiendra les gradients vers les entrées qui sont calculées dans le calcul inverse précédent.
get_outputs ([merge_multi_context]) Comme son nom l'indique, cette méthode obtiendra les sorties du calcul direct précédent.
get_params () Il obtient les paramètres actuels, en particulier ceux qui sont potentiellement des copies des paramètres réels utilisés pour faire le calcul sur l'appareil.
get_states ([merge_multi_context]) Cette méthode obtiendra les états de tous les appareils.
init_optimizer ([kvstore, optimiseur,…]) Cette méthode installe et initialise les optimiseurs. Il initialise égalementkvstore pour distribuer la formation.
init_params ([initialiseur, arg_params,…]) Comme son nom l'indique, cette méthode initialisera les paramètres et les états auxiliaires.
install_monitor (mon) Cette méthode installera le moniteur sur tous les exécuteurs.
load (préfixe, epoch [, sym_gen,…]) Cette méthode créera un modèle à partir du point de contrôle précédemment enregistré.
load_dict ([sym_dict, sym_gen,…]) Cette méthode créera un modèle à partir d'un mappage de dictionnaire (dict) bucket_keyaux symboles. Il partage égalementarg_params et aux_params.
préparer (data_batch [, sparse_row_id_fn]) L'opérateur prépare le module pour traiter un lot de données donné.
save_checkpoint (préfixe, epoch [, remove_amp_cast]) Cette méthode, comme son nom l'indique, enregistre la progression actuelle au point de contrôle pour tous les compartiments de BucketingModule. Il est recommandé d'utiliser mx.callback.module_checkpoint comme epoch_end_callback pour enregistrer pendant l'entraînement.
set_params (arg_params, aux_params [,…]) Comme son nom l'indique, cette fonction affectera des paramètres et des valeurs d'état aux.
set_states ([états, valeur]) Cette méthode, comme son nom l'indique, définit la valeur des états.
switch_bucket (bucket_key, data_shapes [,…]) Il basculera vers un seau différent.
mettre à jour() Cette méthode met à jour les paramètres donnés en fonction de l'optimiseur installé. Il met également à jour les dégradés calculés dans le précédent lot avant-arrière.
update_metric (eval_metric, labels [, pre_sliced]) Cette méthode, comme son nom l'indique, évalue et accumule la métrique d'évaluation sur les sorties du dernier calcul direct.

Les attributs

Le tableau suivant montre les attributs constitués par les méthodes de BaseModule classe -

Les attributs Définition
data_names Il se compose de la liste des noms des données requises par ce module.
data_shapes Il se compose de la liste des paires (nom, forme) spécifiant les entrées de données dans ce module.
label_shapes Il montre la liste des paires (nom, forme) spécifiant les entrées d'étiquette de ce module.
noms_sortie Il se compose de la liste des noms des sorties de ce module.
output_shapes Il se compose de la liste des paires (nom, forme) spécifiant les sorties de ce module.
symbole Comme son nom est spécifié, cet attribut obtient le symbole associé à ce module.

data_shapes: Vous pouvez consulter le lien disponible sur https://mxnet.apache.orgpour plus de détails. output_shapes: Plus

output_shapes: plus d'informations sont disponibles sur https://mxnet.apache.org/api/python

BucketingModule (sym_gen […])

Il représente le Bucketingmodule classe d'un module qui permet de traiter efficacement des entrées de longueur variable.

Méthodes

Le tableau suivant montre les méthodes consistant en BucketingModule class -

Les attributs

Le tableau suivant montre les attributs constitués par les méthodes de BaseModule class -

Les attributs Définition
data_names Il se compose de la liste des noms des données requises par ce module.
data_shapes Il se compose de la liste des paires (nom, forme) spécifiant les entrées de données dans ce module.
label_shapes Il montre la liste des paires (nom, forme) spécifiant les entrées d'étiquette de ce module.
noms_sortie Il se compose de la liste des noms des sorties de ce module.
output_shapes Il se compose de la liste des paires (nom, forme) spécifiant les sorties de ce module.
symbole Comme son nom est spécifié, cet attribut obtient le symbole associé à ce module.

data_shapes - Vous pouvez consulter le lien à https://mxnet.apache.org/api/python/docs pour plus d'informations.

output_shapes− Vous pouvez consulter le lien à https://mxnet.apache.org/api/python/docs pour plus d'informations.

Module (symbole [, data_names, label_names,…])

Il représente un module de base qui encapsule un symbol.

Méthodes

Le tableau suivant montre les méthodes consistant en Module class -

Méthodes Définition
en arrière ([out_grads]) Comme son nom l'indique, cette méthode implémente le backward calcul.
bind (data_shapes [, label_shapes,…]) Il lie les symboles pour construire des exécuteurs et c'est nécessaire avant de pouvoir effectuer le calcul avec le module.
emprunt_optimiseur (module_partagé) Comme son nom l'indique, cette méthode empruntera l'optimiseur à un module partagé.
forward (data_batch [, is_train]) Comme son nom l'indique, cette méthode implémente le Forwardcalcul. Cette méthode prend en charge les lots de données avec différentes formes telles que différentes tailles de lots ou différentes tailles d'image.
get_input_grads ([merge_multi_context]) Cette méthode obtiendra les gradients vers les entrées qui sont calculées dans le calcul inverse précédent.
get_outputs ([merge_multi_context]) Comme son nom l'indique, cette méthode obtiendra les sorties du calcul direct précédent.
get_params () Il obtient les paramètres en particulier ceux qui sont potentiellement des copies des paramètres réels utilisés pour faire le calcul sur l'appareil.
get_states ([merge_multi_context]) Cette méthode obtiendra les états de tous les appareils
init_optimizer ([kvstore, optimiseur,…]) Cette méthode installe et initialise les optimiseurs. Il initialise égalementkvstore pour distribuer la formation.
init_params ([initialiseur, arg_params,…]) Comme son nom l'indique, cette méthode initialisera les paramètres et les états auxiliaires.
install_monitor (mon) Cette méthode installera le moniteur sur tous les exécuteurs.
load (préfixe, epoch [, sym_gen,…]) Cette méthode créera un modèle à partir du point de contrôle précédemment enregistré.
load_optimizer_states (fname) Cette méthode chargera un optimiseur, c'est-à-dire l'état du programme de mise à jour à partir d'un fichier.
préparer (data_batch [, sparse_row_id_fn]) L'opérateur prépare le module pour traiter un lot de données donné.
remodeler (formes_données [, formes_étiquette]) Cette méthode, comme son nom l'indique, remodèle le module pour de nouvelles formes d'entrée.
save_checkpoint (préfixe, époque [,…]) Il enregistre la progression actuelle au point de contrôle.
save_optimizer_states (fname) Cette méthode enregistre l'optimiseur ou l'état du programme de mise à jour dans un fichier.
set_params (arg_params, aux_params [,…]) Comme son nom l'indique, cette fonction affectera des paramètres et des valeurs d'état aux.
set_states ([états, valeur]) Cette méthode, comme son nom l'indique, définit la valeur des états.
mettre à jour() Cette méthode met à jour les paramètres donnés en fonction de l'optimiseur installé. Il met également à jour les dégradés calculés dans le précédent lot avant-arrière.
update_metric (eval_metric, labels [, pre_sliced]) Cette méthode, comme son nom l'indique, évalue et accumule la métrique d'évaluation sur les sorties du dernier calcul direct.

Les attributs

Le tableau suivant montre les attributs constitués par les méthodes de Module class -

Les attributs Définition
data_names Il se compose de la liste des noms des données requises par ce module.
data_shapes Il se compose de la liste des paires (nom, forme) spécifiant les entrées de données dans ce module.
label_shapes Il montre la liste des paires (nom, forme) spécifiant les entrées d'étiquette de ce module.
noms_sortie Il se compose de la liste des noms des sorties de ce module.
output_shapes Il se compose de la liste des paires (nom, forme) spécifiant les sorties de ce module.
label_names Il se compose de la liste des noms des étiquettes requises par ce module.

data_shapes: visitez le lien https://mxnet.apache.org/api/python/docs/api/module pour plus de détails.

output_shapes: Le lien donné ci-joint https://mxnet.apache.org/api/python/docs/api/module/index.html offrira d'autres informations importantes.

PythonLossModule ([nom, noms_données,…])

La base de cette classe est mxnet.module.python_module.PythonModule. La classe PythonLossModule est une classe de module pratique qui implémente la totalité ou la plupart des API de module en tant que fonctions vides.

Méthodes

Le tableau suivant montre les méthodes consistant en PythonLossModule classe:

Méthodes Définition
en arrière ([out_grads]) Comme son nom l'indique, cette méthode implémente le backward calcul.
forward (data_batch [, is_train]) Comme son nom l'indique, cette méthode implémente le Forwardcalcul. Cette méthode prend en charge les lots de données avec différentes formes telles que différentes tailles de lots ou différentes tailles d'image.
get_input_grads ([merge_multi_context]) Cette méthode obtiendra les gradients vers les entrées qui sont calculées dans le calcul inverse précédent.
get_outputs ([merge_multi_context]) Comme son nom l'indique, cette méthode obtiendra les sorties du calcul direct précédent.
install_monitor (mon) Cette méthode installera le moniteur sur tous les exécuteurs.

PythonModule ([noms_données, noms_étiquette…])

La base de cette classe est mxnet.module.base_module.BaseModule. La classe PythonModule est également une classe de module pratique qui implémente la totalité ou la plupart des API de module en tant que fonctions vides.

Méthodes

Le tableau suivant montre les méthodes consistant en PythonModule classe -

Méthodes Définition
bind (data_shapes [, label_shapes,…]) Il lie les symboles pour construire des exécuteurs et c'est nécessaire avant de pouvoir effectuer le calcul avec le module.
get_params () Il obtient les paramètres en particulier ceux qui sont potentiellement des copies des paramètres réels utilisés pour faire le calcul sur l'appareil.
init_optimizer ([kvstore, optimiseur,…]) Cette méthode installe et initialise les optimiseurs. Il initialise égalementkvstore pour distribuer la formation.
init_params ([initialiseur, arg_params,…]) Comme son nom l'indique, cette méthode initialisera les paramètres et les états auxiliaires.
mettre à jour() Cette méthode met à jour les paramètres donnés en fonction de l'optimiseur installé. Il met également à jour les dégradés calculés dans le précédent lot avant-arrière.
update_metric (eval_metric, labels [, pre_sliced]) Cette méthode, comme son nom l'indique, évalue et accumule la métrique d'évaluation sur les sorties du dernier calcul direct.

Les attributs

Le tableau suivant montre les attributs constitués par les méthodes de PythonModule classe -

Les attributs Définition
data_names Il se compose de la liste des noms des données requises par ce module.
data_shapes Il se compose de la liste des paires (nom, forme) spécifiant les entrées de données dans ce module.
label_shapes Il montre la liste des paires (nom, forme) spécifiant les entrées d'étiquette de ce module.
noms_sortie Il se compose de la liste des noms des sorties de ce module.
output_shapes Il se compose de la liste des paires (nom, forme) spécifiant les sorties de ce module.

data_shapes - Suivez le lien https://mxnet.apache.org pour plus de détails.

output_shapes - Pour plus de détails, visitez le lien disponible sur https://mxnet.apache.org

SequentialModule ([enregistreur])

La base de cette classe est mxnet.module.base_module.BaseModule. La classe SequentialModule est également un module conteneur qui peut enchaîner plus de deux (plusieurs) modules ensemble.

Méthodes

Le tableau suivant montre les méthodes consistant en SequentialModule classe

Méthodes Définition
ajouter (module, ** kwargs) C'est la fonction la plus importante de cette classe. Il ajoute un module à la chaîne.
en arrière ([out_grads]) Comme son nom l'indique, cette méthode implémente le calcul en arrière.
bind (data_shapes [, label_shapes,…]) Il lie les symboles pour construire des exécuteurs et c'est nécessaire avant de pouvoir effectuer le calcul avec le module.
forward (data_batch [, is_train]) Comme son nom l'indique, cette méthode implémente le calcul Forward. Cette méthode prend en charge les lots de données avec différentes formes telles que différentes tailles de lots ou différentes tailles d'image.
get_input_grads ([merge_multi_context]) Cette méthode obtiendra les gradients vers les entrées qui sont calculées dans le calcul inverse précédent.
get_outputs ([merge_multi_context]) Comme son nom l'indique, cette méthode obtiendra les sorties du calcul direct précédent.
get_params () Il obtient les paramètres en particulier ceux qui sont potentiellement des copies des paramètres réels utilisés pour faire le calcul sur l'appareil.
init_optimizer ([kvstore, optimiseur,…]) Cette méthode installe et initialise les optimiseurs. Il initialise égalementkvstore pour distribuer la formation.
init_params ([initialiseur, arg_params,…]) Comme son nom l'indique, cette méthode initialisera les paramètres et les états auxiliaires.
install_monitor (mon) Cette méthode installera le moniteur sur tous les exécuteurs.
mettre à jour() Cette méthode met à jour les paramètres donnés en fonction de l'optimiseur installé. Il met également à jour les dégradés calculés dans le précédent lot avant-arrière.
update_metric (eval_metric, labels [, pre_sliced]) Cette méthode, comme son nom l'indique, évalue et accumule la métrique d'évaluation sur les sorties du dernier calcul direct.

Les attributs

Le tableau suivant montre les attributs constitués dans les méthodes de la classe BaseModule -

Les attributs Définition
data_names Il se compose de la liste des noms des données requises par ce module.
data_shapes Il se compose de la liste des paires (nom, forme) spécifiant les entrées de données dans ce module.
label_shapes Il montre la liste des paires (nom, forme) spécifiant les entrées d'étiquette de ce module.
noms_sortie Il se compose de la liste des noms des sorties de ce module.
output_shapes Il se compose de la liste des paires (nom, forme) spécifiant les sorties de ce module.
output_shapes Il se compose de la liste des paires (nom, forme) spécifiant les sorties de ce module.

data_shapes - Le lien ci-joint https://mxnet.apache.org vous aidera à comprendre l'attribut en détail.

output_shapes - Suivez le lien disponible sur https://mxnet.apache.org/api pour plus de détails.

Exemples de mise en œuvre

Dans l'exemple ci-dessous, nous allons créer un mxnet module.

import mxnet as mx
input_data = mx.symbol.Variable('input_data')
f_connected1 = mx.symbol.FullyConnected(data, name='f_connected1', num_hidden=128)
activation_1 = mx.symbol.Activation(f_connected1, name='relu1', act_type="relu")
f_connected2 = mx.symbol.FullyConnected(activation_1, name = 'f_connected2', num_hidden = 64)
activation_2 = mx.symbol.Activation(f_connected2, name='relu2',
act_type="relu")
f_connected3 = mx.symbol.FullyConnected(activation_2, name='fc3', num_hidden=10)
out = mx.symbol.SoftmaxOutput(f_connected3, name = 'softmax')
mod = mx.mod.Module(out)
print(out)

Output

La sortie est mentionnée ci-dessous -

<Symbol softmax>

Example

print(mod)

Output

La sortie est indiquée ci-dessous -

<mxnet.module.module.Module object at 0x00000123A9892F28>

Dans cet exemple ci-dessous, nous allons implémenter le calcul direct

import mxnet as mx
from collections import namedtuple
Batch = namedtuple('Batch', ['data'])
data = mx.sym.Variable('data')
out = data * 2
mod = mx.mod.Module(symbol=out, label_names=None)
mod.bind(data_shapes=[('data', (1, 10))])
mod.init_params()
data1 = [mx.nd.ones((1, 10))]
mod.forward(Batch(data1))
print (mod.get_outputs()[0].asnumpy())

Output

Lorsque vous exécutez le code ci-dessus, vous devriez voir la sortie suivante -

[[2. 2. 2. 2. 2. 2. 2. 2. 2. 2.]]

Example

data2 = [mx.nd.ones((3, 5))]

mod.forward(Batch(data2))
print (mod.get_outputs()[0].asnumpy())

Output

Ci-dessous est la sortie du code -

[[2. 2. 2. 2. 2.]
[2. 2. 2. 2. 2.]
[2. 2. 2. 2. 2.]]