Tensorflow并行GPU计算

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/VioletHan7/article/details/82769531

Tensorflow使用GPU

Tensorflow程序可以通过tf.device函数来指定运行每一个操作的设备,这个设备可以是本地CPU或GPU,也可以是某一台远程服务器。

tf.device函数可以通过设备的名称来指定执行运算的设备。

  • 如CPU在tensorflow中的名称为/cpu:0。在默认情况下,即使机器有很多个CPU,tensorflow也不会区分它们,所有的CPU都使用/cpu:0作为名称。
  • 而一台机器上不同GPU的名称是不同的,第n个GPU在tensorflow中的名称为/gpu:n。

tensorflow提供了一个会计的方式来查看运行每一个运算的设备。在生成会话时,可以通过设置log_device_placement参数来打印运行每一个运算的设备。

import tensorflow as tf 
a=tf.constant([1.0,2.0,3.0],shape=[3],name='a')
b=tf.constant([1.0,2.0,3.0],shape=[3],name='b')
c=a+b
#通过log_device_placement参数来输出运行每一个运算的设备
sess=tf.Session(config=tf.ConfigProto(log_device_placement=True))
print (sess.run(c))

在以上代码中,tensorflow程序生成会话时加入了参数log_device_placement=True,所以程序会将运行每一个操作的设备输出到屏幕。

在配置好GPU的环境中,如果操作没有明确指定运行设备,那么tensorflow会优先选择GPU。但是,尽管有4个GPU,在默认情况下,tensorflow只会将运算优先放到/gpu:0上。如果需要将某些运算放到不同的GPU或CPU上,就需要通过tf.device来手工指定。

import tensorflow as tf

#通过tf.device将运算指定到特定的设备上
with tf.device('/cpu:0'):
    a=tf.constant([1.0,2.0,3.0],shape=[3],name='a')
    b=tf.constant([1.0,2.0,3.0],shape=[3],name='b')
with tf.device('/gpu:1'):
    c=a+b
sess=tf.Session(config=tf.ConfigProto(log_device_placement=True))
print(sess.run(c))

在以上代码中可以看到生成常量a和b的操作被加载到CPU上,而加法操作被放到第二个GPU上。在tensorflow中,不是所有的操作都可以被放在GPU上,如果强行将无法放在GPU上的操作指定到GPU上,程序就会报错。
在GPU上,tf.Variable操作只支持实数型(float16 float32 double)的参数。不支持整数型参数。tensorflow在生成会话时可以指定allow_soft_placement参数。当这个参数设置为True时,如果运算无法由GPU执行,那么tensorflow会自动将它放到CPU上执行。

import tensorflow as tf

a=tf.Variable(0,name='a')
with tf.device('/gpu:0'):
    b=tf.Variable(0,name='b')
#通过allow_soft_placement参数自动将无法放在GPU上的操作放回CPU上
sess=tf.Session(config=tf.ConfigProto(allow_soft_placement=True,log_device_placement=True))
sess.run(tf.initialize_all_variables()

深度学习训练并行模式

tensorflow可以很容易得利用单个GPU加速深度学习模型的训练过程,但要利用更多的GPU或者机器,需要了解如何并行化训练深度学习模型。常用的并行化深度学习模型训练方式有两种:同步模式、异步模式。

在这里插入图片描述
上图是深度学习模型的训练流程图。深度学习模型的训练是一个迭代的过程。在每一轮迭代中,前向传播算法会根据当前参数的取值计算出在一小部分训练数据上的预测值,然后反向传播算法再根据损失函数计算参数的梯度并更新参数。在并行化训练深度学习模型时,不同设备(GPU CPU)可以在不同训练数据上运行这个迭代过程,而不同并行模式的区别在于不同的参数更新方式。

在这里插入图片描述
上图展示了异步模式的训练流程图。从图中可以看出,在每一次迭代时,不同设备会读取参数最新的取值,但因为不同设备读取参数取值的时间不一样,所以得到的值也有可能不一样。根据当前参数的取值和随机获取的一小部分训练数据,不同设备各自运行反向传播的过程并独立地更新参数。可以简单地认为异步模式就是单机模式复制了多份,每一份使用不同的训练数据进行训练。在异步模式下,不同设备之间是完全独立的。

然鹅使用异步模式训练的深度学习模型有可能无法达到较优的训练结果。
在这里插入图片描述
为了避免更新不同步的问题,可以使用同步模式。在同步模式下,所有的设备同事读取参数的取值,并且当反向传播算法完成之后同步更新参数的取值。单个设备不会单独对参数进行更新,而等待所有设备都完成反向传播之后再同意更新参数。
上图展示了同步模式的训练过程。在每一轮迭代时,不同设备首先同意读取当前参数的取值,并随机获取一小部分数据。然后在不同设备上运城反向传播过程得到在各自训练数据上参数的梯度。注意虽然所有设备使用的参数是一致的,但是因为训练数据不同,所以得到参数的梯度可能不一样。当所有设备完成反向传播的计算之后,需要计算出不同设备上参数梯度的平均值,最后再根据平均值对参数进行更新。

同步模式解决了异步模式中存在的参数更新问题,然而同步模式的效率却低于异步模式。在同步模式下,每一轮迭代都需要设备统一开始、统一结束。如果设备的运行速度不一致,呢么每一轮训练都需要等待最慢的设备结束后才能开始更新参数。虽然理论上异步模式存在缺陷,但因为训练深度学习模型时使用的随机梯度下降本身就是梯度下降的一个近似解法,而且即使是梯度下降也无法保证达到全局最优值,所以在实际应用中,在相同时间内,使用异步模式训练的模型不一定比同步模式差。所以,这两种训练模式在实践中都有非常广泛的应用。

多GPU并行

给出具体代码,在一台机器上的多个GPU上并行训练深度学习模型。一般来说一台机器上的多个GPU性能相似,所以在这种设置下更多采用同步模式训练深度学习模型。
在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述

分布式tensorflow

后续再增加,目前只用到并行GPU

猜你喜欢

转载自blog.csdn.net/VioletHan7/article/details/82769531