Apache MXNet - Guida rapida

Questo capitolo evidenzia le funzionalità di Apache MXNet e parla dell'ultima versione di questo framework software di deep learning.

Cos'è MXNet?

Apache MXNet è un potente strumento framework software di deep learning open source che aiuta gli sviluppatori a creare, addestrare e distribuire modelli di deep learning. Negli ultimi anni, dall'assistenza sanitaria al trasporto alla produzione e, di fatto, in ogni aspetto della nostra vita quotidiana, l'impatto del deep learning è stato diffuso. Al giorno d'oggi, il deep learning è ricercato dalle aziende per risolvere alcuni problemi difficili come il riconoscimento facciale, il rilevamento di oggetti, il riconoscimento ottico dei caratteri (OCR), il riconoscimento vocale e la traduzione automatica.

Questo è il motivo per cui Apache MXNet è supportato da:

  • Alcune grandi aziende come Intel, Baidu, Microsoft, Wolfram Research, ecc.

  • Provider di cloud pubblico tra cui Amazon Web Services (AWS) e Microsoft Azure

  • Alcuni grandi istituti di ricerca come Carnegie Mellon, MIT, University of Washington e Hong Kong University of Science & Technology.

Perché Apache MXNet?

Esistono varie piattaforme di deep learning come Torch7, Caffe, Theano, TensorFlow, Keras, Microsoft Cognitive Toolkit, ecc., Quindi potresti chiederti perché Apache MXNet? Diamo un'occhiata ad alcuni dei motivi alla base:

  • Apache MXNet risolve uno dei maggiori problemi delle piattaforme di deep learning esistenti. Il problema è che per utilizzare le piattaforme di deep learning è necessario apprendere un altro sistema per un diverso sapore di programmazione.

  • Con l'aiuto di Apache MXNet, gli sviluppatori possono sfruttare tutte le capacità delle GPU e del cloud computing.

  • Apache MXNet può accelerare qualsiasi calcolo numerico e pone un'enfasi particolare sull'accelerazione dello sviluppo e della distribuzione di DNN (reti neurali profonde) su larga scala.

  • Fornisce agli utenti le capacità di programmazione sia imperativa che simbolica.

Varie caratteristiche

Se stai cercando una libreria di deep learning flessibile per sviluppare rapidamente ricerche di deep learning all'avanguardia o una piattaforma robusta per spingere il carico di lavoro di produzione, la tua ricerca si conclude con Apache MXNet. È a causa delle seguenti caratteristiche:

Formazione distribuita

Che si tratti di formazione multi-GPU o multi-host con un'efficienza di scalabilità quasi lineare, Apache MXNet consente agli sviluppatori di ottenere il massimo dal proprio hardware. MXNet supporta anche l'integrazione con Horovod, un framework di apprendimento profondo distribuito open source creato su Uber.

Per questa integrazione, di seguito sono riportate alcune delle API distribuite comuni definite in Horovod:

  • horovod.broadcast()

  • horovod.allgather()

  • horovod.allgather()

A questo proposito, MXNet ci offre le seguenti funzionalità:

  • Device Placement - Con l'aiuto di MXNet possiamo facilmente specificare ogni struttura dati (DS).

  • Automatic Differentiation - Apache MXNet automatizza la differenziazione, ovvero i calcoli derivati.

  • Multi-GPU training - MXNet ci consente di raggiungere l'efficienza di scalabilità con il numero di GPU disponibili.

  • Optimized Predefined Layers - Possiamo codificare i nostri livelli in MXNet e anche i livelli predefiniti ottimizzati per la velocità.

Ibridazione

Apache MXNet fornisce ai suoi utenti un front-end ibrido. Con l'aiuto dell'API Gluon Python può colmare il divario tra le sue capacità imperative e simboliche. Può essere fatto chiamando la sua funzionalità di ibridazione.

Calcolo più veloce

Le operazioni lineari come decine o centinaia di moltiplicazioni di matrici sono il collo di bottiglia computazionale per le reti neurali profonde. Per risolvere questo collo di bottiglia MXNet fornisce:

  • Calcolo numerico ottimizzato per GPU

  • Calcolo numerico ottimizzato per ecosistemi distribuiti

  • Automazione di flussi di lavoro comuni con l'aiuto del quale è possibile esprimere brevemente lo standard NN.

Associazioni linguistiche

MXNet ha una profonda integrazione in linguaggi di alto livello come Python e R. Fornisce anche supporto per altri linguaggi di programmazione come-

  • Scala

  • Julia

  • Clojure

  • Java

  • C/C++

  • Perl

Non abbiamo bisogno di imparare alcun nuovo linguaggio di programmazione, invece MXNet, combinato con la funzionalità di ibridazione, consente una transizione eccezionalmente fluida da Python alla distribuzione nel linguaggio di programmazione di nostra scelta.

Ultima versione MXNet 1.6.0

Apache Software Foundation (ASF) ha rilasciato la versione stabile 1.6.0 di Apache MXNet il 21 febbraio 2020 con licenza Apache 2.0. Questa è l'ultima versione di MXNet a supportare Python 2 poiché la comunità MXNet ha votato per non supportare più Python 2 in ulteriori versioni. Diamo un'occhiata ad alcune delle nuove funzionalità che questa versione offre ai suoi utenti.

Interfaccia compatibile con NumPy

Grazie alla sua flessibilità e generalità, NumPy è stato ampiamente utilizzato da professionisti, scienziati e studenti di Machine Learning. Ma come sappiamo, gli acceleratori hardware di questi giorni come le unità di elaborazione grafica (GPU) sono diventati sempre più assimilati in vari toolkit di Machine Learning (ML), gli utenti di NumPy, per sfruttare la velocità delle GPU, devono passare a nuovi framework con sintassi diversa.

Con MXNet 1.6.0, Apache MXNet si sta muovendo verso un'esperienza di programmazione compatibile con NumPy. La nuova interfaccia fornisce un'usabilità e un'espressività equivalenti a coloro che hanno familiarità con la sintassi di NumPy. Insieme a questo MXNet 1.6.0 consente anche al sistema Numpy esistente di utilizzare acceleratori hardware come le GPU per accelerare i calcoli su larga scala.

Integrazione con Apache TVM

Apache TVM, uno stack di compilatore di deep learning end-to-end open source per backend hardware come CPU, GPU e acceleratori specializzati, mira a colmare il divario tra i framework di deep learning incentrati sulla produttività e i backend hardware orientati alle prestazioni . Con l'ultima versione MXNet 1.6.0, gli utenti possono sfruttare Apache (incubazione) TVM per implementare kernel operatore ad alte prestazioni nel linguaggio di programmazione Python. I due principali vantaggi di questa nuova funzionalità sono i seguenti:

  • Semplifica il precedente processo di sviluppo basato su C ++.

  • Consente la condivisione della stessa implementazione su più back-end hardware come CPU, GPU, ecc.

Miglioramenti alle funzionalità esistenti

Oltre alle funzionalità sopra elencate di MXNet 1.6.0, fornisce anche alcuni miglioramenti rispetto alle funzionalità esistenti. I miglioramenti sono i seguenti:

Raggruppamento dell'operazione in base agli elementi per GPU

Come sappiamo, le prestazioni delle operazioni basate sugli elementi dipendono dalla larghezza di banda della memoria e questo è il motivo, concatenare tali operazioni può ridurre le prestazioni complessive. Apache MXNet 1.6.0 esegue la fusione di operazioni in termini di elementi, che in realtà genera operazioni di fusione just-in-time come e quando possibile. Tale fusione operativa basata sugli elementi riduce anche le esigenze di archiviazione e migliora le prestazioni complessive.

Semplificare le espressioni comuni

MXNet 1.6.0 elimina le espressioni ridondanti e semplifica le espressioni comuni. Tale miglioramento migliora anche l'utilizzo della memoria e il tempo di esecuzione totale.

Ottimizzazioni

MXNet 1.6.0 fornisce anche varie ottimizzazioni alle funzionalità e agli operatori esistenti, che sono i seguenti:

  • Precisione mista automatica

  • API Gluon Fit

  • MKL-DNN

  • Grande supporto tensore

  • TensorRT integrazione

  • Supporto gradiente di ordine superiore

  • Operators

  • Profiler delle prestazioni dell'operatore

  • Importazione / esportazione ONNX

  • Miglioramenti alle API Gluon

  • Miglioramenti alle API dei simboli

  • Più di 100 correzioni di bug

Per iniziare con MXNet, la prima cosa che dobbiamo fare è installarlo sul nostro computer. Apache MXNet funziona praticamente su tutte le piattaforme disponibili, inclusi Windows, Mac e Linux.

Sistema operativo Linux

Possiamo installare MXNet su sistema operativo Linux nei seguenti modi:

Unità di elaborazione grafica (GPU)

Qui, utilizzeremo vari metodi, ovvero Pip, Docker e Source per installare MXNet quando utilizziamo la GPU per l'elaborazione -

Utilizzando il metodo Pip

Puoi utilizzare il seguente comando per installare MXNet sul tuo sistema operativo Linus:

pip install mxnet

Apache MXNet offre anche pacchetti pip MKL, che sono molto più veloci se eseguiti su hardware Intel. Qui per esempiomxnet-cu101mkl significa che -

  • Il pacchetto è costruito con CUDA / cuDNN

  • Il pacchetto è abilitato per MKL-DNN

  • La versione CUDA è la 10.1

Per altre opzioni puoi anche fare riferimento https://pypi.org/project/mxnet/.

Utilizzando Docker

Puoi trovare le immagini docker con MXNet su DockerHub, disponibile all'indirizzo https://hub.docker.com/u/mxnet Esaminiamo i passaggi seguenti per installare MXNet utilizzando Docker con GPU -

Step 1- Innanzitutto, seguendo le istruzioni di installazione del docker disponibili su https://docs.docker.com/engine/install/ubuntu/. Dobbiamo installare Docker sulla nostra macchina.

Step 2- Per abilitare l'utilizzo delle GPU dai container docker, successivamente dobbiamo installare nvidia-docker-plugin. È possibile seguire le istruzioni di installazione fornite suhttps://github.com/NVIDIA/nvidia-docker/wiki.

Step 3- Utilizzando il seguente comando, puoi estrarre l'immagine docker di MXNet -

$ sudo docker pull mxnet/python:gpu

Ora per vedere se il pull dell'immagine docker mxnet / python ha avuto successo, possiamo elencare le immagini docker come segue:

$ sudo docker images

Per le velocità di inferenza più elevate con MXNet, si consiglia di utilizzare l'ultima MXNet con Intel MKL-DNN. Controlla i comandi seguenti:

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

Dalla fonte

Per creare la libreria condivisa MXNet dall'origine con GPU, prima dobbiamo configurare l'ambiente per CUDA e cuDNN come segue:

  • Scarica e installa il toolkit CUDA, qui si consiglia CUDA 9.2.

  • Quindi scarica cuDNN 7.1.4.

  • Ora dobbiamo decomprimere il file. È inoltre necessario passare alla directory principale cuDNN. Spostare anche l'intestazione e le librerie nella cartella CUDA Toolkit locale come segue:

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

Dopo aver configurato l'ambiente per CUDA e cuDNN, segui i passaggi seguenti per creare la libreria condivisa MXNet dall'origine:

Step 1- Per prima cosa, dobbiamo installare i pacchetti prerequisiti. Queste dipendenze sono richieste su Ubuntu versione 16.04 o successiva.

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

Step 2- In questo passaggio, scaricheremo il sorgente MXNet e lo configureremo. Per prima cosa cloniamo il repository usando il seguente comando-

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

Step 3- Utilizzando i seguenti comandi, puoi creare la libreria condivisa principale di MXNet

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

Two important points regarding the above step is as follows−

Se vuoi creare la versione di debug, specifica quanto segue -

cmake -DCMAKE_BUILD_TYPE=Debug -GNinja ..

Per impostare il numero di lavori di compilazione parallela, specificare quanto segue:

cmake --build . --parallel N

Dopo aver creato con successo la libreria condivisa principale di MXNet, in build cartella nel tuo MXNet project root, troverai libmxnet.so che è richiesto per installare i collegamenti della lingua (opzionale).

Unità di elaborazione centrale (CPU)

Qui, utilizzeremo vari metodi, ovvero Pip, Docker e Source per installare MXNet quando utilizziamo la CPU per l'elaborazione -

Utilizzando il metodo Pip

Puoi usare il seguente comando per installare MXNet sul tuo sistema operativo Linus -

pip install mxnet

Apache MXNet offre anche pacchetti pip abilitati per MKL-DNN che sono molto più veloci quando vengono eseguiti su hardware Intel.

pip install mxnet-mkl

Utilizzando Docker

Puoi trovare le immagini docker con MXNet su DockerHub, disponibile all'indirizzo https://hub.docker.com/u/mxnet. Esaminiamo i passaggi seguenti per installare MXNet utilizzando Docker con CPU -

Step 1- Innanzitutto, seguendo le istruzioni di installazione del docker disponibili su https://docs.docker.com/engine/install/ubuntu/. Dobbiamo installare Docker sulla nostra macchina.

Step 2- Utilizzando il seguente comando, puoi estrarre l'immagine docker di MXNet:

$ sudo docker pull mxnet/python

Ora, per vedere se il pull dell'immagine docker mxnet / python ha avuto successo, possiamo elencare le immagini docker come segue:

$ sudo docker images

Per le velocità di inferenza più elevate con MXNet, si consiglia di utilizzare l'ultima MXNet con Intel MKL-DNN.

Controlla i comandi seguenti:

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

Dalla fonte

Per creare la libreria condivisa MXNet dall'origine con la CPU, segui i passaggi seguenti:

Step 1- Per prima cosa, dobbiamo installare i pacchetti prerequisiti. Queste dipendenze sono richieste su Ubuntu versione 16.04 o successiva.

sudo apt-get update

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

Step 2- In questo passaggio scaricheremo il sorgente MXNet e lo configureremo. Per prima cosa cloniamo il repository usando il seguente comando:

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

cd mxnet
cp config/linux.cmake config.cmake

Step 3- Utilizzando i seguenti comandi, puoi creare la libreria condivisa principale di MXNet:

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

Two important points regarding the above step is as follows−

Se desideri creare la versione di debug, specifica quanto segue:

cmake -DCMAKE_BUILD_TYPE=Debug -GNinja ..

Per impostare il numero di lavori di compilazione parallela, specificare quanto segue -

cmake --build . --parallel N

Dopo aver creato con successo la libreria condivisa principale di MXNet, in build nella cartella principale del tuo progetto MXNet, troverai libmxnet.so, che è richiesto per installare i collegamenti della lingua (opzionale).

Mac OS

Possiamo installare MXNet su MacOS nei seguenti modi:

Unità di elaborazione grafica (GPU)

Se prevedi di creare MXNet su MacOS con GPU, NON sono disponibili metodi Pip e Docker. L'unico metodo in questo caso è crearlo dal sorgente.

Dalla fonte

Per creare la libreria condivisa MXNet dall'origine con GPU, prima dobbiamo configurare l'ambiente per CUDA e cuDNN. Devi seguire ilNVIDIA CUDA Installation Guide disponibile all'indirizzo https://docs.nvidia.com e cuDNN Installation Guide, disponibile all'indirizzo https://docs.nvidia.com/deeplearning per mac OS.

Tieni presente che nel 2019 CUDA ha smesso di supportare macOS. In effetti, anche le future versioni di CUDA potrebbero non supportare macOS.

Dopo aver configurato l'ambiente per CUDA e cuDNN, segui i passaggi indicati di seguito per installare MXNet dalla sorgente su OS X (Mac) -

Step 1- Poiché abbiamo bisogno di alcune dipendenze su OS x, in primo luogo, dobbiamo installare i pacchetti prerequisiti.

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

Possiamo anche creare MXNet senza OpenCV poiché opencv è una dipendenza opzionale.

Step 2- In questo passaggio scaricheremo il sorgente MXNet e lo configureremo. Per prima cosa cloniamo il repository usando il seguente comando-

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

cd mxnet
cp config/linux.cmake config.cmake

Per una GPU abilitata, è necessario installare prima le dipendenze CUDA perché quando si tenta di creare una build abilitata per GPU su una macchina senza GPU, la build MXNet non può rilevare automaticamente l'architettura della GPU. In questi casi MXNet prenderà di mira tutte le architetture GPU disponibili.

Step 3- Utilizzando i seguenti comandi, puoi creare la libreria condivisa principale di MXNet

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

Due punti importanti riguardo al passaggio precedente sono i seguenti:

Se vuoi creare la versione di debug, specifica quanto segue -

cmake -DCMAKE_BUILD_TYPE=Debug -GNinja ..

Per impostare il numero di lavori di compilazione parallela, specificare quanto segue:

cmake --build . --parallel N

Dopo aver creato con successo la libreria condivisa principale di MXNet, in build cartella nel tuo MXNet project root, troverai libmxnet.dylib, che è richiesto per installare i collegamenti della lingua (opzionale).

Unità di elaborazione centrale (CPU)

Qui, useremo vari metodi, ovvero Pip, Docker e Source per installare MXNet quando usiamo la CPU per l'elaborazione

Utilizzando il metodo Pip

Puoi usare il seguente comando per installare MXNet sul tuo sistema operativo Linus

pip install mxnet

Utilizzando Docker

Puoi trovare le immagini docker con MXNet su DockerHub, disponibile all'indirizzo https://hub.docker.com/u/mxnet. Esaminiamo i passaggi seguenti per installare MXNet utilizzando Docker con CPU−

Step 1- In primo luogo, seguendo il docker installation instructions disponibili su https://docs.docker.com/docker-for-mac dobbiamo installare Docker sulla nostra macchina.

Step 2- Usando il seguente comando, puoi estrarre l'immagine docker di MXNet -

$ docker pull mxnet/python

Ora per vedere se il pull dell'immagine docker mxnet / python ha avuto successo, possiamo elencare le immagini docker come segue:

$ docker images

Per le velocità di inferenza più elevate con MXNet, si consiglia di utilizzare l'ultima MXNet con Intel MKL-DNN. Controlla i comandi sottostanti -

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

Dalla fonte

Segui i passaggi indicati di seguito per installare MXNet dalla sorgente su OS X (Mac) -

Step 1- Poiché abbiamo bisogno di alcune dipendenze da OS x, prima dobbiamo installare i pacchetti prerequisiti.

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

Possiamo anche creare MXNet senza OpenCV poiché opencv è una dipendenza opzionale.

Step 2- In questo passaggio scaricheremo il sorgente MXNet e lo configureremo. Per prima cosa, cloniamo il repository usando il seguente comando-

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

cd mxnet

cp config/linux.cmake config.cmake

Step 3- Utilizzando i seguenti comandi, puoi creare la libreria condivisa principale di MXNet:

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

Two important points regarding the above step is as follows−

Se vuoi creare la versione di debug, specifica quanto segue -

cmake -DCMAKE_BUILD_TYPE=Debug -GNinja ..

Per impostare il numero di lavori di compilazione parallela, specificare quanto segue -

cmake --build . --parallel N

Dopo aver creato con successo la libreria condivisa principale di MXNet, in build cartella nel tuo MXNet project root, troverai libmxnet.dylib, che è richiesto per installare i collegamenti della lingua (opzionale).

Sistema operativo Windows

Per installare MXNet su Windows, i seguenti sono i prerequisiti:

requisiti minimi di sistema

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

  • Visual Studio 2015 o 2017 (qualsiasi tipo)

  • Python 2.7 o 3.6

  • pip

Requisiti di sistema raccomandati

  • Windows 10, Server 2012 R2 o Server 2016

  • Visual Studio 2017

  • Almeno una GPU abilitata per NVIDIA CUDA

  • CPU abilitata per MKL: processore Intel® Xeon®, famiglia di processori Intel® Core ™, processore Intel Atom® o processore Intel® Xeon Phi ™

  • Python 2.7 o 3.6

  • pip

Unità di elaborazione grafica (GPU)

Usando il metodo Pip -

Se prevedi di creare MXNet su Windows con GPU NVIDIA, ci sono due opzioni per installare MXNet con supporto CUDA con un pacchetto Python:

Installa con il supporto CUDA

Di seguito sono riportati i passaggi con l'aiuto dei quali possiamo configurare MXNet con CUDA.

Step 1- Prima installa Microsoft Visual Studio 2017 o Microsoft Visual Studio 2015.

Step 2- Quindi, scarica e installa NVIDIA CUDA. Si consiglia di utilizzare le versioni CUDA 9.2 o 9.0 perché in passato sono stati identificati alcuni problemi con CUDA 9.1.

Step 3- Ora scarica e installa NVIDIA_CUDA_DNN.

Step 4- Infine, utilizzando il seguente comando pip, installa MXNet con CUDA-

pip install mxnet-cu92

Installa con CUDA e MKL Support

Di seguito sono riportati i passaggi con l'aiuto dei quali possiamo configurare MXNet con CUDA e MKL.

Step 1- Prima installa Microsoft Visual Studio 2017 o Microsoft Visual Studio 2015.

Step 2- Successivamente, scarica e installa intel MKL

Step 3- Ora scarica e installa NVIDIA CUDA.

Step 4- Ora scarica e installa NVIDIA_CUDA_DNN.

Step 5- Infine, utilizzando il seguente comando pip, installa MXNet con MKL.

pip install mxnet-cu92mkl

Dalla fonte

Per creare la libreria principale MXNet dalla sorgente con GPU, abbiamo le seguenti due opzioni:

Option 1− Build with Microsoft Visual Studio 2017

Per creare e installare MXNet da soli utilizzando Microsoft Visual Studio 2017, sono necessarie le seguenti dipendenze.

Install/update Microsoft Visual Studio.

  • Se Microsoft Visual Studio non è già installato sul tuo computer, devi prima scaricarlo e installarlo.

  • Verrà chiesto di installare Git. Installalo anche.

  • Se Microsoft Visual Studio è già installato sul computer ma si desidera aggiornarlo, procedere al passaggio successivo per modificare l'installazione. Qui ti verrà data l'opportunità di aggiornare anche Microsoft Visual Studio.

Segui le istruzioni per aprire il programma di installazione di Visual Studio disponibile all'indirizzo https://docs.microsoft.com/en-us per modificare i singoli componenti.

Nell'applicazione Visual Studio Installer, aggiorna come richiesto. Dopodiché cerca e controllaVC++ 2017 version 15.4 v14.11 toolset e fare clic Modify.

Ora usando il seguente comando, cambia la versione di Microsoft VS2017 in v14.11-

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

Successivamente, è necessario scaricare e installare CMake disponibile a https://cmake.org/download/ Si consiglia di utilizzare CMake v3.12.2 disponibile all'indirizzo https://cmake.org/download/ perché è testato con MXNet.

Ora scarica ed esegui il file OpenCV pacchetto disponibile su https://sourceforge.net/projects/opencvlibrary/che decomprimerà diversi file. Sta a te decidere se metterli in un'altra directory o meno. Qui useremo il percorsoC:\utils(mkdir C:\utils) come nostro percorso predefinito.

Successivamente, dobbiamo impostare la variabile d'ambiente OpenCV_DIR in modo che punti alla directory di compilazione di OpenCV che abbiamo appena decompresso. Per questo prompt dei comandi aprire e digitareset OpenCV_DIR=C:\utils\opencv\build.

Un punto importante è che se non hai installato Intel MKL (Math Kernel Library) puoi installarlo.

Un altro pacchetto open source che puoi usare è OpenBLAS. Qui per ulteriori istruzioni che supponiamo tu stia utilizzandoOpenBLAS.

Quindi, scarica il file OpenBlas pacchetto disponibile su https://sourceforge.net e decomprimere il file, rinominarlo in OpenBLAS e metterlo sotto C:\utils.

Successivamente, dobbiamo impostare la variabile d'ambiente OpenBLAS_HOME per puntare alla directory OpenBLAS che contiene il file include e libdirectory. Per questo prompt dei comandi aprire e digitareset OpenBLAS_HOME=C:\utils\OpenBLAS.

Ora scarica e installa CUDA disponibile su https://developer.nvidia.com. Nota che, se avevi già CUDA, quindi hai installato Microsoft VS2017, devi reinstallare CUDA ora, in modo da poter ottenere i componenti del toolkit CUDA per l'integrazione di Microsoft VS2017.

Successivamente, è necessario scaricare e installare cuDNN.

Successivamente, devi scaricare e installare git che si trova in https://gitforwindows.org/ anche.

Dopo aver installato tutte le dipendenze richieste, segui i passaggi indicati di seguito per creare il codice sorgente MXNet

Step 1- Apri il prompt dei comandi in Windows.

Step 2- Ora, utilizzando il seguente comando, scarica il codice sorgente MXNet da GitHub:

cd C:\

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

Step 3- Quindi, verifica quanto segue -

DCUDNN_INCLUDE and DCUDNN_LIBRARY le variabili di ambiente puntano al file include cartella e cudnn.lib file della posizione di installazione di CUDA

C:\incubator-mxnet è la posizione del codice sorgente appena clonato nel passaggio precedente.

Step 4- Successivamente, utilizzando il seguente comando, crea una build directory e vai anche alla directory, per esempio -

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

Step 5- Ora, usando cmake, compila il codice sorgente di MXNet come segue -

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- Una volta completato con successo CMake, usa il seguente comando per compilare il codice sorgente MXNet -

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

Option 2: Build with Microsoft Visual Studio 2015

Per creare e installare MXNet da soli utilizzando Microsoft Visual Studio 2015, sono necessarie le seguenti dipendenze.

Installa / aggiorna Microsoft Visual Studio 2015. Il requisito minimo per creare MXnet dall'origine è l'aggiornamento 3 di Microsoft Visual Studio 2015. Puoi utilizzare Tools -> Extensions and Updates... | Product Updates menu per aggiornarlo.

Successivamente, è necessario scaricare e installare CMake disponibile all'indirizzo https://cmake.org/download/. Si consiglia di utilizzareCMake v3.12.2 che è a https://cmake.org/download/, perché è testato con MXNet.

Ora scarica ed esegui il pacchetto OpenCV disponibile su https://excellmedia.dl.sourceforge.netche decomprimerà diversi file. Dipende da te, se vuoi metterli in un'altra directory o meno.

Successivamente, dobbiamo impostare la variabile d'ambiente OpenCV_DIR per indicare il file OpenCVbuild directory che abbiamo appena decompresso. Per questo, apri il prompt dei comandi e digita setOpenCV_DIR=C:\opencv\build\x64\vc14\bin.

Un punto importante è che se non hai installato Intel MKL (Math Kernel Library) puoi installarlo.

Un altro pacchetto open source che puoi usare è OpenBLAS. Qui per ulteriori istruzioni che supponiamo tu stia utilizzandoOpenBLAS.

Quindi, scarica il file OpenBLAS pacchetto disponibile su https://excellmedia.dl.sourceforge.net e decomprimere il file, rinominarlo in OpenBLAS e inserirlo in C: \ utils.

Successivamente, è necessario impostare la variabile di ambiente OpenBLAS_HOME in modo che punti alla directory OpenBLAS che contiene le directory include e lib. Puoi trovare la directory inC:\Program files (x86)\OpenBLAS\

Nota che, se avevi già CUDA, quindi hai installato Microsoft VS2015, devi reinstallare CUDA ora in modo da poter ottenere i componenti del toolkit CUDA per l'integrazione di Microsoft VS2017.

Successivamente, è necessario scaricare e installare cuDNN.

Ora, dobbiamo impostare la variabile di ambiente CUDACXX in modo che punti al file CUDA Compiler(C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v9.1\bin\nvcc.exe per esempio).

Allo stesso modo, dobbiamo anche impostare la variabile d'ambiente CUDNN_ROOT per indicare il file cuDNN directory che contiene il file include, lib e bin directory (C:\Downloads\cudnn-9.1-windows7-x64-v7\cuda per esempio).

Dopo aver installato tutte le dipendenze richieste, segui i passaggi indicati di seguito per creare il codice sorgente MXNet

Step 1- Innanzitutto, scarica il codice sorgente MXNet da GitHub-

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

Step 2- Successivamente, usa CMake per creare un Visual Studio in ./build.

Step 3- Ora, in Visual Studio, dobbiamo aprire il file della soluzione,.slne compilarlo. Questi comandi produrranno una libreria chiamatamxnet.dll nel ./build/Release/ or ./build/Debug cartella

Step 4- Una volta completato con successo CMake, utilizzare il seguente comando per compilare il codice sorgente MXNet

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

Unità di elaborazione centrale (CPU)

Qui, useremo vari metodi, ovvero Pip, Docker e Source per installare MXNet quando usiamo la CPU per l'elaborazione

Utilizzando il metodo Pip

Se prevedi di costruire MXNet su Windows con CPU, ci sono due opzioni per installare MXNet usando un pacchetto Python -

Install with CPUs

Usa il seguente comando per installare MXNet con CPU con Python−

pip install mxnet

Install with Intel CPUs

Come discusso in precedenza, MXNet ha il supporto sperimentale per Intel MKL e MKL-DNN. Usa il seguente comando per installare MXNet con CPU Intel con Python−

pip install mxnet-mkl

Utilizzando Docker

Puoi trovare le immagini della finestra mobile con MXNet su DockerHub, disponibile a https://hub.docker.com/u/mxnet Esaminiamo i passaggi seguenti per installare MXNet utilizzando Docker con CPU-

Step 1- Innanzitutto, seguendo le istruzioni di installazione del docker che possono essere lette su https://docs.docker.com/docker-for-mac/install. Dobbiamo installare Docker sulla nostra macchina.

Step 2- Usando il seguente comando, puoi estrarre l'immagine docker di MXNet -

$ docker pull mxnet/python

Ora per vedere se il pull dell'immagine docker mxnet / python ha avuto successo, possiamo elencare le immagini docker come segue:

$ docker images

Per le velocità di inferenza più elevate con MXNet, si consiglia di utilizzare l'ultima MXNet con Intel MKL-DNN.

Controlla i comandi sottostanti -

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

Installazione di MXNet su cloud e dispositivi

Questa sezione evidenzia come installare Apache MXNet su Cloud e sui dispositivi. Cominciamo imparando come installare MXNet su cloud.

Installazione di MXNet On Cloud

Puoi anche ottenere Apache MXNet su diversi provider cloud con Graphical Processing Unit (GPU)supporto. Altri due tipi di supporto che puoi trovare sono i seguenti:

  • Supporto ibrido GPU / CPU per casi d'uso come inferenza scalabile.
  • Supporto GPU fattoriale con AWS Elastic Inference.

Di seguito sono riportati i provider di cloud che forniscono supporto GPU con diverse macchine virtuali per Apache MXNet−

La console Alibaba

Puoi creare il file NVIDIA GPU Cloud Virtual Machine (VM) disponibile a https://docs.nvidia.com/ngc con la console Alibaba e utilizza Apache MXNet.

Amazon Web Services

Fornisce inoltre supporto GPU e fornisce i seguenti servizi per Apache MXNet−

Amazon SageMaker

Gestisce la formazione e la distribuzione dei modelli Apache MXNet.

AMI AWS Deep Learning

Fornisce un ambiente Conda preinstallato per Python 2 e Python 3 con Apache MXNet, CUDA, cuDNN, MKL-DNN e AWS Elastic Inference.

Formazione dinamica su AWS

Fornisce la formazione per la configurazione EC2 manuale sperimentale e per la configurazione semi-automatica di CloudFormation.

Puoi usare NVIDIA VM disponibile a https://aws.amazon.com con i servizi web di Amazon.

Google Cloud Platform

Google fornisce anche NVIDIA GPU cloud image disponibile all'indirizzo https://console.cloud.google.com per lavorare con Apache MXNet.

Microsoft Azure

Fornisce anche Microsoft Azure Marketplace NVIDIA GPU cloud image disponibile a https://azuremarketplace.microsoft.com per lavorare con Apache MXNet.

Oracle Cloud

Oracle fornisce anche NVIDIA GPU cloud image disponibile a https://docs.cloud.oracle.com per lavorare con Apache MXNet.

Unità di elaborazione centrale (CPU)

Apache MXNet funziona su ogni istanza di sola CPU del provider cloud. Ci sono vari metodi per installare come -

  • Istruzioni per l'installazione di Python pip.

  • Istruzioni Docker.

  • Opzione preinstallata come Amazon Web Services che fornisce AWS Deep Learning AMI (con ambiente Conda preinstallato per Python 2 e Python 3 con MXNet e MKL-DNN).

Installazione di MXNet sui dispositivi

Impariamo come installare MXNet sui dispositivi.

Raspberry Pi

Puoi anche eseguire Apache MXNet su dispositivi Raspberry Pi 3B poiché MXNet supporta anche il sistema operativo Respbian ARM. Per eseguire MXNet senza problemi su Raspberry Pi3, si consiglia di avere un dispositivo con più di 1 GB di RAM e una scheda SD con almeno 4 GB di spazio libero.

Di seguito sono riportati i modi con cui è possibile creare MXNet per Raspberry Pi e installare anche i collegamenti Python per la libreria:

Installazione veloce

La ruota Python preconfigurata può essere utilizzata su un Raspberry Pi 3B con Stretch per una rapida installazione. Uno dei problemi importanti con questo metodo è che dobbiamo installare diverse dipendenze per far funzionare Apache MXNet.

Installazione Docker

È possibile seguire le istruzioni di installazione del docker, disponibili all'indirizzo https://docs.docker.com/engine/install/ubuntu/per installare Docker sulla tua macchina. A questo scopo, possiamo installare e utilizzare anche Community Edition (CE).

Build nativa (dall'origine)

Per installare MXNet dalla sorgente, dobbiamo seguire i seguenti due passaggi:

Passo 1

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

Per creare la libreria condivisa sulla versione Raspberry Wheezy e successive, abbiamo bisogno delle seguenti dipendenze:

  • Git- È necessario estrarre il codice da GitHub.

  • Libblas- È richiesto per le operazioni algebriche lineari.

  • Libopencv- È necessario per le operazioni relative alla visione artificiale. Tuttavia, è facoltativo se desideri salvare la RAM e lo spazio su disco.

  • C++ Compiler- È necessario per compilare e costruire il codice sorgente MXNet. Di seguito sono riportati i compilatori supportati che supportano C ++ 11−

    • G ++ (4.8 o versione successiva)

    • Clang(3.9-6)

Usa i seguenti comandi per installare le dipendenze sopra menzionate -

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

Successivamente, dobbiamo clonare il repository del codice sorgente MXNet. Per questo usa il seguente comando git nella tua home directory -

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

cd incubator-mxnet

Ora, con l'aiuto dei seguenti comandi, crea la libreria condivisa:

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)

Una volta eseguiti i comandi di cui sopra, inizierà il processo di compilazione che richiederà un paio d'ore per terminare. Otterrai un file denominatolibmxnet.so nella directory build.

Passo 2

Install the supported language-specific packages for Apache MXNet

In questo passaggio, installeremo i collegamenti MXNet Pythin. Per fare ciò, dobbiamo eseguire il seguente comando nella directory MXNet -

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

In alternativa, con il seguente comando, puoi anche creare un file whl package installabile con pip-

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

Dispositivi NVIDIA Jetson

Puoi anche eseguire Apache MXNet su dispositivi NVIDIA Jetson, come TX2 o Nanopoiché MXNet supporta anche il sistema operativo basato su Ubuntu Arch64. Per eseguire MXNet senza problemi sui dispositivi NVIDIA Jetson, è necessario che CUDA sia installato sul dispositivo Jetson.

Di seguito sono riportati i modi con cui è possibile creare MXNet per dispositivi NVIDIA Jetson:

  • Utilizzando una ruota pip Jetson MXNet per lo sviluppo di Python

  • Dalla fonte

Ma, prima di costruire MXNet da uno dei modi sopra menzionati, è necessario installare le seguenti dipendenze sui dispositivi Jetson:

Dipendenze Python

Per poter utilizzare l'API Python, abbiamo bisogno delle seguenti dipendenze:

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

Clona il repository del codice sorgente MXNet

Usando il seguente comando git nella tua home directory, clona il repository di codice sorgente MXNet-

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

Imposta le variabili d'ambiente

Aggiungi quanto segue nel tuo file .profile file nella tua directory home -

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

Ora, applica la modifica immediatamente con il seguente comando -

source .profile

Configura CUDA

Prima di configurare CUDA, con nvcc, è necessario verificare quale versione di CUDA è in esecuzione

nvcc --version

Supponiamo, se più di una versione di CUDA è installata sul tuo dispositivo o computer e desideri cambiare versione di CUDA, usa quanto segue e sostituisci il collegamento simbolico alla versione che desideri -

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

Il comando precedente passerà a CUDA 10.0, che è preinstallato sul dispositivo NVIDIA Jetson Nano.

Una volta terminati i prerequisiti sopra menzionati, ora puoi installare MXNet su dispositivi NVIDIA Jetson. Quindi, facci capire i modi con cui puoi installare MXNet-

By using a Jetson MXNet pip wheel for Python development- Se vuoi usare una ruota Python preparata, scarica quanto segue sul tuo Jetson ed eseguilo

  • MXNet 1.4.0 (per Python 3) disponibile su https://docs.docker.com

  • MXNet 1.4.0 (per Python 2) disponibile su https://docs.docker.com

Build nativa (dall'origine)

Per installare MXNet dalla sorgente, dobbiamo seguire i seguenti due passaggi:

Passo 1

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

Per creare la libreria condivisa dal codice sorgente Apache MXNet C ++, puoi utilizzare il metodo Docker o farlo manualmente

Metodo Docker

In questo metodo, devi prima installare Docker ed essere in grado di eseguirlo senza sudo (che è anche spiegato nei passaggi precedenti). Una volta fatto, eseguire quanto segue per eseguire la compilazione incrociata tramite Docker-

$MXNET_HOME/ci/build.py -p jetson

Manuale

In questo metodo, è necessario modificare il file Makefile (con il comando sotto) per installare MXNet con collegamenti CUDA per sfruttare le unità di elaborazione grafica (GPU) sui dispositivi NVIDIA Jetson:

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

Dopo aver modificato il Makefile, è necessario modificare il file config.mk per apportare alcune modifiche aggiuntive per il dispositivo NVIDIA Jetson.

Per questo, aggiorna le seguenti impostazioni -

  • Aggiorna il percorso CUDA: USE_CUDA_PATH = / usr / local / cuda

  • Aggiungi -gencode arch = compute-63, code = sm_62 all'impostazione CUDA_ARCH.

  • Aggiorna le impostazioni NVCC: NVCCFLAGS: = -m64

  • Attiva OpenCV: USE_OPENCV = 1

Ora per assicurarci che MXNet venga compilato con l'accelerazione di bassa precisione a livello hardware di Pascal, dobbiamo modificare il Makefile di Mshadow come segue:

MSHADOW_CFLAGS += -DMSHADOW_USE_PASCAL=1

Infine, con l'aiuto del seguente comando puoi costruire la libreria Apache MXNet completa-

cd $MXNET_HOME make -j $(nproc)

Una volta eseguiti i comandi di cui sopra, inizierà il processo di compilazione che richiederà un paio d'ore per terminare. Otterrai un file denominatolibmxnet.so nel mxnet/lib directory.

Passo 2

Install the Apache MXNet Python Bindings

In questo passaggio, installeremo i collegamenti MXNet Python. Per fare ciò dobbiamo eseguire il seguente comando nella directory MXNet -

cd $MXNET_HOME/python
sudo pip install -e .

Una volta completati i passaggi precedenti, ora sei pronto per eseguire MXNet sui tuoi dispositivi NVIDIA Jetson TX2 o Nano. Può essere verificato con il seguente comando -

import mxnet
mxnet.__version__

Restituirà il numero di versione se tutto funziona correttamente.

Per supportare la ricerca e lo sviluppo di applicazioni di Deep Learning in molti campi, Apache MXNet ci fornisce un ricco ecosistema di toolkit, librerie e molti altri. Cerchiamo di esplorarli -

ToolKits

Di seguito sono riportati alcuni dei toolkit più utilizzati e importanti forniti da MXNet:

GluonCV

Come suggerisce il nome, GluonCV è un toolkit Gluon per la visione artificiale alimentato da MXNet. Fornisce l'implementazione di algoritmi DL (Deep Learning) all'avanguardia nella visione artificiale (CV). Con l'aiuto del toolkit GluonCV, ingegneri, ricercatori e studenti possono convalidare nuove idee e apprendere facilmente il CV.

Di seguito sono riportati alcuni dei file features of GluonCV -

  • Addestra script per riprodurre risultati all'avanguardia riportati nelle ultime ricerche.

  • Più di 170+ modelli pre-addestrati di alta qualità.

  • Adotta un modello di sviluppo flessibile.

  • GluonCV è facile da ottimizzare. Possiamo distribuirlo senza mantenere un framework DL pesante.

  • Fornisce API progettate con cura che riducono notevolmente la complessità dell'implementazione.

  • Supporto comunitario.

  • Implementazioni di facile comprensione.

Di seguito sono riportati i file supported applications di GluonCV toolkit:

  • Classificazione delle immagini

  • Rilevamento di oggetti

  • Segmentazione semantica

  • Segmentazione delle istanze

  • Stima della posa

  • Riconoscimento delle azioni video

Possiamo installare GluonCV usando pip come segue:

pip install --upgrade mxnet gluoncv

GluonNLP

Come suggerisce il nome, GluonNLP è un toolkit Gluon per l'elaborazione del linguaggio naturale (NLP) alimentato da MXNet. Fornisce l'implementazione di modelli DL (Deep Learning) all'avanguardia in PNL.

Con l'aiuto del toolkit GluonNLP, ingegneri, ricercatori e studenti possono creare blocchi per pipeline di dati di testo e modelli. Sulla base di questi modelli, possono prototipare rapidamente le idee di ricerca e il prodotto.

Di seguito sono riportate alcune delle caratteristiche di GluonNLP:

  • Addestra script per riprodurre risultati all'avanguardia riportati nelle ultime ricerche.

  • Set di modelli pre-addestrati per attività comuni di PNL.

  • Fornisce API progettate con cura che riducono notevolmente la complessità dell'implementazione.

  • Supporto comunitario.

  • Fornisce inoltre tutorial per aiutarti a iniziare a svolgere nuove attività di PNL.

Di seguito sono riportate le attività di PNL che possiamo implementare con il toolkit GluonNLP:

  • Incorporamento di parole

  • Modello linguistico

  • Traduzione automatica

  • Classificazione del testo

  • Sentiment Analysis

  • Inferenza del linguaggio naturale

  • Generazione di testo

  • Analisi delle dipendenze

  • Riconoscimento di entità nominate

  • Classificazione degli intenti ed etichettatura degli slot

Possiamo installare GluonNLP usando pip come segue:

pip install --upgrade mxnet gluonnlp

GluonTS

Come suggerisce il nome, GluonTS è un toolkit Gluon per la modellazione di serie temporali probabilistiche alimentato da MXNet.

Fornisce le seguenti funzionalità:

  • Modelli di deep learning all'avanguardia (SOTA) pronti per essere formati.

  • Le utilità per il caricamento e l'iterazione su set di dati di serie temporali.

  • Blocchi per definire il tuo modello.

Con l'aiuto del toolkit GluonTS, ingegneri, ricercatori e studenti possono addestrare e valutare qualsiasi modello integrato sui propri dati, sperimentare rapidamente diverse soluzioni e trovare una soluzione per le loro attività di serie temporali.

Possono anche utilizzare le astrazioni e gli elementi costitutivi forniti per creare modelli di serie temporali personalizzati e confrontarli rapidamente con algoritmi di base.

Possiamo installare GluonTS usando pip come segue:

pip install gluonts

GluonFR

Come suggerisce il nome, è un toolkit Apache MXNet Gluon per FR (Face Recognition). Fornisce le seguenti funzionalità:

  • Modelli di deep learning all'avanguardia (SOTA) nel riconoscimento facciale.

  • L'implementazione di SoftmaxCrossEntropyLoss, ArcLoss, TripletLoss, RingLoss, CosLoss / AMsoftmax, L2-Softmax, A-Softmax, CenterLoss, ContrastiveLoss e LGM Loss, ecc.

Per installare Gluon Face, abbiamo bisogno di Python 3.5 o successivo. Dobbiamo anche prima installare GluonCV e MXNet come segue:

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

Dopo aver installato le dipendenze, puoi utilizzare il seguente comando per installare GluonFR -

From Source

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

Pip

pip install gluonfr

Ecosistema

Ora esploriamo le ricche librerie, pacchetti e framework di MXNet:

Coach RL

Coach, un framework Python Reinforcement Learning (RL) creato da Intel AI lab. Consente una facile sperimentazione con algoritmi RL all'avanguardia. Coach RL supporta Apache MXNet come back-end e consente una semplice integrazione di un nuovo ambiente da risolvere.

Al fine di estendere e riutilizzare facilmente i componenti esistenti, Coach RL ha disaccoppiato molto bene i componenti di apprendimento di rinforzo di base come algoritmi, ambienti, architetture NN, politiche di esplorazione.

Di seguito sono riportati gli agenti e gli algoritmi supportati per il framework Coach RL:

Agenti per l'ottimizzazione del valore

  • Deep Q Network (DQN)

  • Double Deep Q Network (DDQN)

  • Dueling Q Network

  • Monte Carlo misto (MMC)

  • Persistent Advantage Learning (PAL)

  • Categorico Deep Q Network (C51)

  • Regressione quantile Deep Q Network (QR-DQN)

  • Apprendimento N-Step Q

  • Controllo episodico neurale (NEC)

  • Funzioni di vantaggio normalizzate (NAF)

  • Rainbow

Agenti per l'ottimizzazione delle politiche

  • Gradienti dei criteri (PG)

  • Asynchronous Advantage Actor-Critic (A3C)

  • Gradienti di policy deterministici profondi (DDPG)

  • Ottimizzazione della politica prossimale (PPO)

  • Ottimizzazione della politica prossimale ritagliata (CPPO)

  • Stima del vantaggio generalizzato (GAE)

  • Esempio di attore-critico efficiente con Experience Replay (ACER)

  • Soft Actor-Critic (SAC)

  • Gradiente di policy deterministico profondo con ritardo gemellare (TD3)

Agenti generali

  • Previsione futura diretta (DFP)

Agenti di apprendimento dell'imitazione

  • Clonazione comportamentale (BC)

  • Apprendimento dell'imitazione condizionale

Agenti gerarchici per l'apprendimento per rinforzo

  • Critico dell'attore gerarchico (HAC)

Libreria Deep Graph

Deep Graph Library (DGL), sviluppata dai team NYU e AWS, Shanghai, è un pacchetto Python che fornisce facili implementazioni di Graph Neural Networks (GNNs) su MXNet. Fornisce inoltre una facile implementazione dei GNN oltre ad altre importanti librerie di deep learning esistenti come PyTorch, Gluon, ecc.

Deep Graph Library è un software gratuito. È disponibile su tutte le distribuzioni Linux successive a Ubuntu 16.04, macOS X e Windows 7 o versioni successive. Richiede anche la versione Python 3.5 o successiva.

Di seguito sono riportate le caratteristiche di DGL:

No Migration cost - Non ci sono costi di migrazione per l'utilizzo di DGL in quanto si basa sui framework DL esistenti in uscita.

Message Passing- DGL fornisce il passaggio di messaggi e ha un controllo versatile su di esso. Il passaggio dei messaggi varia dalle operazioni di basso livello come l'invio lungo i bordi selezionati al controllo di alto livello come gli aggiornamenti delle funzionalità a livello di grafico.

Smooth Learning Curve - È abbastanza facile da imparare e utilizzare DGL poiché le potenti funzioni definite dall'utente sono flessibili e facili da usare.

Transparent Speed Optimization - DGL fornisce un'ottimizzazione trasparente della velocità eseguendo batch automatici di calcoli e moltiplicazione di matrici sparse.

High performance - Per ottenere la massima efficienza, DGL raggruppa automaticamente l'addestramento DNN (reti neurali profonde) su uno o più grafici insieme.

Easy & friendly interface - DGL ci fornisce interfacce facili e intuitive per l'accesso alle caratteristiche del bordo e per la manipolazione della struttura del grafico.

InsightFace

InsightFace, un kit di strumenti di apprendimento profondo per l'analisi del viso che fornisce l'implementazione dell'algoritmo di analisi del viso SOTA (stato dell'arte) nella visione artificiale basata su MXNet. Fornisce -

  • Ampio set di modelli pre-addestrati di alta qualità.

  • Script di formazione all'avanguardia (SOTA).

  • InsightFace è facile da ottimizzare. Possiamo distribuirlo senza mantenere un framework DL pesante.

  • Fornisce API progettate con cura che riducono notevolmente la complessità dell'implementazione.

  • Blocchi per definire il tuo modello.

Possiamo installare InsightFace usando pip come segue:

pip install --upgrade insightface

Tieni presente che prima di installare InsightFace, installa il pacchetto MXNet corretto in base alla configurazione del tuo sistema.

Keras-MXNet

Poiché sappiamo che Keras è un'API di rete neurale (NN) di alto livello scritta in Python, Keras-MXNet ci fornisce un supporto di backend per Keras. Può essere eseguito su un framework Apache MXNet DL scalabile e ad alte prestazioni.

Le caratteristiche di Keras-MXNet sono menzionate di seguito:

  • Consente agli utenti una prototipazione facile, fluida e veloce. Tutto avviene attraverso facilità d'uso, modularità ed estensibilità.

  • Supporta sia CNN (Convolutional Neural Networks) che RNN (Recurrent Neural Networks) e anche la combinazione di entrambi.

  • Funziona perfettamente sia su Central Processing Unit (CPU) che su Graphical Processing Unit (GPU).

  • Può funzionare su una o più GPU.

Per lavorare con questo backend, devi prima installare keras-mxnet come segue:

pip install keras-mxnet

Ora, se stai utilizzando GPU, installa MXNet con il supporto CUDA 9 come segue:

pip install mxnet-cu90

Ma se stai usando solo CPU, installa MXNet di base come segue:

pip install mxnet

MXBoard

MXBoard è uno strumento di registrazione, scritto in Python, utilizzato per registrare i frame di dati MXNet e visualizzarli in TensorBoard. In altre parole, MXBoard è pensato per seguire l'API tensorboard-pytorch. Supporta la maggior parte dei tipi di dati in TensorBoard.

Alcuni di loro sono menzionati di seguito:

  • Graph

  • Scalar

  • Histogram

  • Embedding

  • Image

  • Text

  • Audio

  • Curva di richiamo di precisione

MXFusion

MXFusion è una libreria di programmazione probabilistica modulare con deep learning. MXFusion ci consente di sfruttare appieno la modularità, che è una caratteristica fondamentale delle librerie di deep learning, per la programmazione probabilistica. È semplice da usare e fornisce agli utenti una comoda interfaccia per progettare modelli probabilistici e applicarli ai problemi del mondo reale.

MXFusion è verificato su Python versione 3.4 e più su MacOS e Linux OS. Per installare MXFusion, dobbiamo prima installare le seguenti dipendenze:

  • MXNet> = 1.3

  • Networkx> = 2.1

Con l'aiuto del seguente comando pip, puoi installare MXFusion -

pip install mxfusion

TVM

Apache TVM, uno stack di compilatore di deep learning end-to-end open source per backend hardware come CPU, GPU e acceleratori specializzati, mira a colmare il divario tra i framework di deep learning incentrati sulla produttività e i backend hardware orientati alle prestazioni . Con l'ultima versione MXNet 1.6.0, gli utenti possono sfruttare Apache (incubazione) TVM per implementare kernel operatore ad alte prestazioni nel linguaggio di programmazione Python.

Apache TVM in realtà è iniziato come progetto di ricerca presso il gruppo SAMPL della Paul G. Allen School of Computer Science & Engineering, Università di Washington e ora è uno sforzo in fase di incubazione presso The Apache Software Foundation (ASF) che è guidato da un OSC comunità open source) che coinvolge più industrie e istituzioni accademiche secondo il metodo Apache.

Di seguito sono riportate le caratteristiche principali di Apache (incubazione) TVM:

  • Semplifica il precedente processo di sviluppo basato su C ++.

  • Consente la condivisione della stessa implementazione su più backend hardware come CPU, GPU, ecc.

  • TVM fornisce la compilazione di modelli DL in vari framework come Kears, MXNet, PyTorch, Tensorflow, CoreML, DarkNet in moduli minimi distribuibili su diversi backend hardware.

  • Ci fornisce inoltre l'infrastruttura per generare e ottimizzare automaticamente gli operatori tensoriali con prestazioni migliori.

XFer

Xfer, un framework per l'apprendimento del trasferimento, è scritto in Python. Fondamentalmente prende un modello MXNet e addestra un meta-modello o modifica il modello anche per un nuovo set di dati di destinazione.

In parole semplici, Xfer è una libreria Python che consente agli utenti di trasferire rapidamente e facilmente la conoscenza memorizzata in DNN (reti neurali profonde).

Xfer può essere utilizzato -

  • Per la classificazione dei dati di formato numerico arbitrario.

  • Ai casi comuni di immagini o dati di testo.

  • Come una pipeline che invia spam dall'estrazione di funzionalità all'addestramento di un repurposer (un oggetto che esegue la classificazione nell'attività di destinazione).

Di seguito sono riportate le caratteristiche di Xfer:

  • L'efficienza delle risorse

  • Efficienza dei dati

  • Facile accesso alle reti neurali

  • Modellazione dell'incertezza

  • Prototipazione rapida

  • Utilità per l'estrazione delle caratteristiche da NN

Questo capitolo ti aiuterà a comprendere l'architettura del sistema MXNet. Cominciamo imparando a conoscere i moduli MXNet.

Moduli MXNet

Lo schema seguente è l'architettura del sistema MXNet e mostra i principali moduli e componenti di MXNet modules and their interaction.

Nel diagramma sopra -

  • I moduli nelle caselle di colore blu sono User Facing Modules.

  • I moduli nelle caselle di colore verde sono System Modules.

  • La freccia piena rappresenta un'elevata dipendenza, ovvero dipende fortemente dall'interfaccia.

  • La freccia tratteggiata rappresenta la dipendenza leggera, ovvero la struttura dei dati utilizzata per comodità e coerenza dell'interfaccia. In effetti, può essere sostituito dalle alternative.

Parliamo di più sugli utenti e sui moduli di sistema.

Moduli rivolti all'utente

I moduli rivolti all'utente sono i seguenti:

  • NDArray- Fornisce programmi imperativi flessibili per Apache MXNet. Sono array n-dimensionali dinamici e asincroni.

  • KVStore- Funge da interfaccia per un'efficiente sincronizzazione dei parametri. In KVStore, KV sta per valore-chiave. Quindi, è un'interfaccia di archivio di valori-chiave.

  • Data Loading (IO) - Questo modulo rivolto all'utente viene utilizzato per il caricamento e l'aumento dei dati distribuiti efficienti.

  • Symbol Execution- È un esecutore di grafici simbolici statici. Fornisce un'efficiente esecuzione e ottimizzazione dei grafici simbolici.

  • Symbol Construction - Questo modulo rivolto all'utente fornisce all'utente un modo per costruire un grafico di calcolo, ad esempio una configurazione di rete.

Moduli di sistema

I moduli di sistema sono i seguenti:

  • Storage Allocator - Questo modulo di sistema, come suggerisce il nome, alloca e ricicla i blocchi di memoria in modo efficiente sull'host, ad esempio CPU e dispositivi diversi, ad esempio GPU.

  • Runtime Dependency Engine - Pianifica il modulo del motore delle dipendenze di runtime ed esegue le operazioni in base alla loro dipendenza di lettura / scrittura.

  • Resource Manager - Il modulo di sistema Resource Manager (RM) gestisce risorse globali come il generatore di numeri casuali e lo spazio temporale.

  • Operator - Il modulo del sistema operatore è composto da tutti gli operatori che definiscono il calcolo statico in avanti e del gradiente, ovvero la propagazione all'indietro.

Qui, i componenti di sistema in Apache MXNet sono spiegati in dettaglio. Innanzitutto, studieremo il motore di esecuzione in MXNet.

Motore di esecuzione

Il motore di esecuzione di Apache MXNet è molto versatile. Possiamo usarlo per il deep learning e per qualsiasi problema specifico del dominio: eseguire un gruppo di funzioni seguendo le loro dipendenze. È progettato in modo tale che le funzioni con dipendenze siano serializzate mentre le funzioni senza dipendenze possono essere eseguite in parallelo.

Interfaccia principale

L'API fornita di seguito è l'interfaccia principale per il motore di esecuzione di 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 di cui sopra ha quanto segue:

  • exec_fun - L'API dell'interfaccia principale di MXNet ci consente di inviare la funzione denominata exec_fun, insieme alle sue informazioni di contesto e dipendenze, al motore di esecuzione.

  • exec_ctx - Le informazioni di contesto in cui deve essere eseguita la funzione di cui sopra exec_fun.

  • const_vars - Queste sono le variabili da cui legge la funzione.

  • mutate_vars - Queste sono le variabili che devono essere modificate.

Il motore di esecuzione fornisce all'utente la garanzia che l'esecuzione di due funzioni qualsiasi che modificano una variabile comune sia serializzata nel loro ordine push.

Funzione

Di seguito è riportato il tipo di funzione del motore di esecuzione di Apache MXNet:

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

Nella funzione sopra, RunContextcontiene le informazioni di runtime. Le informazioni di runtime dovrebbero essere determinate dal motore di esecuzione. La sintassi diRunContext è il seguente -

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

Di seguito vengono forniti alcuni punti importanti sulle funzioni del motore di esecuzione:

  • Tutte le funzioni vengono eseguite dai thread interni del motore di esecuzione di MXNet.

  • Non è bene spingere il blocco della funzione al motore di esecuzione perché con ciò la funzione occuperà il thread di esecuzione e ridurrà anche il throughput totale.

Per questo MXNet fornisce un'altra funzione asincrona come segue -

using Callback = std::function<void()>;
using AsyncFn = std::function<void(RunContext, Callback)>;
  • In questo AsyncFn possiamo passare la parte pesante dei nostri thread, ma il motore di esecuzione non considera la funzione finita finché non chiamiamo il file callback funzione.

Contesto

In Context, possiamo specificare il contesto della funzione da eseguire all'interno. Questo di solito include quanto segue:

  • Se la funzione deve essere eseguita su una CPU o una GPU.

  • Se specifichiamo GPU nel contesto, quale GPU utilizzare.

  • C'è un'enorme differenza tra Context e RunContext. Il contesto ha il tipo di dispositivo e l'ID del dispositivo, mentre RunContext ha le informazioni che possono essere decise solo durante il runtime.

VarHandle

VarHandle, utilizzato per specificare le dipendenze delle funzioni, è come un token (fornito in particolare dal motore di esecuzione) che possiamo utilizzare per rappresentare le risorse esterne che la funzione può modificare o utilizzare.

Ma sorge la domanda, perché dobbiamo usare VarHandle? È perché il motore Apache MXNet è progettato per essere disaccoppiato da altri moduli MXNet.

Di seguito sono riportati alcuni punti importanti su VarHandle:

  • È leggero, quindi creare, eliminare o copiare una variabile comporta costi operativi ridotti.

  • Dobbiamo specificare le variabili immutabili, ovvero le variabili che verranno utilizzate nel file const_vars.

  • Dobbiamo specificare le variabili mutabili, cioè le variabili che verranno modificate nel file mutate_vars.

  • La regola utilizzata dal motore di esecuzione per risolvere le dipendenze tra le funzioni è che l'esecuzione di due funzioni qualsiasi quando una di esse modifica almeno una variabile comune viene serializzata nel loro ordine push.

  • Per creare una nuova variabile, possiamo usare il NewVar() API.

  • Per eliminare una variabile, possiamo usare il PushDelete API.

Facci capire il suo funzionamento con un semplice esempio:

Supponiamo di avere due funzioni, ovvero F1 e F2, e che entrambe mutino la variabile, ovvero V2. In tal caso, è garantito che F2 venga eseguito dopo F1 se F2 viene premuto dopo F1. D'altra parte, se F1 e F2 utilizzano entrambi V2, il loro effettivo ordine di esecuzione potrebbe essere casuale.

Spingi e aspetta

Push e wait sono due API più utili del motore di esecuzione.

Di seguito sono riportate due importanti caratteristiche di Push API:

  • Tutte le API push sono asincrone, il che significa che la chiamata API ritorna immediatamente indipendentemente dal fatto che la funzione inviata sia terminata o meno.

  • L'API push non è thread-safe, il che significa che solo un thread deve effettuare chiamate API del motore alla volta.

Ora, se parliamo di Wait API, i seguenti punti lo rappresentano:

  • Se un utente desidera attendere il completamento di una funzione specifica, dovrebbe includere una funzione di callback nella chiusura. Una volta inclusa, chiama la funzione alla fine della funzione.

  • D'altra parte, se un utente vuole aspettare che tutte le funzioni che coinvolgono una certa variabile finiscano, dovrebbe usare WaitForVar(var) API.

  • Se qualcuno desidera attendere il completamento di tutte le funzioni inviate, utilizzare il WaitForAll () API.

  • Utilizzato per specificare le dipendenze delle funzioni, è come un token.

Operatori

L'operatore in Apache MXNet è una classe che contiene la logica di calcolo effettiva, nonché informazioni ausiliarie e aiuta il sistema a eseguire l'ottimizzazione.

Interfaccia operatore

Forward è l'interfaccia operatore principale la cui sintassi è la seguente:

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 struttura di OpContext, definito in Forward() è come segue:

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

Il OpContextdescrive lo stato dell'operatore (sia in fase di treno che di test), su quale dispositivo deve essere eseguito l'operatore e anche le risorse richieste. altre due utili API del motore di esecuzione.

Dall'alto Forward interfaccia principale, possiamo comprendere le risorse richieste come segue:

  • in_data e out_data rappresentano i tensori di input e output.

  • req denota come vengono scritti i risultati del calcolo nel file out_data.

Il OpReqType può essere definito come -

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

Come Forward , possiamo opzionalmente implementare l'operatore Backward interfaccia come segue -

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);

Vari compiti

Operator l'interfaccia consente agli utenti di eseguire le seguenti attività:

  • L'utente può specificare aggiornamenti sul posto e ridurre i costi di allocazione della memoria

  • Per renderlo più pulito, l'utente può nascondere alcuni argomenti interni a Python.

  • L'utente può definire la relazione tra i tensori e i tensori di uscita.

  • Per eseguire il calcolo, l'utente può acquisire ulteriore spazio temporaneo dal sistema.

Proprietà operatore

Poiché sappiamo che nella rete neurale convoluzionale (CNN), una convoluzione ha diverse implementazioni. Per ottenere le migliori prestazioni da loro, potremmo voler passare tra quelle diverse convoluzioni.

Questo è il motivo per cui Apache MXNet separa l'interfaccia semantica dell'operatore dall'interfaccia di implementazione. Questa separazione avviene sotto forma diOperatorProperty classe che consiste di quanto segue -

InferShape - L'interfaccia InferShape ha due scopi come indicato di seguito:

  • Il primo scopo è indicare al sistema la dimensione di ogni tensore di input e output in modo che lo spazio possa essere allocato prima Forward e Backward chiamata.

  • Il secondo scopo è eseguire un controllo delle dimensioni per assicurarsi che non ci siano errori prima di eseguire.

La sintassi è data di seguito:

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

Request Resource- E se il tuo sistema fosse in grado di gestire l'area di lavoro di calcolo per operazioni come cudnnConvolutionForward? Il tuo sistema può eseguire ottimizzazioni come il riutilizzo dello spazio e molte altre. Qui, MXNet raggiunge facilmente questo obiettivo con l'aiuto delle seguenti due interfacce:

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

Ma cosa succede se il file ForwardResource e BackwardResourcerestituire array non vuoti? In tal caso, il sistema offre le risorse corrispondenti tramitectx parametro in Forward e Backward interfaccia di Operator.

Backward dependency - Apache MXNet ha le seguenti due diverse firme di operatore per gestire la dipendenza all'indietro -

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);

Qui, i due punti importanti da notare:

  • Out_data in FullyConnectedForward non viene utilizzato da FullyConnectedBackward e

  • PoolingBackward richiede tutti gli argomenti di PoolingForward.

Ecco perché per FullyConnectedForward, il out_datatensore una volta consumato potrebbe essere liberato in modo sicuro perché la funzione di ritorno non ne avrà bisogno. Con l'aiuto di questo sistema è riuscito a raccogliere alcuni tensori come spazzatura il prima possibile.

In place Option- Apache MXNet fornisce un'altra interfaccia agli utenti per risparmiare il costo dell'allocazione della memoria. L'interfaccia è appropriata per le operazioni per elemento in cui sia i tensori di input che quelli di output hanno la stessa forma.

Di seguito è riportata la sintassi per specificare l'aggiornamento sul posto:

Esempio per la creazione di un operatore

Con l'aiuto di OperatorProperty possiamo creare un operatore. A tale scopo, seguire i passaggi indicati di seguito:

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]} }
}

Passo 1

Create Operator

Per prima cosa implementare la seguente interfaccia in OperatorProperty:

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

L'esempio è fornito di seguito:

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

Passo 2

Parameterize Operator

Se si intende implementare un operatore di convoluzione, è obbligatorio conoscere la dimensione del kernel, la dimensione del passo, la dimensione del padding e così via. Perché, perché questi parametri dovrebbero essere passati all'operatore prima di chiamare qualsiasiForward o backward interfaccia.

Per questo, dobbiamo definire un file ConvolutionParam struttura come sotto -

#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;
};

Ora, dobbiamo inserire questo ConvolutionOpProperty e passarlo all'operatore come segue:

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_;
};

Passaggio 3

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

Infine, dobbiamo registrare la classe della proprietà dell'operatore e la classe del parametro su MXNet. Può essere fatto con l'aiuto delle seguenti macro:

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

Nella macro precedente, il primo argomento è la stringa del nome e il secondo è il nome della classe di proprietà.

Questo capitolo fornisce informazioni sull'API (Unified Operator Application Programming Interface) in Apache MXNet.

SimpleOp

SimpleOp è una nuova API operatore unificata che unifica diversi processi di chiamata. Una volta richiamato, ritorna agli elementi fondamentali degli operatori. L'operatore unificato è progettato appositamente per operazioni unarie e binarie. È perché la maggior parte degli operatori matematici si occupa di uno o due operandi e più operandi rendono utile l'ottimizzazione relativa alla dipendenza.

Comprenderemo il suo operatore unificato SimpleOp lavorando con l'aiuto di un esempio. In questo esempio, creeremo un operatore che funziona come filesmooth l1 loss, che è una combinazione di perdita l1 e l2. Possiamo definire e scrivere la perdita come indicato di seguito:

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

Qui, nell'esempio sopra,

  • . * sta per moltiplicazione basata sugli elementi

  • f, f’ è la funzione di perdita l1 regolare in cui supponiamo sia mshadow.

Sembra impossibile implementare questa particolare perdita come operatore unario o binario, ma MXNet fornisce ai suoi utenti una differenziazione automatica in esecuzione simbolica che semplifica direttamente la perdita in f ed f '. Ecco perché possiamo certamente implementare questa particolare perdita come operatore unario.

Definizione di forme

Come sappiamo di MXNet mshadow libraryrichiede un'allocazione esplicita della memoria, quindi dobbiamo fornire tutte le forme dei dati prima che avvenga qualsiasi calcolo. Prima di definire le funzioni e il gradiente, è necessario fornire la coerenza della forma di input e la forma di output come segue:

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 funzione mxnet :: Tshape viene utilizzata per controllare la forma dei dati di input e la forma dei dati di output designata. Nel caso in cui, se non si definisce questa funzione, la forma di output predefinita sarebbe la stessa della forma di input. Ad esempio, in caso di operatore binario, la forma di lhs e rhs è selezionata per impostazione predefinita come la stessa.

Ora passiamo al nostro smooth l1 loss example. Per questo, abbiamo bisogno di definire un XPU su cpu o gpu nell'implementazione dell'intestazione smooth_l1_unary-inl.h. Il motivo è riutilizzare lo stesso codice in smooth_l1_unary.cc e smooth_l1_unary.cu.

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

Come nel nostro smooth l1 loss example,l'uscita ha la stessa forma della sorgente, possiamo usare il comportamento predefinito. Può essere scritto come segue:

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

Definizione di funzioni

Possiamo creare una funzione unaria o binaria con un input come segue:

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);

Di seguito è riportato il file RunContext ctx struct che contiene le informazioni necessarie durante il runtime per l'esecuzione -

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

Vediamo ora come scrivere i risultati del calcolo 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
};

Ora passiamo al nostro smooth l1 loss example. Per questo, useremo UnaryFunction per definire la funzione di questo operatore come segue:

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)));
   });
}

Definizione dei gradienti

