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。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

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