Apache MXNet - Pacotes Python

Neste capítulo, aprenderemos sobre os pacotes Python disponíveis no Apache MXNet.

Pacotes importantes do MXNet Python

MXNet tem os seguintes pacotes Python importantes, que discutiremos um por um -

  • Autograd (diferenciação automática)

  • NDArray

  • KVStore

  • Gluon

  • Visualization

Primeiro vamos começar com Autograd Pacote Python para Apache MXNet.

Autograd

Autograd apoia automatic differentiationusado para retropropagar os gradientes da métrica de perda de volta para cada um dos parâmetros. Junto com a retropropagação, ele usa uma abordagem de programação dinâmica para calcular os gradientes com eficiência. É também chamado de diferenciação automática de modo reverso. Esta técnica é muito eficiente em situações de 'fan-in' onde muitos parâmetros afetam uma única métrica de perda.

O que são gradientes?

Os gradientes são os fundamentos do processo de treinamento da rede neural. Basicamente, eles nos dizem como alterar os parâmetros da rede para melhorar seu desempenho.

Como sabemos, as redes neurais (NN) são compostas por operadores como somas, produto, convoluções, etc. Esses operadores, para seus cálculos, utilizam parâmetros como os pesos em núcleos de convolução. Devemos ter que encontrar os valores ideais para esses parâmetros e gradientes nos mostra o caminho e nos leva à solução também.

Estamos interessados ​​no efeito da alteração de um parâmetro no desempenho da rede e os gradientes nos dizem o quanto uma determinada variável aumenta ou diminui quando alteramos uma variável da qual depende. O desempenho é geralmente definido usando uma métrica de perda que tentamos minimizar. Por exemplo, para a regressão, podemos tentar minimizarL2 perda entre nossas previsões e valor exato, ao passo que para classificação podemos minimizar o cross-entropy loss.

Depois de calcularmos o gradiente de cada parâmetro com referência à perda, podemos usar um otimizador, como a descida gradiente estocástica.

Como calcular gradientes?

Temos as seguintes opções para calcular gradientes -

  • Symbolic Differentiation- A primeira opção é a diferenciação simbólica, que calcula as fórmulas para cada gradiente. A desvantagem desse método é que ele levará rapidamente a fórmulas incrivelmente longas conforme a rede se torna mais profunda e as operadoras se tornam mais complexas.

  • Finite Differencing- Outra opção é usar a diferenciação finita que tenta pequenas diferenças em cada parâmetro e ver como a métrica de perda responde. A desvantagem desse método é que ele seria caro do ponto de vista computacional e pode ter uma precisão numérica pobre.

  • Automatic differentiation- A solução para as desvantagens dos métodos acima é usar a diferenciação automática para retropropagar os gradientes da métrica de perda de volta para cada um dos parâmetros. A propagação nos permite uma abordagem de programação dinâmica para calcular com eficiência os gradientes. Este método também é chamado de diferenciação automática no modo reverso.

Diferenciação automática (autograd)

Aqui, entenderemos em detalhes o funcionamento do autograd. Basicamente, funciona seguindo duas etapas -

Stage 1 - Esta fase é chamada ‘Forward Pass’de treinamento. Como o nome indica, nesta etapa ele cria o registro da operadora utilizado pela rede para fazer previsões e calcular a métrica de perda.

Stage 2 - Esta fase é chamada ‘Backward Pass’de treinamento. Como o nome indica, neste estágio ele funciona de trás para frente neste registro. Retrocedendo, avalia as derivadas parciais de cada operadora até o parâmetro da rede.

Vantagens do autograd

A seguir estão as vantagens de usar a diferenciação automática (autograd) -

  • Flexible- A flexibilidade que nos dá na hora de definir nossa rede é um dos grandes benefícios de usar o autograd. Podemos mudar as operações em cada iteração. Eles são chamados de gráficos dinâmicos, que são muito mais complexos de implementar em estruturas que requerem gráfico estático. O autogradado, mesmo nesses casos, ainda será capaz de retropropagar os gradientes corretamente.

  • Automatic- O autograd é automático, ou seja, as complexidades do procedimento de retropropagação são atendidas por ele para você. Precisamos apenas especificar quais gradientes estamos interessados ​​em calcular.

  • Efficient - O Autogard calcula os gradientes de forma muito eficiente.

  • Can use native Python control flow operators- Podemos usar os operadores de fluxo de controle nativos do Python, como if condition e while loop. O autograd ainda será capaz de retropropagar os gradientes de forma eficiente e correta.

Usando autograd no MXNet Gluon

Aqui, com a ajuda de um exemplo, veremos como podemos usar autograd em MXNet Gluon.

Exemplo de Implementação

No exemplo a seguir, implementaremos o modelo de regressão com duas camadas. Após a implementação, usaremos o autograd para calcular automaticamente o gradiente da perda com referência a cada um dos parâmetros de peso -

Primeiro importe o autogrard e outros pacotes necessários da seguinte forma -

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

Agora, precisamos definir a rede da seguinte maneira -

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

Agora precisamos definir a perda da seguinte forma -

loss_function = L2Loss()

Em seguida, precisamos criar os dados fictícios da seguinte maneira -

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

Agora, estamos prontos para nossa primeira passagem para frente pela rede. Queremos autograd para registrar o gráfico computacional para que possamos calcular os gradientes. Para isso, precisamos executar o código de rede no escopo deautograd.record contexto da seguinte forma -

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

Agora, estamos prontos para a passagem para trás, que começamos chamando o método para trás na quantidade de juros. A quantidade de interesse em nosso exemplo é perda porque estamos tentando calcular o gradiente de perda com referência aos parâmetros -

loss.backward()

Agora, temos gradientes para cada parâmetro da rede, que serão usados ​​pelo otimizador para atualizar o valor do parâmetro para melhorar o desempenho. Vamos verificar os gradientes da 1ª camada da seguinte forma -

N_net[0].weight.grad()

Output

A saída é a seguinte−

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

Exemplo de implementação completo

A seguir está o exemplo de implementação 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()