Tranne Input, TBlob, e OpReqTypesono raddoppiati, le funzioni Gradients degli operatori binari hanno una struttura simile. Diamo un'occhiata di seguito, dove abbiamo creato una funzione gradiente con vari tipi di input:

// 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);

Come definito sopra Input0, Input, OutputValue, e OutputGrad tutti condividono la struttura di GradientFunctionArgument. È definito come segue:

struct GradFunctionArgument {
   TBlob data;
}

Ora passiamo al nostro smooth l1 loss example. Per questo, per abilitare la regola della catena del gradiente, dobbiamo moltiplicareout_grad dall'alto al risultato di 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)));
   });
}

Registra SimpleOp su MXNet

Dopo aver creato la forma, la funzione e il gradiente, dobbiamo ripristinarli sia in un operatore NDArray che in un operatore simbolico. Per questo, possiamo utilizzare la macro di registrazione come segue:

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");

Il SimpleOpInplaceOption può essere definito come segue -

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)
};

Ora passiamo al nostro smooth l1 loss example. Per questo, abbiamo una funzione gradiente che si basa sui dati di input in modo che la funzione non possa essere scritta sul posto.

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 su EnvArguments

Come sappiamo, alcune operazioni potrebbero richiedere quanto segue:

  • Uno scalare come input come una scala gradiente

  • Un insieme di argomenti di parole chiave che controllano il comportamento

  • Uno spazio temporaneo per velocizzare i calcoli.

Il vantaggio dell'utilizzo di EnvArguments è che fornisce argomenti e risorse aggiuntivi per rendere i calcoli più scalabili ed efficienti.

Esempio

Per prima cosa definiamo la struttura come di seguito -

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
};

Successivamente, dobbiamo richiedere risorse aggiuntive come mshadow::Random<xpu> e spazio di memoria temporaneo da EnvArguments.resource. Può essere fatto come segue:

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
};

Ora, la registrazione richiederà la richiesta di risorsa dichiarata da mxnet::ResourceManager. Dopodiché, inserirà le risorse std::vector<Resource> resource in EnvAgruments.

Possiamo accedere alle risorse con l'aiuto del seguente codice:

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

Se vedi nel nostro esempio di perdita l1 liscia, è necessario un input scalare per contrassegnare il punto di svolta di una funzione di perdita. Ecco perché nel processo di registrazione utilizziamoset_enable_scalar(true), e env.scalar nelle dichiarazioni di funzione e gradiente.

Building Tensor Operation

Qui sorge la domanda: perché dobbiamo creare operazioni tensoriali? I motivi sono i seguenti:

  • Il calcolo utilizza la libreria mshadow ea volte non abbiamo funzioni prontamente disponibili.

  • Se un'operazione non viene eseguita in un modo saggio di elementi come softmax loss e gradiente.

Esempio

Qui, stiamo usando l'esempio di perdita l1 regolare sopra. Creeremo due mappatori, vale a dire i casi scalari di perdita l1 liscia e gradiente:

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;
         }
      }
   };
}

Questo capitolo riguarda la formazione distribuita in Apache MXNet. Cominciamo col capire quali sono le modalità di calcolo in MXNet.

Modalità di calcolo

MXNet, una libreria ML multilingue, offre ai suoi utenti le seguenti due modalità di calcolo:

Modalità imperativa

Questa modalità di calcolo espone un'interfaccia come NumPy API. Ad esempio, in MXNet, usa il seguente codice imperativo per costruire un tensore di zeri sia sulla CPU che sulla GPU -

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

Come vediamo nel codice sopra, MXNets specifica la posizione in cui tenere il tensore, nella CPU o nel dispositivo GPU. Nell'esempio sopra, si trova nella posizione 0. MXNet raggiunge un utilizzo incredibile del dispositivo, perché tutti i calcoli avvengono in modo lento invece che istantaneo.

Modalità simbolica

Anche se la modalità imperativa è abbastanza utile, ma uno degli svantaggi di questa modalità è la sua rigidità, cioè tutti i calcoli devono essere conosciuti in anticipo insieme a strutture dati predefinite.

D'altra parte, la modalità simbolica espone un grafico di calcolo come TensorFlow. Rimuove lo svantaggio dell'API imperativa consentendo a MXNet di lavorare con simboli o variabili invece di strutture dati fisse / predefinite. Successivamente, i simboli possono essere interpretati come un insieme di operazioni come segue:

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

Tipi di parallelismo

Apache MXNet supporta la formazione distribuita. Ci consente di sfruttare più macchine per una formazione più rapida ed efficace.

Di seguito sono riportati i due modi in cui possiamo distribuire il carico di lavoro dell'addestramento di un NN su più dispositivi, CPU o dispositivo GPU:

Parallelismo dei dati

In questo tipo di parallelismo, ogni dispositivo memorizza una copia completa del modello e funziona con una parte diversa del set di dati. I dispositivi aggiornano anche un modello condiviso collettivamente. Possiamo individuare tutti i dispositivi su una singola macchina o su più macchine.

Parallelismo del modello

È un altro tipo di parallelismo, utile quando i modelli sono così grandi da non entrare nella memoria del dispositivo. Nel parallelismo del modello, a diversi dispositivi viene assegnato il compito di apprendere diverse parti del modello. Il punto importante da notare qui è che attualmente Apache MXNet supporta il parallelismo dei modelli solo in una singola macchina.

Lavoro di formazione distribuita

I concetti forniti di seguito sono la chiave per comprendere il funzionamento della formazione distribuita in Apache MXNet -

Tipi di processi

I processi comunicano tra loro per realizzare la formazione di un modello. Apache MXNet ha i seguenti tre processi:

Lavoratore

Il compito del nodo di lavoro è eseguire l'addestramento su un batch di campioni di addestramento. I nodi di lavoro estrarranno i pesi dal server prima di elaborare ogni batch. I nodi di lavoro invieranno gradienti al server, una volta che il batch è stato elaborato.

server

MXNet può avere più server per memorizzare i parametri del modello e per comunicare con i nodi di lavoro.

Scheduler

Il ruolo dello scheduler è impostare il cluster, che include l'attesa dei messaggi che ogni nodo ha generato e la porta su cui il nodo è in ascolto. Dopo aver configurato il cluster, lo scheduler comunica a tutti i processi di conoscere ogni altro nodo del cluster. È perché i processi possono comunicare tra loro. C'è solo uno scheduler.

Negozio KV

Negozi KV sta per Key-Valuenegozio. È un componente critico utilizzato per l'addestramento multi-dispositivo. È importante perché la comunicazione dei parametri tra i dispositivi su una singola e su più macchine viene trasmessa attraverso uno o più server con un KVStore per i parametri. Comprendiamo il funzionamento di KVStore con l'aiuto dei seguenti punti:

  • Ogni valore in KVStore è rappresentato da un file key e a value.

  • Ad ogni array di parametri nella rete viene assegnato un file key e il peso di tale matrice di parametri è riferito da value.

  • Dopodiché, il nodo di lavoro pushgradienti dopo l'elaborazione di un batch. Essi anchepull pesi aggiornati prima di elaborare un nuovo batch.

La nozione di server KVStore esiste solo durante l'addestramento distribuito e la sua modalità distribuita viene abilitata chiamando mxnet.kvstore.create funzione con un argomento stringa contenente la parola dist -

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

Distribuzione delle chiavi

Non è necessario che tutti i server memorizzino tutti i parametri array o chiavi, ma sono distribuiti su diversi server. Tale distribuzione di chiavi su diversi server è gestita in modo trasparente da KVStore e la decisione su quale server memorizza una chiave specifica viene presa a caso.

KVStore, come discusso sopra, assicura che ogni volta che la chiave viene estratta, la sua richiesta viene inviata a quel server, che ha il valore corrispondente. E se il valore di una chiave fosse grande? In tal caso, potrebbe essere condiviso tra diversi server.

Dati di allenamento divisi

Essendo gli utenti, vogliamo che ogni macchina lavori su parti diverse del set di dati, in particolare quando si esegue l'addestramento distribuito in modalità parallela dei dati. Sappiamo che, per dividere un batch di campioni forniti dall'iteratore di dati per l'addestramento parallelo dei dati su un singolo lavoratore, possiamo utilizzaremxnet.gluon.utils.split_and_load quindi, carica ogni parte del batch sul dispositivo che lo elaborerà ulteriormente.

D'altra parte, in caso di training distribuito, all'inizio dobbiamo dividere il dataset in nparti diverse in modo che ogni lavoratore riceva una parte diversa. Una volta ottenuto, ogni lavoratore può quindi utilizzaresplit_and_loadper dividere nuovamente quella parte del set di dati tra diversi dispositivi su una singola macchina. Tutto questo avviene tramite l'iteratore di dati.mxnet.io.MNISTIterator e mxnet.io.ImageRecordIter sono due di questi iteratori in MXNet che supportano questa funzione.

Aggiornamento pesi

Per l'aggiornamento dei pesi, KVStore supporta le seguenti due modalità:

  • Il primo metodo aggrega i gradienti e aggiorna i pesi utilizzando quei gradienti.

  • Nel secondo metodo il server aggrega solo i gradienti.

Se stai usando Gluon, c'è un'opzione per scegliere tra i metodi sopra indicati passando update_on_kvstorevariabile. Comprendiamolo creando il filetrainer oggetto come segue -

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)

Modalità di formazione distribuita

Se la stringa di creazione di KVStore contiene la parola dist, significa che l'addestramento distribuito è abilitato. Di seguito sono riportate diverse modalità di formazione distribuita che possono essere abilitate utilizzando diversi tipi di KVStore:

dist_sync

Come suggerisce il nome, denota addestramento distribuito sincrono. In questo, tutti i lavoratori utilizzano lo stesso set sincronizzato di parametri del modello all'inizio di ogni batch.

Lo svantaggio di questa modalità è che, dopo ogni batch, il server dovrebbe attendere di ricevere i gradienti da ogni worker prima di aggiornare i parametri del modello. Ciò significa che se un lavoratore si blocca, si fermerebbe il progresso di tutti i lavoratori.

dist_async

Come suggerisce il nome, denota addestramento distribuito sincrono. In questo, il server riceve gradienti da un lavoratore e aggiorna immediatamente il suo archivio. Il server utilizza l'archivio aggiornato per rispondere a qualsiasi ulteriore pull.

Il vantaggio, rispetto a dist_sync mode, è che un lavoratore che termina l'elaborazione di un batch può estrarre i parametri correnti dal server e avviare il batch successivo. Il lavoratore può farlo, anche se l'altro lavoratore non ha ancora completato l'elaborazione del batch precedente. È anche più veloce della modalità dist_sync perché possono essere necessarie più epoche per convergere senza alcun costo di sincronizzazione.

dist_sync_device

Questa modalità è la stessa di dist_syncmodalità. L'unica differenza è che, quando ci sono più GPU utilizzate su ogni nododist_sync_device aggrega gradienti e aggiorna i pesi sulla GPU mentre, dist_sync aggrega gradienti e aggiorna i pesi sulla memoria della CPU.

Riduce le costose comunicazioni tra GPU e CPU. Ecco perché è più veloce didist_sync. Lo svantaggio è che aumenta l'utilizzo della memoria sulla GPU.

dist_async_device

Questa modalità funziona come dist_sync_device modalità, ma in modalità asincrona.

In questo capitolo impareremo a conoscere i pacchetti Python disponibili in Apache MXNet.

Pacchetti MXNet Python importanti

MXNet ha i seguenti importanti pacchetti Python di cui discuteremo uno per uno:

  • Autograd (differenziazione automatica)

  • NDArray

  • KVStore

  • Gluon

  • Visualization

Per prima cosa iniziamo con Autograd Pacchetto Python per Apache MXNet.

Autograd

Autograd sta per automatic differentiationutilizzato per retropropagare i gradienti dalla metrica di perdita a ciascuno dei parametri. Insieme alla backpropagation utilizza un approccio di programmazione dinamico per calcolare in modo efficiente i gradienti. Viene anche chiamata differenziazione automatica in modalità inversa. Questa tecnica è molto efficiente nelle situazioni "fan-in" in cui molti parametri influenzano una singola metrica di perdita.

Cosa sono i gradienti?

I gradienti sono i fondamenti del processo di formazione della rete neurale. Fondamentalmente ci dicono come modificare i parametri della rete per migliorarne le prestazioni.

Come sappiamo, le reti neurali (NN) sono composte da operatori come somme, prodotto, convoluzioni, ecc. Questi operatori, per i loro calcoli, utilizzano parametri come i pesi nei kernel di convoluzione. Dovremmo trovare i valori ottimali per questi parametri e gradienti ci mostrano la strada e ci portano alla soluzione.

Ci interessa l'effetto della modifica di un parametro sulle prestazioni della rete e i gradienti ci dicono di quanto una data variabile aumenta o diminuisce quando cambiamo una variabile da cui dipende. La performance viene solitamente definita utilizzando una metrica di perdita che cerchiamo di ridurre al minimo. Ad esempio, per la regressione potremmo provare a minimizzareL2 perdita tra le nostre previsioni e il valore esatto, mentre per la classificazione potremmo minimizzare il cross-entropy loss.

Una volta calcolato il gradiente di ogni parametro con riferimento alla perdita, possiamo quindi utilizzare un ottimizzatore, come la discesa del gradiente stocastico.

Come calcolare i gradienti?

Abbiamo le seguenti opzioni per calcolare i gradienti:

  • Symbolic Differentiation- La prima opzione è la differenziazione simbolica, che calcola le formule per ogni gradiente. Lo svantaggio di questo metodo è che porterà rapidamente a formule incredibilmente lunghe man mano che la rete diventa più profonda e gli operatori diventano più complessi.

  • Finite Differencing- Un'altra opzione è quella di utilizzare la differenziazione finita che prova leggere differenze su ogni parametro e vedere come risponde la metrica di perdita. Lo svantaggio di questo metodo è che sarebbe costoso in termini di calcolo e potrebbe avere una scarsa precisione numerica.

  • Automatic differentiation- La soluzione agli inconvenienti dei metodi di cui sopra è quella di utilizzare la differenziazione automatica per propagare indietro i gradienti dalla metrica di perdita a ciascuno dei parametri. La propagazione ci consente un approccio di programmazione dinamico per calcolare in modo efficiente i gradienti. Questo metodo è anche chiamato differenziazione automatica in modalità inversa.

Differenziazione automatica (autograd)

Qui capiremo in dettaglio il funzionamento di autograd. Fondamentalmente funziona in due fasi seguenti:

Stage 1 - Questa fase si chiama ‘Forward Pass’di formazione. Come suggerisce il nome, in questa fase crea il record dell'operatore utilizzato dalla rete per fare previsioni e calcolare la metrica di perdita.

Stage 2 - Questa fase si chiama ‘Backward Pass’di formazione. Come suggerisce il nome, in questa fase funziona a ritroso attraverso questo disco. Andando a ritroso, valuta le derivate parziali di ciascun operatore, fino al parametro di rete.

Vantaggi di autograd

Di seguito sono riportati i vantaggi dell'utilizzo della differenziazione automatica (autograd):

  • Flexible- La flessibilità, che ci offre quando definiamo la nostra rete, è uno degli enormi vantaggi dell'utilizzo di autograd. Possiamo cambiare le operazioni ad ogni iterazione. Questi sono chiamati i grafici dinamici, che sono molto più complessi da implementare in framework che richiedono grafici statici. Autograd, anche in questi casi, sarà comunque in grado di retropropagare correttamente i gradienti.

  • Automatic- Autograd è automatico, cioè le complessità della procedura di backpropagation vengono risolte per te. Dobbiamo solo specificare quali gradienti ci interessa calcolare.

  • Efficient - Autogard calcola i gradienti in modo molto efficiente.

  • Can use native Python control flow operators- Possiamo usare gli operatori nativi del flusso di controllo di Python come la condizione if e il ciclo while. L'autograd sarà ancora in grado di retropropagare i gradienti in modo efficiente e corretto.

Utilizzo di autograd in MXNet Gluon

Qui, con l'aiuto di un esempio, vedremo come possiamo utilizzare autograd in MXNet Gluon.

Esempio di implementazione

Nell'esempio seguente, implementeremo il modello di regressione con due livelli. Dopo l'implementazione, utilizzeremo autograd per calcolare automaticamente il gradiente della perdita con riferimento a ciascuno dei parametri di peso -

Per prima cosa importa l'autogrard e gli altri pacchetti richiesti come segue:

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

Ora, dobbiamo definire la rete come segue:

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

Ora dobbiamo definire la perdita come segue:

loss_function = L2Loss()

Successivamente, dobbiamo creare i dati fittizi come segue:

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

Ora siamo pronti per il nostro primo passaggio in avanti attraverso la rete. Vogliamo che autograd registri il grafico computazionale in modo da poter calcolare i gradienti. Per questo, dobbiamo eseguire il codice di rete nell'ambito diautograd.record contesto come segue -

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

Ora siamo pronti per il passaggio all'indietro, che iniziamo chiamando il metodo all'indietro sulla quantità di interesse. La quantità di interesse nel nostro esempio è la perdita perché stiamo cercando di calcolare il gradiente di perdita con riferimento ai parametri -

loss.backward()

Ora abbiamo gradienti per ogni parametro della rete, che verranno utilizzati dall'ottimizzatore per aggiornare il valore del parametro e migliorare le prestazioni. Controlliamo i gradienti del 1 ° livello come segue:

N_net[0].weight.grad()

Output

L'output è il seguente:

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

Esempio di implementazione completo

Di seguito è riportato l'esempio di implementazione completo.

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()

In questo capitolo, discuteremo del formato di array multidimensionale di MXNet chiamato ndarray.

Gestione dei dati con NDArray

Innanzitutto, vedremo come possiamo gestire i dati con NDArray. Di seguito sono riportati i prerequisiti per lo stesso:

Prerequisiti

Per capire come possiamo gestire i dati con questo formato di array multidimensionale, dobbiamo soddisfare i seguenti prerequisiti:

  • MXNet installato in un ambiente Python

  • Python 2.7.x o Python 3.x

Esempio di implementazione

Comprendiamo le funzionalità di base con l'aiuto di un esempio fornito di seguito:

Innanzitutto, dobbiamo importare MXNet e ndarray da MXNet come segue:

import mxnet as mx
from mxnet import nd

Una volta importate le librerie necessarie, andremo con le seguenti funzionalità di base:

Un semplice array 1-D con un elenco di python

Example

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

Output

L'output è come indicato di seguito -

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

Un array 2-D con un elenco di 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

L'output è come indicato di seguito:

