📅  最后修改于: 2020-12-10 04:50:51             🧑  作者: Mango
本章介绍Python软件包KVStore和可视化。
KV商店代表键值存储。它是用于多设备培训的关键组件。这很重要,因为通过一台或多台带有参数KVStore的服务器,可以在一台或多台机器上跨设备进行参数通信。
让我们借助以下几点来了解KVStore的工作方式:
KVStore中的每个值都由一个键和一个值表示。
网络中的每个参数数组都分配有一个键,并且该参数数组的权重由value表示。
之后,工作节点在处理批处理后推送渐变。他们还会在处理新批次之前提取更新的权重。
简而言之,我们可以说KVStore是一个数据共享的地方,每个设备都可以将数据放入和取出数据。
可以将KVStore视为在不同设备(例如GPU和计算机)之间共享的单个对象,其中每个设备都可以推入和拉出数据。
以下是设备将数据推入和拉出数据所需遵循的实现步骤:
初始化-第一步是初始化值。在此示例中,我们将一对(int,NDArray)对初始化为KVStrore,然后将值拉出-
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())
输出
这产生以下输出-
[[2. 2. 2.]
[2. 2. 2.]
[2. 2. 2.]]
推送,聚合和更新-初始化后,我们可以将新值以与键相同的形状推送到KVStore-
kv.push(3, mx.nd.ones(shape)*8)
kv.pull(3, out = a)
print(a.asnumpy())
输出
输出如下-
[[8. 8. 8.]
[8. 8. 8.]
[8. 8. 8.]]
用于推送的数据可以存储在任何设备上,例如GPU或计算机。我们还可以将多个值推入同一键。在这种情况下,KVStore将首先对所有这些值求和,然后按如下所示推送聚合值:
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())
输出
您将看到以下输出-
[[4. 4. 4.]
[4. 4. 4.]
[4. 4. 4.]]
对于您应用的每次推送,KVStore都会将推送的值与已存储的值合并。这将在更新程序的帮助下完成。此处,默认更新程序为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())
输出
当执行上述代码时,您应该看到以下输出-
[[4. 4. 4.]
[4. 4. 4.]
[4. 4. 4.]]
例
kv.push(3, mx.nd.ones(shape))
kv.pull(3, out=a)
print(a.asnumpy())
输出
下面给出的是代码的输出-
update on key: 3
[[6. 6. 6.]
[6. 6. 6.]
[6. 6. 6.]]
Pull-像Push一样,我们也可以通过一次调用将值拉到多个设备上,如下所示-
b = [mx.nd.ones(shape, ctx) for ctx in contexts]
kv.pull(3, out = b)
print(b[1].asnumpy())
输出
输出说明如下-
[[6. 6. 6.]
[6. 6. 6.]
[6. 6. 6.]]
下面给出的是完整的实现示例-
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())
上面我们实现的所有操作都涉及一个键,但是KVStore还提供了一个键值对列表的接口-
以下示例显示了一个KVStore接口,用于单个设备的键值对列表-
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())
输出
您将收到以下输出-
update on key: 5
update on key: 7
update on key: 9
[[3. 3. 3.]
[3. 3. 3.]
[3. 3. 3.]]
以下是显示KVStore接口的示例,该接口用于多个设备的键值对列表-
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())
输出
您将看到以下输出-
update on key: 5
update on key: 7
update on key: 9
[[11. 11. 11.]
[11. 11. 11.]
[11. 11. 11.]]
可视化包是Apache MXNet包,用于将神经网络(NN)表示为由节点和边组成的计算图。
在下面的示例中,我们将使用mx.viz.plot_network可视化神经网络。以下是为此的前提条件-
先决条件
Jupyter笔记本
Graphviz库
在下面的示例中,我们将可视化样本NN以进行线性矩阵分解-
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)