Luc*_*bue 3 python distributed asynchronous tensorflow
我已经阅读了分布式TensorFlow文档以及有关StackOverflow的问题,但我仍然对可以使用TensorFlow及其参数服务器体系结构进行分布式培训背后的动力有些怀疑。这是来自分布式TensorFlow文档的代码片段:
if FLAGS.job_name == "ps":
server.join()
elif FLAGS.job_name == "worker":
# Assigns ops to the local worker by default.
with tf.device(tf.train.replica_device_setter(
worker_device="/job:worker/task:%d" % FLAGS.task_index,
cluster=cluster)):
# Build model...
loss = ...
global_step = tf.contrib.framework.get_or_create_global_step()
train_op = tf.train.AdagradOptimizer(0.01).minimize(
loss, global_step=global_step)
Run Code Online (Sandbox Code Playgroud)
这是我阅读的StackOverflow问题的部分答案:
工作程序从PS任务并行读取所有共享模型参数,并将它们复制到工作程序任务。这些读取与任何并发写入均不协调,并且不会获取任何锁:尤其是该工作程序可能会看到一个或多个其他工作程序的部分更新(例如,可能已应用了来自另一工作程序的更新的子集,或元素的一个子集)中的变量可能已更新)。
工作者根据一批输入数据和在步骤1中读取的参数值在本地计算梯度。
工作人员使用由优化算法(例如SGD,带有动量的SGD,Adagrad,Adam等)确定的更新规则,将每个变量的梯度发送到适当的PS任务,并将梯度应用于它们各自的变量。更新规则通常使用(大约)交换操作,因此它们可以独立地应用于来自每个工作程序的更新,并且每个变量的状态将是接收到的更新序列的运行汇总。
我必须在另一个环境中重现这种参数服务器架构,并且我需要深入了解TensorFlow框架内worker和PS任务之间如何交互。我的问题是,PS任务在从工作人员那里收到值后会执行某种合并或更新操作,还是只存储最新的值?仅仅存储最新的值可以合理吗?查看TensorFlow文档中的代码,我发现PS任务只是执行一个join(),我想知道此方法调用的背后是PS任务的完整行为。
还有一个问题,计算梯度和应用梯度之间有什么区别?
让我们以相反的顺序开始,从最后一个问题开始:计算梯度和应用梯度之间有什么区别?
计算梯度意味着在计算出损耗之后在网络上运行反向传递。对于梯度下降,这意味着估计gradients下面公式中的值(请注意:这是对计算梯度实际需要的内容的极大简化,请查阅有关反向传播和梯度下降的更多信息,以正确解释其工作原理)。应用渐变意味着根据您刚计算出的渐变来更新参数。对于梯度下降,这(大致)意味着执行以下操作:
weights = weights - (learning_step * gradients)
Run Code Online (Sandbox Code Playgroud)
请注意,取决于的值learning_step,的新值weights取决于先前的值和计算的权重。
考虑到这一点,更容易理解PS / worker体系结构。让我们做一个简化的假设,即只有一个PS(我们将在后面看到如何扩展到多PS)
PS(参数服务器)将weights(即参数)保存在内存中,并接收gradients,运行我在上面的代码中编写的更新步骤。每当它收到工人的梯度时,它都会这样做。
另一方面,工作者在PS中查找PS 的当前值,weights在本地复制它,对一批数据运行网络的正向和反向传递,并获取new gradients,然后将其发送回PS。
请注意对“当前”的强调:worker和PS之间没有锁定或进程间同步。如果工作人员weights在更新过程中进行读取(例如,一半已经具有新值,而另一半仍在更新中),那么这就是他将在下一次迭代中使用的权重。这样可以使事情保持快速。
如果还有更多PS,该怎么办?没问题!网络的参数在PS之间进行划分,工作人员只需联系所有参数即可获取每个参数块的新值,并仅发送与每个特定PS相关的梯度。
| 归档时间: |
|
| 查看次数: |
228 次 |
| 最近记录: |