[[ 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)>

Creazione di un NDArray senza alcuna inizializzazione

Qui creeremo una matrice con 3 righe e 4 colonne utilizzando .emptyfunzione. Useremo anche.full funzione, che richiederà un operatore aggiuntivo per il valore che si desidera inserire nell'array.

Example

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

Output

L'output è fornito di seguito:

[[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 di tutti zeri con la funzione .zeros

Example

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

Output

L'output è il seguente:

[[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 di tutti quelli con la funzione .ones

Example

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

Output

L'output è menzionato di seguito:

[[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)>

Creazione di array i cui valori vengono campionati in modo casuale

Example

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

Output

L'output è fornito di seguito:

[[ 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)>

Trovare la dimensione di ogni NDArray

Example

y.shape

Output

L'output è il seguente:

(3, 4)

Trovare la dimensione di ogni NDArray

Example

y.size

Output

12

Trovare il tipo di dati di ogni NDArray

Example

y.dtype

Output

numpy.float32

Operazioni NDArray

In questa sezione, ti presenteremo le operazioni sugli array di MXNet. NDArray supporta un gran numero di operazioni matematiche e sul posto standard.

Operazioni matematiche standard

Di seguito sono riportate le operazioni matematiche standard supportate da NDArray:

Addizione basata sugli elementi

Innanzitutto, dobbiamo importare MXNet e ndarray da MXNet come segue:

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

L'output è fornito di seguito:

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)>

Moltiplicazione per elemento

Example

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

Output

Vedrai il seguente output -

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

Esponenziazione

Example

nd.exp(x)

Output

Quando esegui il codice, vedrai il seguente output:

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

Trasposizione della matrice per calcolare il prodotto matrice-matrice

Example

nd.dot(x, y.T)

Output

Di seguito è riportato l'output del codice:

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

Operazioni sul posto

Ogni volta, nell'esempio precedente, abbiamo eseguito un'operazione, abbiamo allocato una nuova memoria per ospitare il suo risultato.

Ad esempio, se scriviamo A = A + B, dereferenzieremo la matrice a cui A puntava e la indirizzeremo invece alla memoria appena allocata. Cerchiamo di capirlo con l'esempio fornito di seguito, utilizzando la funzione id () di 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

Dopo l'esecuzione, riceverai il seguente output:

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

In effetti, possiamo anche assegnare il risultato a un array precedentemente allocato come segue:

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

L'output è mostrato di seguito:

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

Dall'output di cui sopra, possiamo vedere che x + y allocherà ancora un buffer temporaneo per memorizzare il risultato prima di copiarlo su z. Quindi ora, possiamo eseguire le operazioni sul posto per fare un uso migliore della memoria ed evitare il buffer temporaneo. Per fare ciò, specificheremo l'argomento della parola chiave out che ogni operatore supporta come segue:

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

Eseguendo il programma sopra, otterrai il seguente risultato:

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

Contesti NDArray

In Apache MXNet, ogni array ha un contesto e un contesto potrebbe essere la CPU, mentre altri contesti potrebbero essere più GPU. Le cose possono andare anche peggio, quando distribuiamo il lavoro su più server. Ecco perché, dobbiamo assegnare gli array ai contesti in modo intelligente. Ridurrà al minimo il tempo impiegato per il trasferimento dei dati tra i dispositivi.

Ad esempio, prova a inizializzare un array come segue:

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

Output

Quando esegui il codice sopra, dovresti vedere il seguente output:

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

Possiamo copiare il dato NDArray da un contesto a un altro contesto utilizzando il metodo copyto () come segue:

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

NumPy array vs. NDArray

Abbiamo tutti familiarità con gli array NumPy, ma Apache MXNet offre la propria implementazione di array denominata NDArray. In realtà, inizialmente è stato progettato per essere simile a NumPy ma c'è una differenza fondamentale:

La differenza fondamentale è nel modo in cui i calcoli vengono eseguiti in NumPy e NDArray. Ogni manipolazione di NDArray in MXNet viene eseguita in modo asincrono e non bloccante, il che significa che, quando scriviamo codice come c = a * b, la funzione viene inviata alExecution Engine, che avvierà il calcolo.

Qui, aeb sono entrambi NDArrays. Il vantaggio di utilizzarlo è che la funzione ritorna immediatamente indietro e il thread utente può continuare l'esecuzione nonostante il calcolo precedente potrebbe non essere stato ancora completato.

Funzionamento del motore di esecuzione

Se parliamo del funzionamento del motore di esecuzione, costruisce il grafico di calcolo. Il grafico di calcolo può riordinare o combinare alcuni calcoli, ma rispetta sempre l'ordine di dipendenza.

Ad esempio, se ci sono altre manipolazioni con "X" eseguite successivamente nel codice di programmazione, il motore di esecuzione inizierà a eseguirle una volta che il risultato di "X" sarà disponibile. Il motore di esecuzione gestirà alcuni lavori importanti per gli utenti, come la scrittura di callback per avviare l'esecuzione del codice successivo.

In Apache MXNet, con l'aiuto di NDArray, per ottenere il risultato del calcolo dobbiamo solo accedere alla variabile risultante. Il flusso del codice verrà bloccato finché i risultati del calcolo non verranno assegnati alla variabile risultante. In questo modo, aumenta le prestazioni del codice pur continuando a supportare la modalità di programmazione imperativa.

Conversione di NDArray in NumPy Array

Impariamo come possiamo convertire NDArray in NumPy Array in MXNet.

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

A volte, possiamo assemblare un operatore di livello superiore utilizzando gli operatori esistenti. Uno dei migliori esempi di questo è ilnp.full_like()operatore, che non è presente nell'API NDArray. Può essere facilmente sostituito con una combinazione di operatori esistenti come segue:

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

Otterremo l'output simile come segue:

True

Finding similar operator with different name and/or signature

Tra tutti gli operatori, alcuni hanno nomi leggermente diversi, ma sono simili in termini di funzionalità. Un esempio di questo ènd.ravel_index() con np.ravel()funzioni. Allo stesso modo, alcuni operatori possono avere nomi simili, ma hanno firme diverse. Un esempio di questo ènp.split() e nd.split() sono simili.

Comprendiamolo con il seguente esempio di programmazione:

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

L'output è indicato di seguito:

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

Riduzione al minimo dell'impatto del blocco delle chiamate

In alcuni casi, dobbiamo usare entrambi .asnumpy() o .asscalar()metodi, ma questo costringerà MXNet a bloccare l'esecuzione, fino a quando il risultato non potrà essere recuperato. Possiamo ridurre al minimo l'impatto di una chiamata di blocco chiamando.asnumpy() o .asscalar() metodi nel momento in cui pensiamo che il calcolo di questo valore sia già stato fatto.

Esempio di implementazione

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

L'output è citato di seguito:

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

Un altro pacchetto MXNet Python più importante è Gluon. In questo capitolo discuteremo di questo pacchetto. Gluon fornisce un'API chiara, concisa e semplice per i progetti DL. Consente ad Apache MXNet di prototipare, costruire e addestrare modelli DL senza perdere la velocità di addestramento.

Blocchi

I blocchi costituiscono la base di progetti di rete più complessi. In una rete neurale, con l'aumentare della complessità della rete neurale, dobbiamo passare dalla progettazione di singoli livelli a interi livelli di neuroni. Ad esempio, il design NN come ResNet-152 ha un discreto grado di regolarità in quanto composto dablocks di strati ripetuti.

Esempio

Nell'esempio riportato di seguito, scriveremo codice un blocco semplice, vale a dire blocco per un perceptron multistrato.

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

Questo produce il seguente output:

[[ 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)>

Passaggi necessari per passare dalla definizione dei livelli alla definizione dei blocchi di uno o più livelli -

Step 1 - Block accetta i dati come input.

Step 2- Ora, i blocchi memorizzeranno lo stato sotto forma di parametri. Ad esempio, nell'esempio di codifica sopra il blocco contiene due livelli nascosti e abbiamo bisogno di un posto per memorizzare i parametri per esso.

Step 3- Il blocco successivo richiamerà la funzione di inoltro per eseguire la propagazione in avanti. È anche chiamato calcolo in avanti. Come parte della prima chiamata di inoltro, i blocchi inizializzano i parametri in modo pigro.

Step 4- Infine i blocchi richiameranno la funzione di ritorno e calcoleranno il gradiente con riferimento al loro input. In genere, questo passaggio viene eseguito automaticamente.

Blocco sequenziale

Un blocco sequenziale è un tipo speciale di blocco in cui i dati fluiscono attraverso una sequenza di blocchi. In questo, ogni blocco applicato all'uscita di uno precedente con il primo blocco applicato ai dati di ingresso stessi.

Vediamo come sequential lavori di 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

L'output è fornito di seguito:

[[ 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)>

Blocco personalizzato

Possiamo facilmente andare oltre la concatenazione con il blocco sequenziale come definito sopra. Ma, se vorremmo fare delle personalizzazioni, allora il fileBlockclass ci fornisce anche le funzionalità richieste. La classe Block ha un costruttore di modelli fornito nel modulo nn. Possiamo ereditare quel costruttore del modello per definire il modello che vogliamo.

Nell'esempio seguente, il MLP class sovrascrive il __init__ e le funzioni forward della classe Block.

Vediamo come funziona.

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

Quando esegui il codice, vedrai il seguente output:

[[ 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)>

Livelli personalizzati

L'API Gluon di Apache MXNet viene fornita con un numero modesto di livelli predefiniti. Tuttavia, a un certo punto, potremmo scoprire che è necessario un nuovo livello. Possiamo facilmente aggiungere un nuovo livello nell'API Gluon. In questa sezione vedremo come creare un nuovo livello da zero.

Il livello personalizzato più semplice

Per creare un nuovo livello nell'API Gluon, dobbiamo creare una classe ereditata dalla classe Block che fornisce le funzionalità di base. Possiamo ereditare tutti i livelli predefiniti da esso direttamente o tramite altre sottoclassi.

Per creare il nuovo livello, l'unico metodo di istanza che deve essere implementato è forward (self, x). Questo metodo definisce cosa farà esattamente il nostro livello durante la propagazione in avanti. Come discusso in precedenza, il passaggio di back-propagation per i blocchi verrà eseguito automaticamente da Apache MXNet stesso.

Esempio

Nell'esempio seguente, definiremo un nuovo livello. Lo implementeremo ancheforward() metodo per normalizzare i dati di input inserendoli in un intervallo di [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

Eseguendo il programma sopra, otterrai il seguente risultato:

[[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)>

Ibridazione

Può essere definito come un processo utilizzato da Apache MXNet per creare un grafico simbolico di un calcolo in avanti. L'ibridazione consente a MXNet di aumentare le prestazioni di calcolo ottimizzando il grafico simbolico computazionale. Piuttosto che ereditare direttamente daBlock, infatti, potremmo scoprire che durante l'implementazione di livelli esistenti un blocco eredita da un file HybridBlock.

Di seguito sono riportate le ragioni per questo:

  • Allows us to write custom layers: HybridBlock ci consente di scrivere livelli personalizzati che possono essere ulteriormente utilizzati sia nella programmazione imperativa che in quella simbolica.

  • Increase computation performance- HybridBlock ottimizza il grafico simbolico computazionale che consente a MXNet di aumentare le prestazioni di calcolo.

Esempio

In questo esempio, riscriveremo il nostro livello di esempio, creato sopra, utilizzando 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

L'output è indicato di seguito:

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

L'ibridazione non ha nulla a che fare con il calcolo su GPU e si possono addestrare reti ibridate e non ibridate sia su CPU che su GPU.

Differenza tra Block e HybridBlock

Se confrontiamo il file Block Classe e HybridBlock, lo vedremo HybridBlock ha già il suo forward() metodo implementato. HybridBlock definisce un hybrid_forward()metodo che deve essere implementato durante la creazione dei livelli. L'argomento F crea la principale differenza traforward() e hybrid_forward(). Nella comunità MXNet, l'argomento F è indicato come backend. F può riferirsi amxnet.ndarray API (utilizzato per la programmazione imperativa) o mxnet.symbol API (utilizzato per la programmazione simbolica).

Come aggiungere un livello personalizzato a una rete?

Invece di utilizzare i layer personalizzati separatamente, questi layer vengono utilizzati con layer predefiniti. Possiamo usare entrambiSequential o HybridSequentialcontenitori da una rete neurale sequenziale. Come discusso in precedenza anche,Sequential container eredita da Block e HybridSequential ereditare da HybridBlock rispettivamente.

Esempio

Nell'esempio seguente, creeremo una semplice rete neurale con un livello personalizzato. L'output diDense (5) layer sarà l'input di NormalizationHybridLayer. L'output diNormalizationHybridLayer diventerà l'input di Dense (1) strato.

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

Vedrai il seguente output:

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

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

Parametri del livello personalizzati

In una rete neurale, un livello ha una serie di parametri ad esso associati. A volte li chiamiamo pesi, che è lo stato interno di un livello. Questi parametri svolgono ruoli diversi:

  • A volte questi sono quelli che vogliamo imparare durante la fase di backpropagation.

  • A volte queste sono solo costanti che vogliamo usare durante il passaggio in avanti.

Se parliamo del concetto di programmazione, questi parametri (pesi) di un blocco vengono memorizzati e accessibili tramite ParameterDict classe che aiuta nell'inizializzazione, aggiornamento, salvataggio e caricamento di loro.

Esempio

Nell'esempio seguente, definiremo due seguenti set di parametri:

  • Parameter weights- Questo è addestrabile e la sua forma è sconosciuta durante la fase di costruzione. Verrà dedotto alla prima esecuzione della propagazione in avanti.

  • Parameter scale- Questa è una costante il cui valore non cambia. A differenza dei pesi dei parametri, la sua forma viene definita durante la costruzione.

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

Questo capitolo tratta dei pacchetti python KVStore e della visualizzazione.

Pacchetto KVStore

KV stores sta per Key-Value store. È un componente critico utilizzato per l'addestramento multi-dispositivo. È importante perché la comunicazione dei parametri tra i dispositivi su una singola e su più macchine viene trasmessa attraverso uno o più server con un KVStore per i parametri.

Cerchiamo di capire il funzionamento di KVStore con l'aiuto dei seguenti punti:

  • Ogni valore in KVStore è rappresentato da un file key e a value.

  • Ad ogni array di parametri nella rete viene assegnato un file key e il peso di tale matrice di parametri è riferito da value.

  • Dopodiché, il nodo di lavoro pushgradienti dopo l'elaborazione di un batch. Essi anchepull pesi aggiornati prima di elaborare un nuovo batch.

In parole semplici, possiamo dire che KVStore è un luogo per la condivisione dei dati in cui ogni dispositivo può inserire ed estrarre dati.

Inserimento ed estrazione dei dati

KVStore può essere pensato come un singolo oggetto condiviso tra diversi dispositivi come GPU e computer, in cui ogni dispositivo è in grado di inserire ed estrarre dati.

Di seguito sono riportati i passaggi di implementazione che devono essere seguiti dai dispositivi per inserire ed estrarre i dati:

Fasi di implementazione

Initialisation- Il primo passo è inizializzare i valori. Qui per il nostro esempio, inizializzeremo una coppia (int, NDArray) in KVStrore e successivamente estraeremo i valori -

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

Questo produce il seguente output:

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

Push, Aggregate, and Update - Una volta inizializzato, possiamo inserire un nuovo valore in KVStore con la stessa forma alla chiave -

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

Output

L'output è fornito di seguito:

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

I dati utilizzati per il push possono essere archiviati su qualsiasi dispositivo come GPU o computer. Possiamo anche inserire più valori nella stessa chiave. In questo caso, KVStore prima sommerà tutti questi valori e poi invierà il valore aggregato come segue:

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

Vedrai il seguente output:

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

Per ogni push applicato, KVStore combinerà il valore inviato con il valore già memorizzato. Sarà fatto con l'aiuto di un programma di aggiornamento. Qui, il programma di aggiornamento predefinito è 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

Quando esegui il codice sopra, dovresti vedere il seguente output:

[[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

Di seguito è riportato l'output del codice:

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

Pull - Come per Push, possiamo anche trasferire il valore su più dispositivi con una singola chiamata come segue:

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

Output

L'output è indicato di seguito:

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

Esempio di implementazione completo

Di seguito è riportato l'esempio di implementazione completo:

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())

Gestione delle coppie chiave-valore

Tutte le operazioni che abbiamo implementato sopra coinvolgono una singola chiave, ma KVStore fornisce anche un'interfaccia per a list of key-value pairs -

Per un unico dispositivo

Di seguito è riportato un esempio per mostrare un'interfaccia KVStore per un elenco di coppie chiave-valore per un singolo dispositivo:

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

Riceverai il seguente output:

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

Per più dispositivi

Di seguito è riportato un esempio per mostrare un'interfaccia KVStore per un elenco di coppie chiave-valore per più dispositivi:

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

Vedrai il seguente output:

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

Pacchetto di visualizzazione

Il pacchetto di visualizzazione è il pacchetto Apache MXNet utilizzato per rappresentare la rete neurale (NN) come un grafico di calcolo costituito da nodi e bordi.

Visualizza la rete neurale

Nell'esempio seguente useremo mx.viz.plot_networkper visualizzare la rete neurale. I seguenti sono i prerequisiti per questo:

Prerequisites

  • Taccuino Jupyter

  • Libreria Graphviz

Esempio di implementazione

Nell'esempio seguente visualizzeremo un campione NN per la fattorizzazione di matrici lineari -

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)

Questo capitolo spiega la libreria ndarray disponibile in Apache MXNet.

Mxnet.ndarray

La libreria NDArray di Apache MXNet definisce il core DS (strutture dati) per tutti i calcoli matematici. Due compiti fondamentali di NDArray sono i seguenti:

  • Supporta l'esecuzione rapida su un'ampia gamma di configurazioni hardware.

  • Parallelizza automaticamente più operazioni sull'hardware disponibile.

L'esempio riportato di seguito mostra come è possibile creare un NDArray utilizzando un 'array' 1-D e 2-D da un normale elenco Python -

import mxnet as mx
from mxnet import nd

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

Output

L'output è fornito di seguito:

[ 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

Questo produce il seguente output:

[[ 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)>

Ora discutiamo in dettaglio sulle classi, funzioni e parametri dell'API ndarray di MXNet.

Classi

La seguente tabella è composta dalle classi dell'API ndarray di MXNet -

Classe Definizione
CachedOp (sym [, flags]) Viene utilizzato per l'handle dell'operatore memorizzato nella cache.
NDArray (handle [, scrivibile]) Viene utilizzato come un oggetto array che rappresenta un array multidimensionale e omogeneo di elementi di dimensione fissa.

Funzioni e loro parametri

Di seguito sono riportate alcune delle funzioni importanti e dei relativi parametri coperti dall'API mxnet.ndarray:

Funzione e suoi parametri Definizione
Activation([data, act_type, out, name]) Applica una funzione di attivazione per elemento all'ingresso. Supporta le funzioni di attivazione relu, sigmoid, tanh, softrelu, softsign.
BatchNorm([dati, gamma, beta, moving_mean, ...]) Viene utilizzato per la normalizzazione batch. Questa funzione normalizza un batch di dati in base alla media e alla varianza. Applica una scala gamma e offset beta.
BilinearSampler([dati, griglia, cudnn_off, ...])

Questa funzione applica il campionamento bilineare alla mappa delle caratteristiche di input. In realtà è la chiave di "Spatial Transformer Networks".

Se hai familiarità con la funzione di rimappatura in OpenCV, l'utilizzo di questa funzione è abbastanza simile a quello. L'unica differenza è che ha il passaggio all'indietro.

BlockGrad ([data, out, name]) Come specificato dal nome, questa funzione interrompe il calcolo del gradiente. Fondamentalmente arresta il gradiente accumulato degli input dal fluire attraverso questo operatore all'indietro.
cast ([data, dtype, out, name]) Questa funzione eseguirà il cast di tutti gli elementi dell'input in un nuovo tipo.

Esempi di implementazione

Nell'esempio seguente, utilizzeremo la funzione BilinierSampler () per ingrandire i dati due volte e spostare i dati orizzontalmente di -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

Quando esegui il codice sopra, dovresti vedere il seguente output:

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

L'output sopra mostra lo zoom indietro dei dati due volte.

L'esempio di spostamento dei dati di -1 pixel è il seguente:

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

L'output è indicato di seguito:

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

Allo stesso modo, il seguente esempio mostra l'uso della funzione cast () -

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

Output

Dopo l'esecuzione, riceverai il seguente output:

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

ndarray.contrib

L'API Contrib NDArray è definita nel pacchetto ndarray.contrib. In genere fornisce molte API sperimentali utili per nuove funzionalità. Questa API funziona come un luogo per la comunità in cui possono provare le nuove funzionalità. Anche il collaboratore della funzione riceverà il feedback.

Funzioni e loro parametri

Di seguito sono riportate alcune delle funzioni importanti e dei relativi parametri coperti da mxnet.ndarray.contrib API -

Funzione e suoi parametri Definizione
rand_zipfian(true_classes, num_sampled, ...) Questa funzione estrae campioni casuali da una distribuzione approssimativamente Zipfian. La distribuzione di base di questa funzione è la distribuzione Zipfian. Questa funzione campiona casualmente num_sampled candidati e gli elementi di sampled_candidates vengono estratti dalla distribuzione di base data sopra.
foreach(corpo, dati, stati_iniziali) Come suggerisce il nome, questa funzione esegue un ciclo for con calcolo definito dall'utente su NDArrays sulla dimensione 0. Questa funzione simula un ciclo for e il corpo ha il calcolo per un'iterazione del ciclo for.
while_loop (cond, func, loop_vars [,…]) Come suggerisce il nome, questa funzione esegue un ciclo while con calcoli definiti dall'utente e condizioni di ciclo. Questa funzione simula un ciclo while che letteralmente esegue calcoli personalizzati se la condizione è soddisfatta.
cond(pred, then_func, else_func) Come suggerisce il nome, questa funzione esegue un if-then-else utilizzando condizioni e calcoli definiti dall'utente. Questa funzione simula un ramo if-like che sceglie di eseguire uno dei due calcoli personalizzati in base alla condizione specificata.
isinf(dati) Questa funzione esegue un controllo in termini di elemento per determinare se NDArray contiene un elemento infinito o meno.
getnnz([dati, asse, uscita, nome]) Questa funzione ci fornisce il numero di valori memorizzati per un tensore sparso. Include anche zeri espliciti. Supporta solo la matrice CSR sulla CPU.
riquantizza ([dati, intervallo_min, intervallo_max, ...]) Questa funzione riquantizza i dati forniti che vengono quantizzati in int32 e le soglie corrispondenti, in int8 utilizzando le soglie min e max calcolate a runtime o dalla calibrazione.

Esempi di implementazione

Nell'esempio seguente, useremo la funzione rand_zipfian per disegnare campioni casuali da una distribuzione approssimativamente Zipfian -

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

Vedrai il seguente output:

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

Example

exp_count_true

Output

L'output è fornito di seguito:

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

Example

exp_count_sample

Output

Questo produce il seguente output:

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

Nell'esempio seguente, useremo la funzione while_loop per eseguire un ciclo while per il calcolo definito dall'utente e la condizione del ciclo:

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

L'output è mostrato di seguito:

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

Example

States

Output

Questo produce il seguente output:

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

ndarray.image

L'API Image NDArray è definita nel pacchetto ndarray.image. Come suggerisce il nome, viene tipicamente utilizzato per le immagini e le loro caratteristiche.

Funzioni e loro parametri

Di seguito sono riportate alcune delle funzioni importanti e dei relativi parametri coperti da mxnet.ndarray.image API-

Funzione e suoi parametri Definizione
adjust_lighting([data, alpha, out, name]) Come suggerisce il nome, questa funzione regola il livello di illuminazione dell'ingresso. Segue lo stile AlexNet.
crop([dati, x, y, larghezza, altezza, fuori, nome]) Con l'aiuto di questa funzione, possiamo ritagliare un'immagine NDArray di forma (H x W x C) o (N x H x L x C) alla dimensione fornita dall'utente.
normalize([data, mean, std, out, name]) Normalizzerà un tensore di forma (C x H x W) o (N x C x H x W) con mean e standard deviation(SD).
random_crop ([data, xrange, yrange, width, ...]) Simile a crop (), ritaglia in modo casuale un'immagine NDArray di forma (H x L x C) o (N x H x L x C) alla dimensione fornita dall'utente. Sovracampiona il risultato se src è più piccolo della dimensione.
random_lighting([data, alpha_std, out, name]) Come suggerisce il nome, questa funzione aggiunge il rumore PCA in modo casuale. Segue anche lo stile AlexNet.
random_resized_crop([data, xrange, yrange, ...]) Ritaglia anche un'immagine in modo casuale NDArray di forma (H x L x C) o (N x H x L x C) alla dimensione data. Sovracampiona il risultato, se src è più piccolo della dimensione. Inoltre randomizzerà anche l'area e le proporzioni.
resize([data, size, keep_ratio, interp, ...]) Come suggerisce il nome, questa funzione ridimensionerà un'immagine NDArray di forma (H x W x C) o (N x H x L x C) alla dimensione fornita dall'utente.
to_tensor([data, out, name]) Converte un'immagine NDArray di forma (H x W x C) o (N x H x W x C) con i valori nell'intervallo [0, 255] in un tensore NDArray di forma (C x H x W) o ( N x C x H x W) con i valori nell'intervallo [0, 1].

Esempi di implementazione

Nell'esempio seguente, utilizzeremo la funzione to_tensor per convertire l'immagine NDArray di forma (H x L x C) o (N x H x L x C) con i valori nell'intervallo [0, 255] in un tensore NDArray di forma (C x H x W) o (N x C x H x L) con i valori nell'intervallo [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

Vedrai il seguente output:

[[[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

Quando esegui il codice, vedrai il seguente output:

[[[[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)>

Nell'esempio seguente, useremo la funzione normalize per normalizzare un tensore di forma (C x H x W) o (N x C x H x W) con mean e 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

Questo produce il seguente output:

[[[ 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

Quando esegui il codice sopra, dovresti vedere il seguente output:

[[[[ 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 è definita nel pacchetto ndarray.random. Come suggerisce il nome, è il generatore di distribuzione casuale NDArray API di MXNet.

Funzioni e loro parametri

Di seguito sono riportate alcune delle funzioni importanti e dei relativi parametri coperti da mxnet.ndarray.random API -

Funzione e suoi parametri Definizione
uniforme ([low, high, shape, dtype, ctx, out]) Genera campioni casuali da una distribuzione uniforme.
normale ([loc, scale, shape, dtype, ctx, out]) Genera campioni casuali da una distribuzione normale (gaussiana).
randn (* forma, ** kwargs) Genera campioni casuali da una distribuzione normale (gaussiana).
esponenziale ([scale, shape, dtype, ctx, out]) Genera campioni da una distribuzione esponenziale.
gamma ([alpha, beta, shape, dtype, ctx, out]) Genera campioni casuali da una distribuzione gamma.
multinomiale (data [, shape, get_prob, out, dtype]) Genera campionamento simultaneo da più distribuzioni multinomiali.
negativo_binomiale ([k, p, forma, dtype, ctx, out]) Genera campioni casuali da una distribuzione binomiale negativa.
generalized_negative_binomial ([mu, alpha,…]) Genera campioni casuali da una distribuzione binomiale negativa generalizzata.
shuffle (dati, ** kwargs) Mescola gli elementi in modo casuale.
randint (basso, alto [, forma, dtype, ctx, out]) Genera campioni casuali da una distribuzione uniforme discreta.
exponential_like ([data, lam, out, name]) Genera campioni casuali da una distribuzione esponenziale in base alla forma dell'array di input.
gamma_like ([data, alpha, beta, out, name]) Genera campioni casuali da una distribuzione gamma in base alla forma dell'array di input.
generalized_negative_binomial_like ([data,…]) Genera campioni casuali da una distribuzione binomiale negativa generalizzata, in base alla forma dell'array di input.
negative_binomial_like ([data, k, p, out, name]) Genera campioni casuali da una distribuzione binomiale negativa, in base alla forma dell'array di input.
normal_like ([data, loc, scale, out, name]) Genera campioni casuali da una distribuzione normale (gaussiana), in base alla forma dell'array di input.
poisson_like ([data, lam, out, name]) Genera campioni casuali da una distribuzione di Poisson, in base alla forma dell'array di input.
uniform_like ([data, low, high, out, name]) Genera campioni casuali da una distribuzione uniforme, in base alla forma dell'array di input.

Esempi di implementazione

Nell'esempio seguente, disegneremo campioni casuali da una distribuzione uniforme. Per questo utilizzerà la funzioneuniform().

mx.nd.random.uniform(0, 1)

Output

L'output è menzionato di seguito:

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

Example

mx.nd.random.uniform(-1, 1, shape=(2,))

Output

L'output è fornito di seguito:

[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

Vedrai il seguente output:

[[1.8649333 1.8073189]
 [2.4113967 2.5691009]
 [3.1399727 3.4071832]]
<NDArray 3x2 @cpu(0)>

Nell'esempio seguente, trarremo campioni casuali da una distribuzione binomiale negativa generalizzata. Per questo, useremo la funzionegeneralized_negative_binomial().

mx.nd.random.generalized_negative_binomial(10, 0.5)

Output

Quando esegui il codice sopra, dovresti vedere il seguente output:

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

Example

mx.nd.random.generalized_negative_binomial(10, 0.5, shape=(2,))

Output

L'output è fornito di seguito:

[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

Di seguito è riportato l'output del codice:

[[0. 0.]
 [4. 1.]
 [9. 3.]]
<NDArray 3x2 @cpu(0)>

ndarray.utils

L'utilità NDArray API è definita nel pacchetto ndarray.utils. Come suggerisce il nome, fornisce le funzioni di utilità per NDArray e BaseSparseNDArray.

Funzioni e loro parametri

Di seguito sono riportate alcune delle funzioni importanti e dei relativi parametri coperti da mxnet.ndarray.utils API -

Funzione e suoi parametri Definizione
zeri (forma [, ctx, dtype, stype]) Questa funzione restituirà un nuovo array di forma e tipo dati, riempito con zeri.
vuoto (forma [, ctx, dtype, stype]) Restituirà un nuovo array di forma e tipo dati, senza inizializzare le voci.
array (array_origine [, ctx, dtype]) Come suggerisce il nome, questa funzione creerà un array da qualsiasi oggetto che espone l'interfaccia dell'array.
caricare (fname) Caricherà un array dal file.
load_frombuffer (buf) Come suggerisce il nome, questa funzione caricherà un dizionario o un elenco di array da un buffer
salva (fname, dati) Questa funzione salverà un elenco di array o un dict di str-> array in un file.

Esempi di implementazione

Nell'esempio seguente, restituiremo un nuovo array di forma e tipo dati, riempito con zeri. Per questo, useremo la funzionezeros().

mx.nd.zeros((1,2), mx.cpu(), stype='csr')

Output

Questo produce il seguente output:

<CSRNDArray 1x2 @cpu(0)>

Example

mx.nd.zeros((1,2), mx.cpu(), 'float16', stype='row_sparse').asnumpy()

Output

Riceverai il seguente output:

array([[0., 0.]], dtype=float16)

Nell'esempio seguente, salveremo un elenco di array e un dizionario di stringhe. Per questo, useremo la funzionesave().

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

Dopo l'esecuzione, riceverai il seguente output:

[
[[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

L'output è mostrato di seguito:

{'x':
[[0. 0. 0.]
[0. 0. 0.]]
<NDArray 2x3 @cpu(0)>, 'y':
[[1. 1. 1. 1.]]
<NDArray 1x4 @cpu(0)>}

Come abbiamo già discusso nei capitoli precedenti, MXNet Gluon fornisce un'API chiara, concisa e semplice per i progetti DL. Consente ad Apache MXNet di prototipare, costruire e addestrare modelli DL senza perdere la velocità di addestramento.

Moduli principali

Impariamo i moduli principali di Apache MXNet Python application programming interface (API) gluon.

gluon.nn

Gluon fornisce un gran numero di livelli NN incorporati nel modulo gluon.nn. Questo è il motivo per cui è chiamato il modulo principale.

Metodi e loro parametri

Di seguito sono riportati alcuni dei metodi importanti e dei relativi parametri coperti da mxnet.gluon.nn modulo principale -

Metodi e suoi parametri Definizione
Attivazione (attivazione, ** kwargs) Come suggerisce il nome, questo metodo applica una funzione di attivazione all'input.
AvgPool1D ([pool_size, strides, padding, ...]) Questa è un'operazione di pooling media per i dati temporali.
AvgPool2D ([pool_size, strides, padding, ...]) Questa è un'operazione di pooling media per i dati spaziali.
AvgPool3D ([pool_size, strides, padding, ...]) Questa è un'operazione di pooling media per i dati 3D. I dati possono essere spaziali o spazio-temporali.
BatchNorm ([asse, quantità di moto, epsilon, centro, ...]) Rappresenta il livello di normalizzazione batch.
BatchNormReLU ([axis, momentum, epsilon, ...]) Rappresenta anche il livello di normalizzazione batch ma con funzione di attivazione Relu.
Blocca ([prefix, params]) Fornisce la classe base per tutti i livelli e modelli di rete neurale.
Conv1D (canali, kernel_size [, strides, ...]) Questo metodo viene utilizzato per lo strato di convoluzione 1-D. Ad esempio, convoluzione temporale.
Conv1DTranspose (canali, kernel_size [, ...]) Questo metodo viene utilizzato per il livello di convoluzione 1D trasposto.
Conv2D (canali, kernel_size [, strides, ...]) Questo metodo viene utilizzato per il livello di convoluzione 2D. Ad esempio, convoluzione spaziale sulle immagini).
Conv2DTranspose (canali, kernel_size [, ...]) Questo metodo viene utilizzato per il livello di convoluzione 2D trasposto.
Conv3D (canali, kernel_size [, strides, ...]) Questo metodo viene utilizzato per il livello di convoluzione 3D. Ad esempio, convoluzione spaziale sui volumi.
Conv3DTranspose (canali, kernel_size [, ...]) Questo metodo viene utilizzato per il livello di convoluzione 3D trasposto.
Denso (unità [, attivazione, use_bias, ...]) Questo metodo rappresenta per il tuo normale livello NN densamente connesso.
Abbandono (tasso [, assi]) Come suggerisce il nome, il metodo applica Dropout all'input.
ELU ([alpha]) Questo metodo viene utilizzato per Exponential Linear Unit (ELU).
Incorporamento (input_dim, output_dim [, dtype, ...]) Trasforma interi non negativi in ​​vettori densi di dimensione fissa.
Appiattisci (** kwargs) Questo metodo appiattisce l'input a 2-D.
GELU (** kwargs) Questo metodo viene utilizzato per Gaussian Exponential Linear Unit (GELU).
GlobalAvgPool1D ([layout]) Con l'aiuto di questo metodo, possiamo eseguire un'operazione di pooling medio globale per i dati temporali.
GlobalAvgPool2D ([layout]) Con l'aiuto di questo metodo, possiamo eseguire un'operazione di pooling medio globale per i dati spaziali.
GlobalAvgPool3D ([layout]) Con l'aiuto di questo metodo, possiamo eseguire un'operazione di pooling medio globale per i dati 3-D.
GlobalMaxPool1D ([layout]) Con l'aiuto di questo metodo, possiamo eseguire l'operazione di pooling massimo globale per i dati 1-D.
GlobalMaxPool2D ([layout]) Con l'aiuto di questo metodo, possiamo eseguire l'operazione di pooling massimo globale per i dati 2D.
GlobalMaxPool3D ([layout]) Con l'aiuto di questo metodo, possiamo eseguire l'operazione di pooling massimo globale per i dati 3-D.
GroupNorm ([num_groups, epsilon, center, ...]) Questo metodo applica la normalizzazione del gruppo all'array di input nD.
HybridBlock ([prefix, params]) Questo metodo supporta l'inoltro con entrambi Symbol e NDArray.
HybridLambda(funzione [, prefisso]) Con l'aiuto di questo metodo possiamo racchiudere un operatore o un'espressione come oggetto HybridBlock.
HybridSequential ([prefix, params]) Impila gli HybridBlock in sequenza.
InstanceNorm ([asse, epsilon, centro, scala, ...]) Questo metodo applica la normalizzazione dell'istanza all'array di input nD.

Esempi di implementazione

Nell'esempio seguente, useremo Block () che fornisce la classe base per tutti i livelli e modelli di rete neurale.

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

Vedrai il seguente output:

[[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;

Nell'esempio seguente, utilizzeremo HybridBlock () che supporta l'inoltro sia con Symbol che con 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

L'output è menzionato di seguito:

[[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 fornisce un gran numero di build-in recurrent neural network(RNN) strati nel modulo gluon.rnn. Questo è il motivo, si chiama modulo principale.

Metodi e loro parametri

Di seguito sono riportati alcuni dei metodi importanti e dei relativi parametri coperti da mxnet.gluon.nn modulo principale:

Metodi e suoi parametri Definizione
BidirectionalCell (l_cell, r_cell [,…]) Viene utilizzato per la cella Bidirectional Recurrent Neural Network (RNN).
DropoutCell (tasso [, assi, prefisso, parametri]) Questo metodo applicherà il dropout sull'input fornito.
GRU (hidden_size [, num_layers, layout, ...]) Applica un RNN multi-layer gated recurrent unit (GRU) a una determinata sequenza di input.
GRUCell (hidden_size [,…]) Viene utilizzato per la cella di rete Gated Rectified Unit (GRU).
HybridRecurrentCell ([prefix, params]) Questo metodo supporta l'ibridazione.
HybridSequentialRNNCell ([prefix, params]) Con l'aiuto di questo metodo possiamo impilare sequenzialmente più celle HybridRNN.
LSTM (hidden_size [, num_layers, layout, ...]) 0 Applica un RNN di memoria a lungo termine (LSTM) multistrato a una determinata sequenza di input.
LSTMCell (hidden_size [,…]) Viene utilizzato per la cella di rete LSTM (Long-Short Term Memory).
ModifierCell (base_cell) È la classe Base per le celle modificatrici.
RNN (hidden_size [, num_layers, activation, ...]) Applica un Elman RNN multistrato con tanh o ReLU non linearità a una data sequenza di input.
RNNCell (hidden_size [, attivazione, ...]) Viene utilizzato per la cella di rete neurale ricorrente Elman RNN.
RecurrentCell ([prefix, params]) Rappresenta la classe base astratta per le celle RNN.
SequentialRNNCell ([prefix, params]) Con l'aiuto di questo metodo possiamo impilare sequenzialmente più celle RNN.
ZoneoutCell (base_cell [, zoneout_outputs, ...]) Questo metodo applica Zoneout sulla cella di base.

Esempi di implementazione

Nell'esempio seguente, useremo GRU () che applica un RNN di unità ricorrente (GRU) a più livelli a una data sequenza di input.

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

Questo produce il seguente output:

[[[ 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

Questo produce il seguente output:

[[[-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
………………………….

Nell'esempio seguente useremo LSTM () che applica un RNN di memoria a lungo termine (LSTM) a una data sequenza di input.

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

L'output è menzionato di seguito:

[[[ 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

Quando esegui il codice, vedrai il seguente output:

[
[[[ 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
……………………

Moduli di formazione

I moduli di formazione in Gluon sono i seguenti:

gluon.loss

In mxnet.gluon.lossmodulo, Gluon fornisce una funzione di perdita predefinita. Fondamentalmente, ha le perdite per l'addestramento della rete neurale. Questo è il motivo per cui si chiama modulo di formazione.

Metodi e loro parametri

Di seguito sono riportati alcuni dei metodi importanti e dei relativi parametri coperti da mxnet.gluon.loss modulo di formazione:

Metodi e suoi parametri Definizione
Perdita (peso, batch_axis, ** kwarg) Questo funge da classe base per la perdita.
L2Loss ([peso, batch_axis]) Calcola l'errore quadratico medio (MSE) tra label e prediction(pred).
L1Loss ([weight, batch_axis]) Calcola l'errore assoluto medio (MAE) tra label e pred.
SigmoidBinaryCrossEntropyLoss ([…]) Questo metodo viene utilizzato per la perdita di entropia incrociata per la classificazione binaria.
SigmoidBCELoss Questo metodo viene utilizzato per la perdita di entropia incrociata per la classificazione binaria.
SoftmaxCrossEntropyLoss ([axis,…]) Calcola la softmax cross-entropy loss (CEL).
SoftmaxCELoss Calcola anche la perdita di entropia incrociata softmax.
KLDivLoss ([from_logits, axis, weight, ...]) Viene utilizzato per la perdita di divergenza Kullback-Leibler.
CTCLoss ([layout, label_layout, weight]) Viene utilizzato per la perdita di classificazione temporale (TCL) connessionista.
HuberLoss ([rho, weight, batch_axis]) Calcola la perdita L1 livellata. La perdita L1 livellata sarà uguale alla perdita L1 se l'errore assoluto supera rho, altrimenti è uguale alla perdita L2.
HingeLoss ([margin, weight, batch_axis]) Questo metodo calcola la funzione di perdita della cerniera spesso utilizzata negli SVM:
SquaredHingeLoss ([margin, weight, batch_axis]) Questo metodo calcola la funzione di perdita di margine flessibile utilizzata negli SVM:
LogisticLoss ([weight, batch_axis, label_format]) Questo metodo calcola la perdita logistica.
TripletLoss ([margin, weight, batch_axis]) Questo metodo calcola la perdita di triplette dati tre tensori di input e un margine positivo.
PoissonNLLLoss ([weight, from_logits,…]) La funzione calcola la perdita di probabilità del log negativo.
CosineEmbeddingLoss ([weight, batch_axis, margin]) La funzione calcola la distanza del coseno tra i vettori.
SDMLLoss ([smoothing_parameter, weight,…]) Questo metodo calcola la perdita SDML (Batchwise Smoothed Deep Metric Learning) dati due tensori di input e una perdita SDM di peso livellante. Apprende la somiglianza tra campioni accoppiati utilizzando campioni non accoppiati nel minibatch come potenziali esempi negativi.

Esempio

Come lo sappiamo mxnet.gluon.loss.losscalcolerà il MSE (Mean Squared Error) tra etichetta e previsione (pred). È fatto con l'aiuto della seguente formula:

gluon.parameter

mxnet.gluon.parameter è un contenitore che contiene i parametri cioè i pesi dei blocchi.

Metodi e loro parametri

Di seguito sono riportati alcuni dei metodi importanti e dei relativi parametri coperti da mxnet.gluon.parameter modulo di formazione -

Metodi e suoi parametri Definizione
cast (dtype) Questo metodo eseguirà il cast dei dati e del gradiente di questo parametro su un nuovo tipo di dati.
dati ([ctx]) Questo metodo restituirà una copia di questo parametro in un contesto.
grad ([ctx]) Questo metodo restituirà un buffer del gradiente per questo parametro in un contesto.
inizializza ([init, ctx, default_init, ...]) Questo metodo inizializzerà gli array di parametri e gradienti.
list_ctx () Questo metodo restituirà un elenco di contesti in cui questo parametro è inizializzato.
list_data () Questo metodo restituirà copie di questo parametro in tutti i contesti. Sarà fatto nello stesso ordine della creazione.
list_grad () Questo metodo restituirà buffer sfumati in tutti i contesti. Ciò avverrà nello stesso ordine divalues().
list_row_sparse_data (row_id) Questo metodo restituirà copie del parametro "row_sparse" in tutti i contesti. Ciò avverrà nello stesso ordine della creazione.
reset_ctx (ctx) Questo metodo riassegnerà il parametro ad altri contesti.
row_sparse_data (row_id) Questo metodo restituirà una copia del parametro "row_sparse" nello stesso contesto di row_id.
set_data (dati) Questo metodo imposterà il valore di questo parametro in tutti i contesti.
var () Questo metodo restituirà un simbolo che rappresenta questo parametro.
zero_grad () Questo metodo imposterà il buffer del gradiente su tutti i contesti su 0.

Esempio di implementazione

Nell'esempio seguente, inizializzeremo i parametri e gli array dei gradienti utilizzando il metodo initialize () come segue:

weight = mx.gluon.Parameter('weight', shape=(2, 2))
weight.initialize(ctx=mx.cpu(0))
weight.data()

Output

L'output è menzionato di seguito:

[[-0.0256899 0.06511251]
[-0.00243821 -0.00123186]]
<NDArray 2x2 @cpu(0)>

Example

weight.grad()

Output

L'output è fornito di seguito:

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

Example

weight.initialize(ctx=[mx.gpu(0), mx.gpu(1)])
weight.data(mx.gpu(0))

Output

Vedrai il seguente output:

[[-0.00873779 -0.02834515]
 [ 0.05484822 -0.06206018]]
<NDArray 2x2 @gpu(0)>

Example

weight.data(mx.gpu(1))

Output

Quando esegui il codice sopra, dovresti vedere il seguente output:

[[-0.00873779 -0.02834515]
 [ 0.05484822 -0.06206018]]
<NDArray 2x2 @gpu(1)>

gluon.trainer

mxnet.gluon.trainer applica un ottimizzatore a una serie di parametri. Dovrebbe essere usato insieme ad autograd.

Metodi e loro parametri

Di seguito sono riportati alcuni dei metodi importanti e dei relativi parametri coperti da mxnet.gluon.trainer modulo di formazione -

Metodi e suoi parametri Definizione
allreduce_grads () Questo metodo ridurrà i gradienti da diversi contesti per ogni parametro (peso).
load_states (fname) Come suggerisce il nome, questo metodo caricherà gli stati del trainer.
save_states (fname) Come suggerisce il nome, questo metodo salverà gli stati del trainer.
set_learning_rate (lr) Questo metodo imposterà una nuova velocità di apprendimento dell'ottimizzatore.
passaggio (batch_size [, ignore_stale_grad]) Questo metodo eseguirà un passaggio dell'aggiornamento dei parametri. Dovrebbe essere chiamato dopoautograd.backward() e al di fuori di record() scopo.
aggiornamento (batch_size [, ignore_stale_grad]) Questo metodo farà anche un passaggio per l'aggiornamento dei parametri. Dovrebbe essere chiamato dopoautograd.backward() e al di fuori di record() scope e dopo trainer.update ().

Moduli dati

I moduli dati di Gluon sono spiegati di seguito:

gluon.data

Gluon fornisce un gran numero di utilità per set di dati incorporate nel modulo gluon.data. Questo è il motivo per cui è chiamato modulo dati.

Classi e loro parametri

Di seguito sono riportati alcuni dei metodi importanti e dei relativi parametri coperti dal modulo principale mxnet.gluon.data. Questi metodi sono in genere correlati a set di dati, campionamento e DataLoader.

Set di dati
Metodi e suoi parametri Definizione
ArrayDataset (* args) Questo metodo rappresenta un set di dati che combina due o più di due oggetti simili a un set di dati. Ad esempio, set di dati, elenchi, array, ecc.
BatchSampler (sampler, batch_size [, last_batch]) Questo metodo avvolge un altro Sampler. Una volta confezionato restituisce i mini lotti di campioni.
DataLoader (set di dati [, batch_size, shuffle, ...]) Simile a BatchSampler ma questo metodo carica i dati da un set di dati. Una volta caricato restituisce i mini batch di dati.
Questo rappresenta la classe del set di dati astratto.
FilterSampler (fn, set di dati) Questo metodo rappresenta gli elementi di esempio da un Dataset per il quale fn (funzione) restituisce True.
RandomSampler (lunghezza) Questo metodo rappresenta campioni di elementi da [0, length) in modo casuale senza sostituzione.
RecordFileDataset (nome file) Rappresenta un set di dati che avvolge un file RecordIO. L'estensione del file è.rec.
Campionatore Questa è la classe base per i campionatori.
SequentialSampler (lunghezza [, inizio]) Rappresenta gli elementi campione dell'insieme [inizio, inizio + lunghezza) in sequenza.
Rappresenta gli elementi campione dell'insieme [inizio, inizio + lunghezza) in sequenza. Questo rappresenta il semplice wrapper del set di dati soprattutto per elenchi e array.

Esempi di implementazione

Nell'esempio seguente, useremo gluon.data.BatchSampler()API, che avvolge un altro campionatore. Restituisce i mini lotti di campioni.

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

L'output è menzionato di seguito:

[[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11], [12, 13, 14]]

gluon.data.vision.datasets

Gluon fornisce un gran numero di funzioni di dataset di visione predefinite in gluon.data.vision.datasets modulo.

Classi e loro parametri

MXNet ci fornisce set di dati utili e importanti, le cui classi e parametri sono riportati di seguito:

Classi e suoi parametri Definizione
MNIST ([root, train, transform]) Questo è un set di dati utile che ci fornisce le cifre scritte a mano. L'URL per il set di dati MNIST è http://yann.lecun.com/exdb/mnist
FashionMNIST ([root, train, transform]) Questo set di dati è costituito dalle immagini degli articoli di Zalando costituite da prodotti di moda. È una sostituzione immediata del set di dati MNIST originale. Puoi ottenere questo set di dati da https://github.com/zalandoresearch/fashion-mnist
CIFAR10 ([root, train, transform]) Questo è un set di dati di classificazione delle immagini da https://www.cs.toronto.edu/~kriz/cifar.html. In questo set di dati ogni campione è un'immagine con forma (32, 32, 3).
CIFAR100 ([root, fine_label, train, transform]) Questo è il set di dati di classificazione delle immagini CIFAR100 da https://www.cs.toronto.edu/~kriz/cifar.html. Inoltre, ogni campione è un'immagine con forma (32, 32, 3).
ImageRecordDataset (nomefile [, flag, transform]) Questo set di dati sta avvolgendo un file RecordIO che contiene immagini. In questo ogni campione è un'immagine con la sua etichetta corrispondente.
ImageFolderDataset (root [, flag, transform]) Questo è un set di dati per il caricamento di file di immagine archiviati in una struttura di cartelle.
ImageListDataset ([root, imglist, flag]) Questo è un set di dati per il caricamento dei file di immagine specificati da un elenco di voci.

Esempio

Nell'esempio seguente, mostreremo l'uso di ImageListDataset (), che viene utilizzato per caricare file di immagine specificati da un elenco di voci:

# 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]]

Moduli di utilità

I moduli di utilità in Gluon sono i seguenti:

gluon.utils

Gluon fornisce un gran numero di ottimizzatori di utilità di parallelizzazione incorporati nel modulo gluon.utils. Fornisce una varietà di utilità per la formazione. Questo è il motivo per cui è chiamato modulo di utilità.

Funzioni e loro parametri

Di seguito sono riportate le funzioni ei relativi parametri costituiti da questo modulo di utilità denominato gluon.utils −

Funzioni e suoi parametri Definizione
split_data (data, num_slice [, batch_axis, ...]) Questa funzione viene solitamente utilizzata per il parallelismo dei dati e ogni slice viene inviata a un dispositivo, ovvero GPU. Divide un NDArray innum_slice fette lungo batch_axis.
split_and_load (data, ctx_list [, batch_axis, ...]) Questa funzione divide un NDArray in len(ctx_list) fette lungo batch_axis. L'unica differenza dalla funzione split_data () sopra è che carica anche ogni slice in un contesto in ctx_list.
clip_global_norm (array, max_norm [,…]) Il compito di questa funzione è riscalare gli NDArray in modo tale che la somma della loro 2-norma sia inferiore a max_norm.
check_sha1 (nome file, sha1_hash) Questa funzione controllerà se l'hash sha1 del contenuto del file corrisponde o meno all'hash previsto.
download (url [, path, overwrite, sha1_hash,…]) Come specificato dal nome, questa funzione scaricherà un determinato URL.
sostituire_file (src, dst) Questa funzione implementerà atomic os.replace. sarà fatto con Linux e OSX.

Questo capitolo tratta l'API autograd e inizializzatore in MXNet.

mxnet.autograd

Questa è l'API autograd di MXNet per NDArray. Ha la seguente classe:

Classe: Funzione ()

Viene utilizzato per la differenziazione personalizzata in autograd. Può essere scritto comemxnet.autograd.Function. Se, per qualsiasi motivo, l'utente non desidera utilizzare i gradienti calcolati dalla regola della catena predefinita, può utilizzare la classe Function di mxnet.autograd per personalizzare la differenziazione per il calcolo. Ha due metodi: Forward () e Backward ().

Cerchiamo di capire il funzionamento di questa classe con l'aiuto dei seguenti punti:

  • Innanzitutto, dobbiamo definire il nostro calcolo nel metodo forward.

  • Quindi, dobbiamo fornire la differenziazione personalizzata nel metodo a ritroso.

  • Ora durante il calcolo del gradiente, invece della funzione all'indietro definita dall'utente, mxnet.autograd utilizzerà la funzione all'indietro definita dall'utente. Possiamo anche eseguire il cast su numpy array e viceversa per alcune operazioni in avanti e all'indietro.

Example

Prima di utilizzare la classe mxnet.autograd.function, definiamo una funzione sigmoide stabile con metodi all'indietro e in avanti come segue:

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)

Ora, la classe della funzione può essere utilizzata come segue:

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

Quando esegui il codice, vedrai il seguente output:

array([0.21458015, 0.21291625, 0.23330082, 0.2361367 , 0.23086983,
0.24060014, 0.20326573, 0.21093895, 0.24968489, 0.24301809],
dtype=float32)

Metodi e loro parametri

Di seguito sono riportati i metodi ei relativi parametri della classe mxnet.autogard.function:

Metodi e suoi parametri Definizione
forward (heads [, head_grads, keep_graph, ...]) Questo metodo viene utilizzato per il calcolo in avanti.
indietro (heads [, head_grads, keep_graph, ...]) Questo metodo viene utilizzato per il calcolo all'indietro. Calcola i gradienti delle teste rispetto alle variabili precedentemente contrassegnate. Questo metodo accetta tanti input quanti output di forward. Restituisce anche tanti NDArray quanti sono gli input del forward.
get_symbol (x) Questo metodo viene utilizzato per recuperare la cronologia dei calcoli registrata come file Symbol.
grad (teste, variabili [, head_grads, ...]) Questo metodo calcola i gradienti delle teste rispetto alle variabili. Una volta calcolati, invece di archiviare in variable.grad, i gradienti verranno restituiti come nuovi NDArray.
is_recording () Con l'aiuto di questo metodo possiamo ottenere lo stato della registrazione e non della registrazione.
is_training () Con l'aiuto di questo metodo possiamo ottenere lo stato dell'allenamento e della previsione.
mark_variables (variabili, gradienti [, grad_reqs]) Questo metodo contrassegnerà gli NDArrays come variabili per calcolare il gradiente per autograd. Questo metodo è lo stesso della funzione .attach_grad () in una variabile, ma l'unica differenza è che con questa chiamata possiamo impostare il gradiente su qualsiasi valore.
pausa ([train_mode]) Questo metodo restituisce un contesto di ambito da utilizzare nell'istruzione "with" per i codici che non richiedono il calcolo dei gradienti.
forecast_mode () Questo metodo restituisce un contesto di ambito da utilizzare nell'istruzione "with" in cui il comportamento del passaggio in avanti è impostato sulla modalità di inferenza e cioè senza modificare gli stati di registrazione.
record ([train_mode]) Restituirà un file autograd registrazione del contesto dell'ambito da utilizzare nell'istruzione "with" e cattura il codice che richiede il calcolo dei gradienti.
set_recording (is_recording) Simile a is_recoring (), con l'aiuto di questo metodo possiamo ottenere lo stato sulla registrazione e non sulla registrazione.
set_training (is_training) Simile a is_traininig (), con l'aiuto di questo metodo possiamo impostare lo stato su training o previsione.
train_mode () Questo metodo restituirà un contesto di ambito da utilizzare nell'istruzione "with" in cui il comportamento del passaggio in avanti è impostato sulla modalità di addestramento e cioè senza modificare gli stati di registrazione.

Esempio di implementazione

Nell'esempio seguente, utilizzeremo il metodo mxnet.autograd.grad () per calcolare il gradiente di testa rispetto alle variabili -

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

L'output è menzionato di seguito:

[
[3.7182817 3.7182817]
<NDArray 2 @cpu(0)>]

Possiamo usare il metodo mxnet.autograd.predict_mode () per restituire uno scope da usare nell'istruzione 'with' -

with mx.autograd.record():
y = model(x)
with mx.autograd.predict_mode():
y = sampling(y)
backward([y])

mxnet.intializer

Questa è l'API di MXNet per l'inizializzatore di pesata. Ha le seguenti classi:

Classi e loro parametri

Di seguito sono riportati i metodi e i relativi parametri di mxnet.autogard.function classe:

Classi e suoi parametri Definizione
Bilineare () Con l'aiuto di questa classe possiamo inizializzare il peso per i layer di up-sampling.
Costante (valore) Questa classe inizializza i pesi su un dato valore. Il valore può essere sia scalare che NDArray che corrisponde alla forma del parametro da impostare.
FusedRNN (init, num_hidden, num_layers, modalità) Come suggerisce il nome, questa classe inizializza i parametri per i layer RNN (Recurrent Neural Network) fusi.
InitDesc Agisce come descrittore per il modello di inizializzazione.
Inizializzatore (** kwargs) Questa è la classe base di un inizializzatore.
LSTMBias ([dimenticare_bias]) Questa classe inizializza tutti i bias di un LSTMCell su 0.0 ma ad eccezione del dimenticare gate il cui bias è impostato su un valore personalizzato.
Carica (param [, default_init, verbose]) Questa classe inizializza le variabili caricando i dati dal file o dal dizionario.
MSRAPrelu ([factor_type, slope]) Come suggerisce il nome, questa classe Inizializza il peso secondo una carta MSRA.
Misto (modelli, inizializzatori) Inizializza i parametri utilizzando più inizializzatori.
Normale ([sigma]) La classe Normal () inizializza i pesi con valori casuali campionati da una distribuzione normale con media zero e deviazione standard (SD) di sigma.
Uno() Inizializza i pesi del parametro su uno.
Ortogonale ([scale, rand_type]) Come suggerisce il nome, questa classe inizializza il peso come matrice ortogonale.
Uniforme ([scale]) Inizializza i pesi con valori casuali che vengono campionati in modo uniforme da un determinato intervallo.
Xavier ([rnd_type, factor_type, magnitude]) In realtà restituisce un inizializzatore che esegue l'inizializzazione "Xavier" per i pesi.
Zero() Inizializza i pesi del parametro a zero.

Esempio di implementazione

Nell'esempio seguente, useremo la classe mxnet.init.Normal () per creare un inizializzatore e recuperare i suoi parametri -

init = mx.init.Normal(0.8)
init.dumps()

Output

L'output è fornito di seguito:

'["normal", {"sigma": 0.8}]'

Example

init = mx.init.Xavier(factor_type="in", magnitude=2.45)
init.dumps()

Output

L'output è mostrato di seguito:

'["xavier", {"rnd_type": "uniform", "factor_type": "in", "magnitude": 2.45}]'

Nell'esempio seguente, utilizzeremo la classe mxnet.initializer.Mixed () per inizializzare i parametri utilizzando più inizializzatori:

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

L'output è mostrato di seguito:

fullyconnected1_weight
[[ 0.0097627 0.01856892 0.04303787]]
fullyconnected1_bias
[ 0.]

In questo capitolo, impareremo a conoscere un'interfaccia in MXNet che viene definita Simbolo.

Mxnet.ndarray

L'API Symbol di Apache MXNet è un'interfaccia per la programmazione simbolica. L'API dei simboli offre l'uso di quanto segue:

  • Grafici computazionali

  • Utilizzo della memoria ridotto

  • Ottimizzazione della funzione pre-utilizzo

L'esempio riportato di seguito mostra come creare una semplice espressione utilizzando l'API dei simboli di MXNet:

Un NDArray utilizzando un 'array' 1-D e 2-D da un normale elenco Python -

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

Vedrai il seguente output:

<Symbol _plus0>

Example

(x, y, z)

Output

L'output è fornito di seguito:

(<Symbol x>, <Symbol y>, <Symbol _plus0>)

Ora discutiamo in dettaglio sulle classi, funzioni e parametri dell'API ndarray di MXNet.

Classi

La seguente tabella è composta dalle classi di Symbol API di MXNet -

Classe Definizione
Simbolo (maniglia) Questa classe, ovvero il simbolo, è il grafico simbolico di Apache MXNet.

Funzioni e loro parametri

Di seguito sono riportate alcune delle funzioni importanti e dei relativi parametri coperti da mxnet.Symbol API -

Funzione e suoi parametri Definizione
Attivazione ([data, act_type, out, name]) Applica una funzione di attivazione per elemento all'ingresso. Supportarelu, sigmoid, tanh, softrelu, softsign funzioni di attivazione.
BatchNorm ([dati, gamma, beta, moving_mean, ...]) Viene utilizzato per la normalizzazione batch. Questa funzione normalizza un batch di dati per media e varianza. Applica una scalagamma e offset beta.
BilinearSampler ([data, grid, cudnn_off,…]) Questa funzione applica il campionamento bilineare alla mappa delle caratteristiche di input. In realtà è la chiave di "Spatial Transformer Networks". Se hai familiarità con la funzione di rimappatura in OpenCV, l'utilizzo di questa funzione è abbastanza simile a quello. L'unica differenza è che ha il passaggio all'indietro.
BlockGrad ([data, out, name]) Come specificato dal nome, questa funzione interrompe il calcolo del gradiente. Fondamentalmente arresta il gradiente accumulato degli input dal fluire attraverso questo operatore all'indietro.
cast ([data, dtype, out, name]) Questa funzione eseguirà il cast di tutti gli elementi dell'input in un nuovo tipo.
Questa funzione eseguirà il cast di tutti gli elementi dell'input in un nuovo tipo. Questa funzione, come specificato dal nome, restituisce un nuovo simbolo di forma e tipo dati, riempito con zeri.
quelli (forma [, dtype]) Questa funzione, come specificato dal nome, restituisce un nuovo simbolo di una data forma e tipo, riempito con uno.
full (shape, val [, dtype]) Questa funzione, come il nome specificato, restituisce un nuovo array di forma e tipo dati, riempito con il valore dato val.
arange (start [, stop, step, repeat, ...]) Restituirà valori equidistanti entro un dato intervallo. I valori vengono generati all'interno dell'intervallo semiaperto [avvio, arresto), il che significa che l'intervallo includestart ma esclude stop.
linspace (start, stop, num [, endpoint, name, ...]) Restituirà numeri equidistanti entro un intervallo specificato. Simile alla funzione arrangia (), i valori vengono generati entro un intervallo semiaperto [start, stop), il che significa che l'intervallo includestart ma esclude stop.
istogramma (a [, bin, range]) Come suggerisce il nome, questa funzione calcolerà l'istogramma dei dati di input.
potenza (base, esp) Come suggerisce il nome, questa funzione restituirà il risultato in termini di elemento di base elemento elevato a potenze da expelemento. Entrambi gli input, ovvero base ed exp, possono essere Symbol o scalare. Nota che la trasmissione non è consentita. Puoi usarebroadcast_pow se vuoi usare la funzione di trasmissione.
SoftmaxActivation ([data, mode, name, attr, out]) Questa funzione applica l'attivazione softmax all'ingresso. È inteso per strati interni. In realtà è deprecato, possiamo usaresoftmax() anziché.

Esempi di implementazione

Nell'esempio seguente useremo la funzione power() che restituirà il risultato in termini di elemento dell'elemento base elevato alle potenze dell'elemento exp:

import mxnet as mx
mx.sym.power(3, 5)

Output

Vedrai il seguente output:

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

Questo produce il seguente output:

array([1., 8.], dtype=float32)

Example

z = mx.sym.power(4, y)
z.eval(y=mx.nd.array([2,3]))[0].asnumpy()

Output

Quando esegui il codice sopra, dovresti vedere il seguente output:

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

L'output è menzionato di seguito:

array([ 16., 125.], dtype=float32)

Nell'esempio riportato di seguito, utilizzeremo la funzione SoftmaxActivation() (or softmax()) che verrà applicato all'input ed è inteso per i livelli interni.

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

Vedrai il seguente output:

[[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]]

symbol.contrib

L'API Contrib NDArray è definita nel pacchetto symbol.contrib. In genere fornisce molte API sperimentali utili per nuove funzionalità. Questa API funziona come un luogo per la comunità in cui possono provare le nuove funzionalità. Anche il collaboratore della funzione riceverà il feedback.

Funzioni e loro parametri

Di seguito sono riportate alcune delle funzioni importanti e dei relativi parametri coperti da mxnet.symbol.contrib API -

Funzione e suoi parametri Definizione
rand_zipfian (true_classes, num_sampled, ...) Questa funzione estrae campioni casuali da una distribuzione approssimativamente Zipfian. La distribuzione di base di questa funzione è la distribuzione Zipfian. Questa funzione campiona casualmente num_sampled candidati e gli elementi di sampled_candidates vengono estratti dalla distribuzione di base data sopra.
foreach (body, data, init_states) Come suggerisce il nome, questa funzione esegue un ciclo con il calcolo definito dall'utente su NDArrays sulla dimensione 0. Questa funzione simula un ciclo for e il corpo ha il calcolo per un'iterazione del ciclo for.
while_loop (cond, func, loop_vars [,…]) Come suggerisce il nome, questa funzione esegue un ciclo while con calcoli definiti dall'utente e condizioni di ciclo. Questa funzione simula un ciclo while che letteralmente esegue calcoli personalizzati se la condizione è soddisfatta.
cond (pred, then_func, else_func) Come suggerisce il nome, questa funzione esegue un if-then-else utilizzando condizioni e calcoli definiti dall'utente. Questa funzione simula un ramo if-like che sceglie di eseguire uno dei due calcoli personalizzati in base alla condizione specificata.
getnnz ([dati, asse, uscita, nome]) Questa funzione ci fornisce il numero di valori memorizzati per un tensore sparso. Include anche zeri espliciti. Supporta solo la matrice CSR sulla CPU.
riquantizza ([dati, intervallo_min, intervallo_max, ...]) Questa funzione riquantizza i dati forniti che vengono quantizzati in int32 e le soglie corrispondenti, in int8 utilizzando le soglie min e max calcolate in fase di esecuzione o dalla calibrazione.
index_copy ([old_tensor, index_vector,…]) Questa funzione copia gli elementi di un file 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 ([query,…]) Questo operatore calcola la moltiplicazione della matrice tra le proiezioni di query e chiavi nell'uso dell'attenzione multi-head come codificatore-decodificatore. La condizione è che gli input siano un tensore delle proiezioni delle query che segue il layout: (seq_length, batch_size, num_heads *, head_dim).

Esempi di implementazione

Nell'esempio seguente useremo la funzione rand_zipfian per disegnare campioni casuali da una distribuzione approssimativamente Zipfian -

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

Vedrai il seguente output:

array([4, 0, 2, 1, 5], dtype=int64)

Example

exp_count_true.eval(true_cls=mx.nd.array([3]))[0].asnumpy()

Output

L'output è menzionato di seguito:

array([0.57336551])

Example

exp_count_sample.eval(true_cls=mx.nd.array([3]))[0].asnumpy()

Output

Vedrai il seguente output:

array([1.78103594, 0.46847373, 1.04183923, 0.57336551, 1.04183923])

Nell'esempio seguente useremo la funzione while_loop per eseguire un ciclo while per il calcolo definito dall'utente e la condizione del ciclo -

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

L'output è fornito di seguito:

[<Symbol _while_loop0>]

Example

Print(States)

Output

Questo produce il seguente output:

[<Symbol _while_loop0>, <Symbol _while_loop0>]

Nell'esempio seguente useremo la funzione index_copy che copia gli elementi di new_tensor in 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

Quando esegui il codice sopra, dovresti vedere il seguente output:

[[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 dei simboli immagine è definita nel pacchetto symbol.image. Come suggerisce il nome, viene tipicamente utilizzato per le immagini e le loro caratteristiche.

Funzioni e loro parametri

Di seguito sono riportate alcune delle funzioni importanti e dei relativi parametri coperti da mxnet.symbol.image API -

Funzione e suoi parametri Definizione
Adjust_lighting ([data, alpha, out, name]) Come suggerisce il nome, questa funzione regola il livello di illuminazione dell'ingresso. Segue lo stile AlexNet.
ritaglio ([dati, x, y, larghezza, altezza, fuori, nome]) Con l'aiuto di questa funzione possiamo ritagliare un'immagine NDArray di forma (H x W x C) o (N x H x W x C) alla dimensione fornita dall'utente.
normalizzare ([data, mean, std, out, name]) Normalizzerà un tensore di forma (C x H x W) o (N x C x H x L) con mean e standard deviation(SD).
random_crop ([data, xrange, yrange, width, ...]) Simile a crop (), ritaglia in modo casuale un'immagine NDArray di forma (H x L x C) o (N x H x L x C) alla dimensione fornita dall'utente. Sovracampiona il risultato sesrc è più piccolo di size.
random_lighting([data, alpha_std, out, name]) Come suggerisce il nome, questa funzione aggiunge il rumore PCA in modo casuale. Segue anche lo stile AlexNet.
random_resized_crop ([data, xrange, yrange, ...]) Ritaglia anche un'immagine in modo casuale NDArray di forma (H x L x C) o (N x H x L x C) alla dimensione data. Sovracampiona il risultato se src è più piccolo della dimensione. Inoltre randomizzerà anche l'area e le proporzioni.
ridimensiona ([data, size, keep_ratio, interp, ...]) Come suggerisce il nome, questa funzione ridimensionerà un'immagine NDArray di forma (H x W x C) o (N x H x L x C) alla dimensione fornita dall'utente.
to_tensor ([data, out, name]) Converte un'immagine NDArray di forma (H x W x C) o (N x H x W x C) con i valori nell'intervallo [0, 255] in un tensore NDArray di forma (C x H x W) o ( N x C x H x W) con i valori nell'intervallo [0, 1].

Esempi di implementazione

Nell'esempio seguente, utilizzeremo la funzione to_tensor per convertire l'immagine NDArray di forma (H x L x C) o (N x H x L x C) con i valori nell'intervallo [0, 255] in un tensore NDArray di forma (C x H x W) o (N x C x H x L) con i valori nell'intervallo [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

L'output è indicato di seguito:

<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

L'output è menzionato di seguito:

<Symbol to_tensor5>

Nell'esempio seguente, useremo la funzione normalize () per normalizzare un tensore di forma (C x H x W) o (N x C x H x W) con mean e 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

Di seguito è riportato l'output del codice:

<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

L'output è mostrato di seguito:

<Symbol normalize1>

symbol.random

L'API Random Symbol è definita nel pacchetto symbol.random. Come suggerisce il nome, è un generatore di distribuzione casuale Symbol API di MXNet.

Funzioni e loro parametri

Di seguito sono riportate alcune delle funzioni importanti e dei relativi parametri coperti da mxnet.symbol.random API -

Funzione e suoi parametri Definizione
uniforme ([low, high, shape, dtype, ctx, out]) Genera campioni casuali da una distribuzione uniforme.
normale ([loc, scale, shape, dtype, ctx, out]) Genera campioni casuali da una distribuzione normale (gaussiana).
randn (* forma, ** kwargs) Genera campioni casuali da una distribuzione normale (gaussiana).
poisson ([lam, shape, dtype, ctx, out]) Genera campioni casuali da una distribuzione di Poisson.
esponenziale ([scale, shape, dtype, ctx, out]) Genera campioni da una distribuzione esponenziale.
gamma ([alpha, beta, shape, dtype, ctx, out]) Genera campioni casuali da una distribuzione gamma.
multinomiale (data [, shape, get_prob, out, dtype]) Genera campionamento simultaneo da più distribuzioni multinomiali.
negativo_binomiale ([k, p, forma, dtype, ctx, out]) Genera campioni casuali da una distribuzione binomiale negativa.
generalized_negative_binomial ([mu, alpha,…]) Genera campioni casuali da una distribuzione binomiale negativa generalizzata.
shuffle (dati, ** kwargs) Mescola gli elementi in modo casuale.
randint (basso, alto [, forma, dtype, ctx, out]) Genera campioni casuali da una distribuzione uniforme discreta.
exponential_like ([data, lam, out, name]) Genera campioni casuali da una distribuzione esponenziale in base alla forma dell'array di input.
gamma_like ([data, alpha, beta, out, name]) Genera campioni casuali da una distribuzione gamma in base alla forma dell'array di input.
generalized_negative_binomial_like ([data,…]) Genera campioni casuali da una distribuzione binomiale negativa generalizzata in base alla forma dell'array di input.
negative_binomial_like ([data, k, p, out, name]) Genera campioni casuali da una distribuzione binomiale negativa in base alla forma dell'array di input.
normal_like ([data, loc, scale, out, name]) Genera campioni casuali da una distribuzione normale (gaussiana) in base alla forma dell'array di input.
poisson_like ([data, lam, out, name]) Genera campioni casuali da una distribuzione di Poisson in base alla forma dell'array di input.
uniform_like ([data, low, high, out, name]) Genera campioni casuali da una distribuzione uniforme in base alla forma dell'array di input.

Esempi di implementazione

Nell'esempio seguente, mescoleremo gli elementi in modo casuale utilizzando la funzione shuffle (). Mescolerà l'array lungo il primo asse.

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

Vedrai il seguente output:

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

Example

y.eval(x=data)

Output

Quando esegui il codice sopra, dovresti vedere il seguente output:

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

Nell'esempio seguente, trarremo campioni casuali da una distribuzione binomiale negativa generalizzata. Per questo utilizzerà la funzionegeneralized_negative_binomial().

mx.sym.random.generalized_negative_binomial(10, 0.1)

Output

L'output è fornito di seguito:

<Symbol _random_generalized_negative_binomial0>

symbol.sparse

L'API dei simboli sparse è definita nel pacchetto mxnet.symbol.sparse. Come suggerisce il nome, fornisce grafici di rete neurale sparsi e auto-differenziazione sulla CPU.

Funzioni e loro parametri

Di seguito sono riportate alcune delle funzioni importanti (include routine per la creazione di simboli, routine di manipolazione dei simboli, funzioni matematiche, funzione trigonometrica, funzioni iberboliche, funzioni di riduzione, arrotondamento, poteri, rete neurale) e relativi parametri coperti da mxnet.symbol.sparse API -

Funzione e suoi parametri Definizione
ElementWiseSum (* args, ** kwargs) Questa funzione aggiungerà tutti gli argomenti di input in base agli elementi. Ad esempio, _ (1,2,… = 1 + 2 + ⋯ +). Qui, possiamo vedere che add_n è potenzialmente più efficiente della chiamata add by n volte.
Incorporamento ([data, weight, input_dim, ...]) Mapperà gli indici interi su rappresentazioni vettoriali, ovvero incorporamenti. In realtà mappa le parole su vettori di valore reale nello spazio ad alta dimensione che è chiamato word embedding.
LinearRegressionOutput ([data, label, ...]) Calcola e ottimizza la perdita al quadrato durante la propagazione all'indietro fornendo solo i dati di output durante la propagazione in avanti.
LogisticRegressionOutput ([data, label, ...]) Applica all'ingresso una funzione logistica chiamata anche funzione sigmoide. La funzione è calcolata come 1/1 + exp (−x).
MAERegressionOutput ([data, label, ...]) Questo operatore calcola l'errore assoluto medio dell'input. MAE è in realtà una metrica di rischio corrispondente al valore atteso dell'errore assoluto.
abs ([data, name, attr, out]) Come suggerisce il nome, questa funzione restituirà il valore assoluto dell'input in termini di elemento.
adagrad_update ([weight, grad, history, lr, ...]) È una funzione di aggiornamento per AdaGrad optimizer.
adam_update ([weight, grad, mean, var, lr,…]) È una funzione di aggiornamento per Adam optimizer.
add_n (* args, ** kwargs) Come suggerisce il nome, aggiungerà tutti gli argomenti di input per elemento.
arccos ([data, name, attr, out]) Questa funzione restituirà il coseno inverso rispetto agli elementi della matrice di input.
punto ([lhs, rhs, transpose_a, transpose_b, ...]) Come suggerisce il nome, darà il prodotto scalare di due array. Dipenderà dalla dimensione della matrice di input: 1-D: prodotto interno dei vettori 2-D: moltiplicazione di matrici ND: un prodotto somma sull'ultimo asse del primo input e sul primo asse del secondo input.
elemwise_add ([lhs, rhs, name, attr, out]) Come suggerisce il nome, lo farà add argomento saggio elemento.
elemwise_div ([lhs, rhs, name, attr, out]) Come suggerisce il nome, lo farà divide argomento saggio elemento.
elemwise_mul ([lhs, rhs, name, attr, out]) Come suggerisce il nome, lo farà Multiply argomento saggio elemento.
elemwise_sub ([lhs, rhs, name, attr, out]) Come suggerisce il nome, sottrarrà gli argomenti in base agli elementi.
exp ([data, name, attr, out]) Questa funzione restituirà il valore esponenziale saggio dell'elemento dell'input fornito.
sgd_update ([weight, grad, lr, wd, ...]) Agisce come una funzione di aggiornamento per l'ottimizzatore Stochastic Gradient Descent.
sigmoid ([data, name, attr, out]) Come suggerisce il nome, calcolerà sigmoid di x elemento saggio.
sign ([data, name, attr, out]) Restituirà il segno saggio dell'elemento dell'input fornito.
sin ([data, name, attr, out]) Come suggerisce il nome, questa funzione calcolerà il seno saggio dell'elemento dell'array di input specificato.

Esempio di implementazione

Nell'esempio seguente, mescoleremo gli elementi in modo casuale usando ElementWiseSum()funzione. Mapperà gli indici interi a rappresentazioni vettoriali, ad esempio incorporamenti di parole.

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 del modulo di Apache MXNet è come un modello FeedForward ed è più facile comporre simile al modulo Torch. Consiste delle seguenti classi:

BaseModule ([logger])

Rappresenta la classe base di un modulo. Un modulo può essere pensato come un componente di calcolo o una macchina di calcolo. Il compito di un modulo è eseguire passaggi avanti e indietro. Aggiorna anche i parametri in un modello.

Metodi

La tabella seguente mostra i metodi in cui consistevano BaseModule class-

Questo metodo otterrà gli stati da tutti i dispositivi
Metodi Definizione
indietro ([out_grads]) Come suggerisce il nome, questo metodo implementa il backward calcolo.
bind (data_shapes [, label_shapes,…]) Associa i simboli per costruire esecutori ed è necessario prima di poter eseguire calcoli con il modulo.
adatta (train_data [, eval_data, eval_metric,…]) Questo metodo addestra i parametri del modulo.
avanti (data_batch [, is_train]) Come suggerisce il nome, questo metodo implementa il calcolo Forward. Questo metodo supporta batch di dati con varie forme come diverse dimensioni di batch o diverse dimensioni di immagine.
forward_backward (data_batch) È una funzione comoda, come suggerisce il nome, che chiama sia in avanti che all'indietro.
get_input_grads ([merge_multi_context]) Questo metodo porterà i gradienti agli input che vengono calcolati nel precedente calcolo all'indietro.
get_outputs ([merge_multi_context]) Come suggerisce il nome, questo metodo otterrà gli output del precedente calcolo in avanti.
get_params () Ottiene i parametri, in particolare quelli che sono potenzialmente copie dei parametri effettivi utilizzati per eseguire il calcolo sul dispositivo.
get_states ([merge_multi_context])
init_optimizer ([kvstore, optimizer, ...]) Questo metodo installa e inizializza gli ottimizzatori. Inoltre si inizializzakvstore per distribuire la formazione.
init_params ([inizializzatore, arg_params, ...]) Come suggerisce il nome, questo metodo inizializzerà i parametri e gli stati ausiliari.
install_monitor (lun) Questo metodo installerà il monitor su tutti gli esecutori.
iter_predict (eval_data [, num_batch, reset, ...]) Questo metodo itererà sulle previsioni.
load_params (fname) Come specificato dal nome, caricherà i parametri del modello dal file.
prevedere (eval_data [, num_batch,…]) Eseguirà la previsione e raccoglierà anche gli output.
preparare (data_batch [, sparse_row_id_fn]) L'operatore prepara il modulo per l'elaborazione di un dato batch di dati.
save_params (fname) Come specificato dal nome, questa funzione salverà i parametri del modello su file.
punteggio (eval_data, eval_metric [, num_batch,…]) Esegue la previsione eval_data e valuta anche le prestazioni in base al dato eval_metric.
set_params (arg_params, aux_params [,…]) Questo metodo assegnerà i valori del parametro e dello stato ausiliario.
set_states ([states, value]) Questo metodo, come suggerisce il nome, imposta il valore per gli stati.
aggiornare() Questo metodo aggiorna i parametri forniti in base all'ottimizzatore installato. Aggiorna anche i gradienti calcolati nel precedente batch avanti-indietro.
update_metric (eval_metric, etichette [, pre_sliced]) Questo metodo, come suggerisce il nome, valuta e accumula la metrica di valutazione sugli output dell'ultimo calcolo in avanti.
indietro ([out_grads]) Come suggerisce il nome, questo metodo implementa il backward calcolo.
bind (data_shapes [, label_shapes,…]) Configura i bucket e associa l'esecutore alla chiave del bucket predefinita. Questo metodo rappresenta l'associazione per un fileBucketingModule.
avanti (data_batch [, is_train]) Come suggerisce il nome, questo metodo implementa il calcolo Forward. Questo metodo supporta batch di dati con varie forme come diverse dimensioni di batch o diverse dimensioni di immagine.
get_input_grads ([merge_multi_context]) Questo metodo porterà i gradienti agli input che sono calcolati nel precedente calcolo all'indietro.
get_outputs ([merge_multi_context]) Come suggerisce il nome, questo metodo otterrà gli output dal precedente calcolo in avanti.
get_params () Ottiene i parametri correnti, in particolare quelli che sono potenzialmente copie dei parametri effettivi utilizzati per eseguire il calcolo sul dispositivo.
get_states ([merge_multi_context]) Questo metodo otterrà gli stati da tutti i dispositivi.
init_optimizer ([kvstore, optimizer, ...]) Questo metodo installa e inizializza gli ottimizzatori. Inoltre si inizializzakvstore per distribuire la formazione.
init_params ([inizializzatore, arg_params, ...]) Come suggerisce il nome, questo metodo inizializzerà i parametri e gli stati ausiliari.
install_monitor (lun) Questo metodo installerà il monitor su tutti gli esecutori.
caricamento (prefisso, epoch [, sym_gen, ...]) Questo metodo creerà un modello dal checkpoint salvato in precedenza.
load_dict ([sym_dict, sym_gen,…]) Questo metodo creerà un modello da una mappatura del dizionario (dict) bucket_keyai simboli. Condivide anchearg_params e aux_params.
preparare (data_batch [, sparse_row_id_fn]) L'operatore prepara il modulo per l'elaborazione di un dato batch di dati.
save_checkpoint (prefix, epoch [, remove_amp_cast]) Questo metodo, come suggerisce il nome, salva l'avanzamento corrente nel checkpoint per tutti i bucket in BucketingModule. Si consiglia di utilizzare mx.callback.module_checkpoint come epoch_end_callback per salvare durante l'addestramento.
set_params (arg_params, aux_params [,…]) Come specificato dal nome, questa funzione assegnerà parametri e valori di stato ausiliario.
set_states ([states, value]) Questo metodo, come suggerisce il nome, imposta il valore per gli stati.
switch_bucket (bucket_key, data_shapes [,…]) Passerà a un secchio diverso.
aggiornare() Questo metodo aggiorna i parametri forniti in base all'ottimizzatore installato. Aggiorna anche i gradienti calcolati nel precedente batch avanti-indietro.
update_metric (eval_metric, etichette [, pre_sliced]) Questo metodo, come suggerisce il nome, valuta e accumula la metrica di valutazione sugli output dell'ultimo calcolo in avanti.

Attributi

La tabella seguente mostra gli attributi consistenti nei metodi di BaseModule classe -

Attributi Definizione
data_names Consiste nella lista dei nomi per i dati richiesti da questo modulo.
data_shapes Consiste dell'elenco di coppie (nome, forma) che specificano i dati in ingresso a questo modulo.
label_shapes Mostra l'elenco delle coppie (nome, forma) che specificano gli input dell'etichetta per questo modulo.
output_names Consiste nella lista dei nomi per le uscite di questo modulo.
output_shapes Consiste nella lista di (nome, forma) coppie che specificano gli output di questo modulo.
simbolo Come il nome specificato, questo attributo ottiene il simbolo associato a questo modulo.

data_shapes: puoi fare riferimento al link disponibile su https://mxnet.apache.orgper dettagli. output_shapes: Altro

output_shapes: ulteriori informazioni sono disponibili all'indirizzo https://mxnet.apache.org/api/python

BucketingModule (sym_gen […])

Rappresenta il Bucketingmodule classe di un modulo che aiuta a gestire in modo efficiente input di lunghezza variabile.

Metodi

La tabella seguente mostra i metodi in cui consistevano BucketingModule class -

Attributi

La tabella seguente mostra gli attributi consistenti nei metodi di BaseModule class -

Attributi Definizione
data_names Consiste nella lista dei nomi per i dati richiesti da questo modulo.
data_shapes Consiste dell'elenco di coppie (nome, forma) che specificano i dati in ingresso a questo modulo.
label_shapes Mostra l'elenco delle coppie (nome, forma) che specificano gli input dell'etichetta per questo modulo.
output_names Consiste nella lista dei nomi per le uscite di questo modulo.
output_shapes Consiste nella lista di (nome, forma) coppie che specificano gli output di questo modulo.
Simbolo Come il nome specificato, questo attributo ottiene il simbolo associato a questo modulo.

data_shapes - Puoi fare riferimento al collegamento all'indirizzo https://mxnet.apache.org/api/python/docs per maggiori informazioni.

output_shapes - Puoi fare riferimento al collegamento a https://mxnet.apache.org/api/python/docs per maggiori informazioni.

Modulo (simbolo [, data_names, label_names, ...])

Rappresenta un modulo di base che avvolge un file symbol.

Metodi

La tabella seguente mostra i metodi in cui consistevano Module class -

Metodi Definizione
indietro ([out_grads]) Come suggerisce il nome, questo metodo implementa il backward calcolo.
bind (data_shapes [, label_shapes,…]) Associa i simboli per costruire esecutori ed è necessario prima di poter eseguire calcoli con il modulo.
prestiti_optimizer (shared_module) Come suggerisce il nome, questo metodo prenderà in prestito l'ottimizzatore da un modulo condiviso.
avanti (data_batch [, is_train]) Come suggerisce il nome, questo metodo implementa il Forwardcalcolo. Questo metodo supporta batch di dati con varie forme come diverse dimensioni di batch o diverse dimensioni di immagine.
get_input_grads ([merge_multi_context]) Questo metodo porterà i gradienti agli input che vengono calcolati nel precedente calcolo all'indietro.
get_outputs ([merge_multi_context]) Come suggerisce il nome, questo metodo otterrà gli output del precedente calcolo in avanti.
get_params () Ottiene i parametri, in particolare quelli che sono potenzialmente copie dei parametri effettivi utilizzati per eseguire il calcolo sul dispositivo.
get_states ([merge_multi_context]) Questo metodo otterrà gli stati da tutti i dispositivi
init_optimizer ([kvstore, optimizer, ...]) Questo metodo installa e inizializza gli ottimizzatori. Inoltre si inizializzakvstore per distribuire la formazione.
init_params ([inizializzatore, arg_params, ...]) Come suggerisce il nome, questo metodo inizializzerà i parametri e gli stati ausiliari.
install_monitor (lun) Questo metodo installerà il monitor su tutti gli esecutori.
caricamento (prefisso, epoch [, sym_gen, ...]) Questo metodo creerà un modello dal checkpoint salvato in precedenza.
load_optimizer_states (fname) Questo metodo caricherà un ottimizzatore, ovvero lo stato del programma di aggiornamento da un file.
preparare (data_batch [, sparse_row_id_fn]) L'operatore prepara il modulo per l'elaborazione di un dato batch di dati.
rimodellare (data_shapes [, label_shapes]) Questo metodo, come suggerisce il nome, rimodella il modulo per nuove forme di input.
save_checkpoint (prefix, epoch [,…]) Salva lo stato di avanzamento corrente al checkpoint.
save_optimizer_states (fname) Questo metodo salva l'ottimizzatore o lo stato del programma di aggiornamento in un file.
set_params (arg_params, aux_params [,…]) Come specificato dal nome, questa funzione assegnerà parametri e valori di stato ausiliario.
set_states ([states, value]) Questo metodo, come suggerisce il nome, imposta il valore per gli stati.
aggiornare() Questo metodo aggiorna i parametri forniti in base all'ottimizzatore installato. Aggiorna anche i gradienti calcolati nel precedente batch avanti-indietro.
update_metric (eval_metric, etichette [, pre_sliced]) Questo metodo, come suggerisce il nome, valuta e accumula la metrica di valutazione sugli output dell'ultimo calcolo in avanti.

Attributi

La tabella seguente mostra gli attributi consistenti nei metodi di Module class -

Attributi Definizione
data_names Consiste nella lista dei nomi per i dati richiesti da questo modulo.
data_shapes Consiste dell'elenco di coppie (nome, forma) che specificano i dati in ingresso a questo modulo.
label_shapes Mostra l'elenco delle coppie (nome, forma) che specificano gli input dell'etichetta per questo modulo.
output_names Consiste nella lista dei nomi per le uscite di questo modulo.
output_shapes Consiste nella lista di (nome, forma) coppie che specificano gli output di questo modulo.
label_names Consiste dell'elenco di nomi per le etichette richieste da questo modulo.

data_shapes: visita il link https://mxnet.apache.org/api/python/docs/api/module per ulteriori dettagli.

output_shapes: il collegamento fornito con la presente https://mxnet.apache.org/api/python/docs/api/module/index.html offrirà altre importanti informazioni.

PythonLossModule ([name, data_names, ...])

La base di questa classe è mxnet.module.python_module.PythonModule. La classe PythonLossModule è una comoda classe di moduli che implementa tutte o molte delle API del modulo come funzioni vuote.

Metodi

La tabella seguente mostra i metodi in cui consistevano PythonLossModule classe:

Metodi Definizione
indietro ([out_grads]) Come suggerisce il nome, questo metodo implementa il backward calcolo.
avanti (data_batch [, is_train]) Come suggerisce il nome, questo metodo implementa il Forwardcalcolo. Questo metodo supporta batch di dati con varie forme come diverse dimensioni di batch o diverse dimensioni di immagine.
get_input_grads ([merge_multi_context]) Questo metodo porterà i gradienti agli input che vengono calcolati nel precedente calcolo all'indietro.
get_outputs ([merge_multi_context]) Come suggerisce il nome, questo metodo otterrà gli output del precedente calcolo in avanti.
install_monitor (lun) Questo metodo installerà il monitor su tutti gli esecutori.

PythonModule ([data_names, label_names…])

La base di questa classe è mxnet.module.base_module.BaseModule. La classe PythonModule è anche una comoda classe del modulo che implementa tutte o molte delle API del modulo come funzioni vuote.

Metodi

La tabella seguente mostra i metodi in cui consistevano PythonModule classe -

Metodi Definizione
bind (data_shapes [, label_shapes,…]) Associa i simboli per costruire esecutori ed è necessario prima di poter eseguire calcoli con il modulo.
get_params () Ottiene i parametri, in particolare quelli che sono potenzialmente copie dei parametri effettivi utilizzati per eseguire il calcolo sul dispositivo.
init_optimizer ([kvstore, optimizer, ...]) Questo metodo installa e inizializza gli ottimizzatori. Inoltre si inizializzakvstore per distribuire la formazione.
init_params ([inizializzatore, arg_params, ...]) Come suggerisce il nome, questo metodo inizializzerà i parametri e gli stati ausiliari.
aggiornare() Questo metodo aggiorna i parametri forniti in base all'ottimizzatore installato. Aggiorna anche i gradienti calcolati nel precedente batch avanti-indietro.
update_metric (eval_metric, etichette [, pre_sliced]) Questo metodo, come suggerisce il nome, valuta e accumula la metrica di valutazione sugli output dell'ultimo calcolo in avanti.

Attributi

La tabella seguente mostra gli attributi consistenti nei metodi di PythonModule classe -

Attributi Definizione
data_names Consiste nella lista dei nomi per i dati richiesti da questo modulo.
data_shapes Consiste dell'elenco di coppie (nome, forma) che specificano i dati in ingresso a questo modulo.
label_shapes Mostra l'elenco delle coppie (nome, forma) che specificano gli input dell'etichetta per questo modulo.
output_names Consiste nella lista dei nomi per le uscite di questo modulo.
output_shapes Consiste nella lista di (nome, forma) coppie che specificano gli output di questo modulo.

data_shapes - Segui il link https://mxnet.apache.org per dettagli.

output_shapes - Per ulteriori dettagli, visitare il collegamento disponibile all'indirizzo https://mxnet.apache.org

SequentialModule ([logger])

La base di questa classe è mxnet.module.base_module.BaseModule. La classe SequentialModule è anche un modulo contenitore che può concatenare più di due (più) moduli insieme.

Metodi

La tabella seguente mostra i metodi in cui consistevano SequentialModule classe

Metodi Definizione
aggiungi (modulo, ** kwargs) Questa è la funzione più importante di questa classe. Aggiunge un modulo alla catena.
indietro ([out_grads]) Come suggerisce il nome, questo metodo implementa il calcolo all'indietro.
bind (data_shapes [, label_shapes,…]) Associa i simboli per costruire esecutori ed è necessario prima di poter eseguire calcoli con il modulo.
avanti (data_batch [, is_train]) Come suggerisce il nome, questo metodo implementa il calcolo Forward. Questo metodo supporta batch di dati con varie forme come diverse dimensioni di batch o diverse dimensioni di immagine.
get_input_grads ([merge_multi_context]) Questo metodo porterà i gradienti agli input che vengono calcolati nel precedente calcolo all'indietro.
get_outputs ([merge_multi_context]) Come suggerisce il nome, questo metodo otterrà gli output del precedente calcolo in avanti.
get_params () Ottiene i parametri, in particolare quelli che sono potenzialmente copie dei parametri effettivi utilizzati per eseguire il calcolo sul dispositivo.
init_optimizer ([kvstore, optimizer, ...]) Questo metodo installa e inizializza gli ottimizzatori. Inoltre si inizializzakvstore per distribuire la formazione.
init_params ([inizializzatore, arg_params, ...]) Come suggerisce il nome, questo metodo inizializzerà i parametri e gli stati ausiliari.
install_monitor (lun) Questo metodo installerà il monitor su tutti gli esecutori.
aggiornare() Questo metodo aggiorna i parametri forniti in base all'ottimizzatore installato. Aggiorna anche i gradienti calcolati nel precedente batch avanti-indietro.
update_metric (eval_metric, etichette [, pre_sliced]) Questo metodo, come suggerisce il nome, valuta e accumula la metrica di valutazione sugli output dell'ultimo calcolo in avanti.

Attributi

La tabella seguente mostra gli attributi consistenti nei metodi della classe BaseModule -

Attributi Definizione
data_names Consiste nella lista dei nomi per i dati richiesti da questo modulo.
data_shapes Consiste dell'elenco di coppie (nome, forma) che specificano i dati in ingresso a questo modulo.
label_shapes Mostra l'elenco delle coppie (nome, forma) che specificano gli input dell'etichetta per questo modulo.
output_names Consiste nella lista dei nomi per le uscite di questo modulo.
output_shapes Consiste nella lista di (nome, forma) coppie che specificano gli output di questo modulo.
output_shapes Consiste nella lista di (nome, forma) coppie che specificano gli output di questo modulo.

data_shapes - Il link qui fornito https://mxnet.apache.org ti aiuterà a comprendere l'attributo in modo molto dettagliato.

output_shapes - Segui il link disponibile su https://mxnet.apache.org/api per dettagli.

Esempi di implementazione

Nell'esempio seguente, creeremo un file mxnet modulo.

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

L'output è menzionato di seguito:

<Symbol softmax>

Example

print(mod)

Output

L'output è mostrato di seguito:

<mxnet.module.module.Module object at 0x00000123A9892F28>

In questo esempio di seguito, implementeremo il calcolo in avanti

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

Quando esegui il codice sopra, dovresti vedere il seguente output:

[[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

Di seguito è riportato l'output del codice:

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