Apache MXNet - KVStore y visualización
Este capítulo trata sobre la visualización y los paquetes de Python KVStore.
Paquete KVStore
KV stores significa tienda de valor clave. Es un componente crítico que se utiliza para el entrenamiento con múltiples dispositivos. Es importante porque la comunicación de parámetros a través de dispositivos en una o varias máquinas se transmite a través de uno o más servidores con un KVStore para los parámetros.
Comprendamos el funcionamiento de KVStore con la ayuda de los siguientes puntos:
Cada valor en KVStore está representado por un key y un value.
A cada matriz de parámetros de la red se le asigna un key y los pesos de esa matriz de parámetros se refieren a value.
Después de eso, los nodos trabajadores pushgradientes después de procesar un lote. Ellos tambiénpull pesos actualizados antes de procesar un nuevo lote.
En palabras simples, podemos decir que KVStore es un lugar para compartir datos donde, cada dispositivo puede insertar y extraer datos.
Inserción y extracción de datos
KVStore se puede considerar como un único objeto compartido entre diferentes dispositivos, como GPU y computadoras, donde cada dispositivo puede ingresar y extraer datos.
Los siguientes son los pasos de implementación que deben seguir los dispositivos para insertar y extraer datos:
Pasos de implementación
Initialisation- El primer paso es inicializar los valores. Aquí, para nuestro ejemplo, inicializaremos un par (int, NDArray) en KVStrore y luego sacaremos los valores -
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
Esto produce la siguiente salida:
[[2. 2. 2.]
[2. 2. 2.]
[2. 2. 2.]]
Push, Aggregate, and Update - Una vez inicializado, podemos insertar un nuevo valor en KVStore con la misma forma que la clave -
kv.push(3, mx.nd.ones(shape)*8)
kv.pull(3, out = a)
print(a.asnumpy())
Output
La salida se da a continuación:
[[8. 8. 8.]
[8. 8. 8.]
[8. 8. 8.]]
Los datos utilizados para empujar se pueden almacenar en cualquier dispositivo, como GPU o computadoras. También podemos insertar varios valores en la misma clave. En este caso, KVStore primero sumará todos estos valores y luego enviará el valor agregado de la siguiente manera:
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
Verá la siguiente salida:
[[4. 4. 4.]
[4. 4. 4.]
[4. 4. 4.]]
Para cada envío que haya aplicado, KVStore combinará el valor enviado con el valor ya almacenado. Se hará con la ayuda de un actualizador. Aquí, el actualizador predeterminado es ASIGNAR.
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
Cuando ejecute el código anterior, debería ver el siguiente resultado:
[[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
A continuación se muestra la salida del código:
update on key: 3
[[6. 6. 6.]
[6. 6. 6.]
[6. 6. 6.]]
Pull - Al igual que Push, también podemos extraer el valor en varios dispositivos con una sola llamada de la siguiente manera:
b = [mx.nd.ones(shape, ctx) for ctx in contexts]
kv.pull(3, out = b)
print(b[1].asnumpy())
Output
La salida se indica a continuación:
[[6. 6. 6.]
[6. 6. 6.]
[6. 6. 6.]]
Ejemplo de implementación completo
A continuación se muestra el ejemplo de implementación 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())
Manejo de pares clave-valor
Todas las operaciones que hemos implementado anteriormente implican una sola clave, pero KVStore también proporciona una interfaz para a list of key-value pairs -
Para un solo dispositivo
A continuación, se muestra un ejemplo para mostrar una interfaz KVStore para una lista de pares clave-valor para un solo 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
Recibirá el siguiente resultado:
update on key: 5
update on key: 7
update on key: 9
[[3. 3. 3.]
[3. 3. 3.]
[3. 3. 3.]]
Para varios dispositivos
A continuación se muestra un ejemplo para mostrar una interfaz de KVStore para una lista de pares clave-valor para varios dispositivos:
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
Verá la siguiente salida:
update on key: 5
update on key: 7
update on key: 9
[[11. 11. 11.]
[11. 11. 11.]
[11. 11. 11.]]
Paquete de visualización
El paquete de visualización es el paquete Apache MXNet que se utiliza para representar la red neuronal (NN) como un gráfico de cálculo que consta de nodos y bordes.
Visualice la red neuronal
En el siguiente ejemplo usaremos mx.viz.plot_networkpara visualizar la red neuronal. Los siguientes son los requisitos previos para esto:
Prerequisites
Cuaderno Jupyter
Biblioteca Graphviz
Ejemplo de implementación
En el siguiente ejemplo, visualizaremos una muestra NN para la factorización de matriz lineal:
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)