tensorflow 多gpu实现学习记录

理论与概念

不看网上教程了,直接看官网的介绍。也不用keras,keras一点都不灵活,还各种bug。

直接看源码,地址为https://github.com/tensorflow/models/blob/master/tutorials/image/cifar10/cifar10_input.py

我的理解是这样,首先共享变量的定义是什么?是如何共享的?

答:变量有一个主要存储的地方,如cpu1,而其余的引用都是借用,而原版永远都是在cpu1中。所以共享的方式就是有一个拷贝在cpu1中,利用with device来借用这些变量,在with device的设备里面借用并计算。

with tf.device('/gpu:%d' % i):
        # Dequeues one batch for the GPU
        image_batch, label_batch = batch_queue.dequeue()
        logits = cifar10.inference(images)

上面的inference里的所有推导计算都是这样的:

kernel = _variable_with_weight_decay('weights',
                                     shape=[5, 5, 3, 64],
                                     stddev=5e-2,
                                     wd=None)
conv = tf.nn.conv2d(images, kernel, [1, 1, 1, 1], padding='SAME')
biases = _variable_on_cpu('biases', [64], tf.constant_initializer(0.0))
pre_activation = tf.nn.bias_add(conv, biases)
conv1 = tf.nn.relu(pre_activation, name=scope.name)

可以看到都是在cpu中建立变量,因此所有变量的本体都在cpu里,gpu只是借用来计算。按照这个思路基本上就搞清楚了。

在用多gpu时,流程为

1,先在cpu里建立一个网络,这些网络的变量名字定义好。

2,用with device gpu来借用这些变量并计算,计算的结果也存到cpu。

3,更新cpu中的权重

4,重复2

实践与验证

写一个最简单的网络,然后用cpu存参数,用多个gpu来借用参数并计算。

def _variable_on_cpu(name, shape, initializer):
    """Helper to create a Variable stored on CPU memory.
    Args:
      name: name of the variable
      shape: list of ints
      initializer: initializer for Variable
    Returns:
      Variable Tensor
    """
    with tf.device('/cpu:0'):
        var = tf.get_variable(name, shape, initializer=initializer)
    return var


ccc = _variable_on_cpu('ccc', [2, 3, 4], tf.random_normal_initializer())
ddd=tf.get_variable_scope()
ddd.reuse_variables()
ccc1=_variable_on_cpu('ccc', [2, 3, 4], tf.random_normal_initializer())
init = tf.global_variables_initializer()
sess = tf.Session()
print(ccc==ccc1)#True

不加那个reuse_variables()会报错。

接下来做一个验证,即是cpu上建立本体变量,gpu借用这个变量,然后改变cpu本体变量,gpu借用这个变量,看变化。

ccc = _variable_on_cpu('ccc', tf.ones([2, 3, 4]))
ddd = tf.get_variable_scope()
ddd.reuse_variables()
init = tf.global_variables_initializer()
sess = tf.Session()
sess.run(init)

with tf.device('/cpu:0'):
    with tf.device('/gpu:0'):
        ccc1=tf.get_variable('ccc')
        ccc2=ccc1*2
        print(sess.run(ccc2))
    fff=ccc.assign_add(tf.ones([2, 3, 4]))
    sess.run(fff)

    print(sess.run(ccc2))

这里就一目了然了,上面的代码说明我的猜想是正确的,接下来就是利用这个机制来搭一个模型,多gpu训练。要注意的就是变量名字要唯一就好了,假如所有变量都是没有要区分可以reuse和不能reuse的话,那么就把所有变量都放到一个variable_scope,并且都设置为reusable。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章