现在,假设我们把样本分配到n个工作节点,每个节点在m个样本上进行学习(节点1处理样本1,……,m,节点2处理样本m+1,……,2m,以此类推),则得到:
当然,上述结果在实际应用中可能并不严格一致(从性能和收敛性的角度来说,对所有minibatch进行平均和不采用诸如momentum和RMSProp之类的updater的建议都较为偏颇),但是它从直觉上告诉了我们为啥参数平均法是一种可行的做法,尤其是当参数被频繁的求均值。
参数平均法听上去非常简单,但事实上并没有我们看上去这么容易。
首先,我们应该如何求平均值?最简单的办法就是简单地将每轮迭代之后的参数进行平均。一旦这样实现了,我们会发现此方法在计算之外的额外开销非常巨大;网络通信和同步的开销也许就能抵消额外机器带来的效率收益。因此,参数平均法通常有一个大于1的平均周期averaging period(就每个节点的minibatch而言)。如果求均值太频繁,那么每个节点得到的局部参数更多样化,求均值之后的模型效果非常差。我们的想法是N个局部最小值的均值并不保证就是局部最小:
什么样的平均的周期算是过高呢?这个问题还没有结论性的回答,和其它超参数搅和在一起之后变得更为复杂,比如学习率、minibatch的大小,和工作节点的数量。有些初步的研究结论(比如[8])建议平均的周期为每10~20个minibatch计算一次(每个工作节点)能够取得比较好的效果。随着平均的周期延长,模型的准确率则随之下降。
另一类额外的复杂度则是与优化算法相关,比如adagrad,momentum和RMSProp。这些优化方法(即Deeplearning4j中的updater)在神经网络的训练过程中能够显著提升收敛的特性。然而,这些updater都有中间状态(通常每个模型参数有1或2个状态值)—— 我们也需要对这些状态值求均值吗?对每个节点的中间状态求均值可以加快收敛的速度,而牺牲的代价则是两倍(或者多倍)增加网络的传输数据量。有些研究在参数服务器的层面应用类似的“updater”机制,而不仅仅在每个工作节点([1])。
异步随机梯度下降
有另一种与参数平均概念类似的方法,我们称之为‘基于更新’的数据并行化。两者的主要区别在于相对于在工作节点与参数服务器之间传递参数,我们在这里只传递更新信息(即梯度和冲量等等)。参数的更新形式变为了:
其中 λ 是一个缩放因素(类似于学习率这类的超参数)。
它从结构上来看与参数平均法非常相似:
熟悉神经网络模型训练过程的数学原理的读者也许已经注意到了参数平均法与基于更新的方法之间的相似点。如果我们定义损失函数为L,学习率为α,那么权值向量W在SGD训练过程的第i+1次迭代的结果为
W
i
+
1
,
j
=
W
i
−
α
∇
L
j
,其中
∇
L
=
(
∂
L
∂
w
1
,
…
,
∂
L
∂
w
n
)
。
如果我们按照上述的权重更新规则,并且设置
λ
=
1
n
,权重值的更新量为
Δ
W
i
,
j
=
α
∇
L
j
(简单期间,仅用学习率为α的SGD算法),于是得到:
最终,当参数时同步方式更新时,参数平均法等价于基于更新的数据并行化。这个等价关系对多个平均步骤以及其它updater都成立(不仅限于简单版SGD)。
当我们松绑同步更新的条件之后,基于更新的数据并行化方法变得更有意思了。也就是说,一旦计算得到?Wi,j,就立即将其应用于参数向量(而不是等待N ≥ 1 轮迭代),我们因此得到了异步随机梯度下降算法。异步SGD有两个主要优势: