Apache MXNet - KVStore und Visualisierung
Dieses Kapitel befasst sich mit den Python-Paketen KVStore und Visualisierung.
KVStore-Paket
KV Stores steht für Key-Value Store. Es ist eine wichtige Komponente für das Training mit mehreren Geräten. Dies ist wichtig, da die Kommunikation von Parametern zwischen Geräten auf einem oder mehreren Computern über einen oder mehrere Server mit einem KVStore für die Parameter übertragen wird.
Lassen Sie uns die Arbeitsweise von KVStore anhand folgender Punkte verstehen:
Jeder Wert in KVStore wird durch a dargestellt key und ein value.
Jedem Parameterarray im Netzwerk ist a zugeordnet key und auf die Gewichte dieses Parameterarrays wird verwiesen value.
Danach die Worker-Knoten pushFarbverläufe nach der Bearbeitung einer Charge. Sie auchpull Aktualisierte Gewichte vor der Verarbeitung einer neuen Charge.
Mit einfachen Worten können wir sagen, dass KVStore ein Ort für den Datenaustausch ist, an dem jedes Gerät Daten ein- und ausziehen kann.
Daten Push-In und Pull-Out
KVStore kann als einzelnes Objekt betrachtet werden, das von verschiedenen Geräten wie GPUs und Computern gemeinsam genutzt wird, wobei jedes Gerät Daten ein- und ausziehen kann.
Im Folgenden sind die Implementierungsschritte aufgeführt, die von Geräten ausgeführt werden müssen, um Daten ein- und abzurufen:
Implementierungsschritte
Initialisation- Der erste Schritt besteht darin, die Werte zu initialisieren. In unserem Beispiel initialisieren wir ein Paar (int, NDArray) in KVStrore und ziehen danach die Werte heraus -
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
Dies erzeugt die folgende Ausgabe -
[[2. 2. 2.]
[2. 2. 2.]
[2. 2. 2.]]
Push, Aggregate, and Update - Nach der Initialisierung können wir einen neuen Wert mit der gleichen Form auf den Schlüssel in den KVStore übertragen. -
kv.push(3, mx.nd.ones(shape)*8)
kv.pull(3, out = a)
print(a.asnumpy())
Output
Die Ausgabe ist unten angegeben -
[[8. 8. 8.]
[8. 8. 8.]
[8. 8. 8.]]
Die zum Pushen verwendeten Daten können auf jedem Gerät wie GPUs oder Computern gespeichert werden. Wir können auch mehrere Werte in dieselbe Taste drücken. In diesem Fall summiert der KVStore zuerst alle diese Werte und überträgt dann den aggregierten Wert wie folgt:
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
Sie sehen die folgende Ausgabe -
[[4. 4. 4.]
[4. 4. 4.]
[4. 4. 4.]]
Bei jedem Push, den Sie angewendet haben, kombiniert KVStore den Push-Wert mit dem bereits gespeicherten Wert. Dies erfolgt mit Hilfe eines Updaters. Hier ist der Standard-Updater 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
Wenn Sie den obigen Code ausführen, sollte die folgende Ausgabe angezeigt werden:
[[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
Unten ist die Ausgabe des Codes angegeben -
update on key: 3
[[6. 6. 6.]
[6. 6. 6.]
[6. 6. 6.]]
Pull - Wie bei Push können wir den Wert auch mit einem einzigen Aufruf wie folgt auf mehrere Geräte übertragen: -
b = [mx.nd.ones(shape, ctx) for ctx in contexts]
kv.pull(3, out = b)
print(b[1].asnumpy())
Output
Die Ausgabe ist unten angegeben -
[[6. 6. 6.]
[6. 6. 6.]
[6. 6. 6.]]
Vollständiges Implementierungsbeispiel
Im Folgenden finden Sie das vollständige Implementierungsbeispiel -
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())
Umgang mit Schlüsselwertpaaren
Alle oben implementierten Vorgänge umfassen einen einzelnen Schlüssel, aber KVStore bietet auch eine Schnittstelle für a list of key-value pairs - -
Für ein einzelnes Gerät
Das folgende Beispiel zeigt eine KVStore-Schnittstelle für eine Liste von Schlüssel-Wert-Paaren für ein einzelnes Gerät:
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
Sie erhalten folgende Ausgabe:
update on key: 5
update on key: 7
update on key: 9
[[3. 3. 3.]
[3. 3. 3.]
[3. 3. 3.]]
Für mehrere Geräte
Das folgende Beispiel zeigt eine KVStore-Schnittstelle für eine Liste von Schlüssel-Wert-Paaren für mehrere Geräte:
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
Sie sehen die folgende Ausgabe -
update on key: 5
update on key: 7
update on key: 9
[[11. 11. 11.]
[11. 11. 11.]
[11. 11. 11.]]
Visualisierungspaket
Das Visualisierungspaket ist ein Apache MXNet-Paket, mit dem das neuronale Netzwerk (NN) als Berechnungsdiagramm dargestellt wird, das aus Knoten und Kanten besteht.
Visualisieren Sie das neuronale Netzwerk
Im folgenden Beispiel werden wir verwenden mx.viz.plot_networkneuronales Netzwerk zu visualisieren. Folgendes sind die Voraussetzungen dafür -
Prerequisites
Jupyter Notizbuch
Graphviz-Bibliothek
Implementierungsbeispiel
Im folgenden Beispiel werden wir ein Beispiel NN für die lineare Matrixfaktorisierung visualisieren -
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)