分布式训练产生的神经网络是每个分布式节点内训练的神经网络的平均值吗?

Does distributed training produce NN that is average of NNs trained within each distributed node?

我目前正在筛选大量关于神经网络分布式训练(反向传播训练)的 material。而且我越深入研究这个 material 在我看来,基本上每个分布式神经网络训练算法都只是一种结合分布式节点产生的梯度(通常使用平均值完成)相对于执行约束的方法环境(即网络拓扑、节点性能平等等)。

底层算法的所有优点都集中在利用执行环境约束的假设上,目的是减少整体滞后,从而减少完成训练所需的总时间。

因此,如果我们只是以某种巧妙的方式使用权重平均将梯度与分布式训练相结合,那么整个过程训练(或多或少)等同于每个分布式节点内训练产生的网络平均。

如果我对上述内容的看法是正确的,那么我想尝试手动组合分布式节点产生的权重。

所以我的问题是: 您如何使用任何主流技术(例如 tensorflow / caffe / mxnet / ...

产生两个或多个神经网络权重的平均值

提前致谢

编辑@Matias Valdenegro

Matias 我明白你在说什么:你的意思是一旦你应用梯度,新的梯度就会改变,因此不可能进行并行化,因为旧的梯度与新的更​​新权重无关。所以现实世界的算法会评估梯度,对它们进行平均然后应用它们。

现在,如果您只是展开此数学运算中的括号,您会注意到您可以在本地应用渐变。如果您平均增量(向量)或平均 NN 状态(点),基本上没有区别。请参考下图:

假设 NN 权重是一个二维向量。

Initial state  = (0, 0)
Deltas 1       = (1, 1)
Deltas 2       = (1,-1)
-----------------------
Average deltas = (1, 1) * 0.5 + (1, -1) * 0.5 = (1, 0)
NN State       = (0, 0) - (1, 0) = (-1, 0)

现在,如果在节点上局部应用梯度并且中心节点将平均权重而不是增量,则可以获得相同的结果:

--------- Central node 0 ---------
Initial state  = (0, 0)
----------------------------------

------------- Node 1 -------------
Deltas 1       = (1, 1)
State 1        = (0, 0) - (1,  1) = (-1, -1)
----------------------------------

------------- Node 2 -------------
Deltas 2       = (1,-1)
State 2        = (0, 0) - (1, -1) = (-1,  1)
----------------------------------

--------- Central node 0 ---------
Average state  = ((-1, -1) * 0.5 + (-1,  1) * 0.5) = (-1, 0)
----------------------------------

所以结果是一样的...

标题中的问题与 body 中的问题不同 :) 我都会回答:

题目问题:"Does distributed training produce NN that is average of NNs trained within each distributed node?"

没有。在使用 minibatch SGD 进行模型训练的上下文中,分布式训练通常指的是 data-parallel 分布式训练,它将 mini-batch 条记录的梯度计算分布在 N 个 worker 上,然后产生一个平均梯度用于以异步或同步方式更新中央模型权重。从历史上看,平均发生在一个称为参数服务器的单独进程中(MXNet 和 TensorFlow 中的历史默认值),但现代方法使用更多 network-frugal、peer-to-peer ring-style all-reduce、 Uber's Horovod extension, initially developed for TensorFlow but now available for Keras, PyTorch and MXNet too. Note that model-parallel distributed training (having different piece of a model hosted in different devices) also exists, but data parallel training is more common in practice, possibly because simpler to implement (distributing an average is easy) and because full models often fit comfortably in memory of modern hardware. However, model parallel training is occasionally seen for very large models, such as Google's GNMT.

民主化

Body 问题:"How do you produce an average of two or more neural network weights using any mainstream technology?"

这取决于每个框架API,例如:

在张量流中: Tensorflow - Averaging model weights from restored models

在 PyTorch 中: How to take the average of the weights of two networks?

在 MXNet 中(虚拟代码假设已初始化 gluon nn.Sequential() 具有相似架构的模型):

# create Parameter dict storing model parameters
p1 = net1.collect_params()
p2 = net2.collect_params()
p3 = net3.collect_params()

for k1, k2, k3 in zip(p1, p2, p3):
    p3[k3].set_data(0.5*(p1[k1].data() + p2[k2].data()))