tensorflow源码学习之五 -- 同步训练和异步训练

 同步和异步训练是由optimizer来决定的。

        1. 同步训练

        同步训练需要使用SyncReplicasOptimizer,参考https://www.tensorflow.org/api_docs/python/tf/train/SyncReplicasOptimizer 。其他optimizer都属于异步训练方式。

        同步训练实现在sync_replicas_optimizer.py文件中的def apply_gradient()方法中。假设有n个参数:

        对于PS,需要创建n个参数收集器(每个参数对应一个收集器),每一个worker将自己计算得到的grad梯度推送到收集器上(推送是使用Send/Recv OP实现的)。每个参数收集器收集到所有的worker的推送值时,对所有的值求平均,然后更新参数的值。当所有的参数都更新完成之后,对global_step加1,并将global_step推送到每个worker的token_queue中,worker更新global_step,开始下一次训练。

       对于Worker,从PS拉取需要的参数,计算grad梯度值,然后将grad推送到相应的参数收集器。推送之后从token_queue中拉取新的global_step(拉取不到新的global_step 就等待?),继续下一次训练。

        2. 异步训练

         训练代码中使用的是GradientDescentOptimizer(继承了Optimizer),调用其minimize()方法,minimize()方法就是先调用compute_gradients()然后调用apply_gradient()方法。

         异步训练的实现在optimizer.py文件中的def apply_gradient()方法中(GradientDescentOptimizer没有重写Optimizer的apply_gradient()方法)。参考https://stackoverflow.com/questions/43147435/how-does-asynchronous-training-work-in-distributed-tensorflow

         对于Worker,worker从PS拉取需要的参数,拉取过程是没有锁的,因此拉取的值可能包含了其他worker的修改,也可能没包含。计算gard梯度值,然后将grad梯度值发送给相应PS。

         对于PS,ps收到grad值之后根据优化算法(如,SGD, SGD with Momentum, Adagrad, Adam, etc.)来更新参数。

         :在异步训练中,假设worker1读取参数w1,worker2再读取参数w1,然后worker1更新梯度,worker2再更新梯度,worker1更新的梯度就被worker2覆盖掉了。如果想对修改做同步,GradientDescentOptimizer的构造函数提供了use_locking参数。

参考:
[1] http://jcf94.com/2018/01/13/2018-01-13-tfunpacking/   (session.run())
[2] http://jcf94.com/2018/01/23/2018-01-23-tfunpacking2/ (tf数据流模型和自动求导)
[3] http://jcf94.com/2018/02/28/2018-02-28-tfunpacking3/ (graph和node)
[4] http://jcf94.com/2018/03/07/2018-03-07-tfunpacking4/ (device)
[5] http://jcf94.com/2018/03/09/2018-03-09-tfunpacking5/ (distributed)
[6] https://www.tensorflow.org/deploy/distributed               (distributed tensorflow)
[7] https://stackoverflow.com/questions/43147435/how-does-asynchronous-training-work-in-distributed-tensorflow (asynchronous training in distributed tensorflow)

猜你喜欢

转载自www.cnblogs.com/lixiaolun/p/9818347.html