1. 程式人生 > >tensorflow的session.run執行一個op和多個op的區別

tensorflow的session.run執行一個op和多個op的區別

背景:

session.run方法可以傳入一個op,也可以傳入op列表,例如,我們希望執行op1和op2,有兩種寫法:

sess.run(op1)

sess.run(op2)

sess.run([op1, op2])

如果op1和op2有相互包含關係,第寫法1會將op1和op2的圖各完整執行一遍,而寫法2不會重複執行op1和op2中的公共部分。

例如:

# coding: utf-8
# 匯入tensorflow
import tensorflow as tf

with tf.Session() as sess:
    base_path = '/Users/gandalf/WorkSpace/test/inputtexts/'
    # 3個檔案
    filename = [base_path + 'a.txt', base_path + 'b.txt', base_path + 'c.txt']
    # 構造檔名佇列,epoch內非隨機排序,1個epoch
    filename_queue = tf.train.string_input_producer(filename, shuffle=False, num_epochs=1)
    # WholeFileReader每次讀出的是一個檔案的所有內容
    reader = tf.WholeFileReader()
    key, value = reader.read(filename_queue)

    # tf.train.string_input_producer定義了一個epoch變數,要對它進行初始化
    tf.local_variables_initializer().run()
    # 使用start_queue_runners之後,才會開始填充佇列
    coord = tf.train.Coordinator()  # 為監測輸入檔名佇列是否處理結束
    threads = tf.train.start_queue_runners(sess=sess, coord=coord)  # 啟動檔案讀取執行緒
    try:
        while not coord.should_stop():
            # 同時執行多個op
            key_data, txt_data = sess.run([key, value])
            print "key:" + key_data
            print "value:\n" + txt_data
            print "-------------------------"

    except tf.errors.OutOfRangeError:
        print('Done reading, file queue ended.')
    finally:
        coord.request_stop()

    coord.join(threads)
    sess.close()

輸出:

gandalfdeMacBook-Air:test gandalf$ python sessrun.multi.test.py 

2018-08-19 20:01:30.853685: I tensorflow/core/platform/cpu_feature_guard.cc:141] Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX2 FMA

key:/Users/gandalf/WorkSpace/test/inputtexts/a.txt

value:

1 1 1

2 2 2

3 3 3

-------------------------

key:/Users/gandalf/WorkSpace/test/inputtexts/b.txt

value:

4 4 4

5 5 5

6 6 6

-------------------------

key:/Users/gandalf/WorkSpace/test/inputtexts/c.txt

value:

7 7 7

8 8 8

9 9 9

-------------------------

Done reading, file queue ended.

可見,3個輸入檔案在1個epoch中被順利輸出。

我們試試獨立輸入op:

# coding: utf-8
# 匯入tensorflow
import tensorflow as tf

with tf.Session() as sess:
    base_path = '/Users/gandalf/WorkSpace/test/inputtexts/'
    # 3個檔案
    filename = [base_path + 'a.txt', base_path + 'b.txt', base_path + 'c.txt']
    # 構造檔名佇列,epoch內非隨機排序,1個epoch
    filename_queue = tf.train.string_input_producer(filename, shuffle=False, num_epochs=1)
    # WholeFileReader每次讀出的是一個檔案的所有內容
    reader = tf.WholeFileReader()
    key, value = reader.read(filename_queue)

    # tf.train.string_input_producer定義了一個epoch變數,要對它進行初始化
    tf.local_variables_initializer().run()
    # 使用start_queue_runners之後,才會開始填充佇列
    coord = tf.train.Coordinator()  # 為監測輸入檔名佇列是否處理結束
    threads = tf.train.start_queue_runners(sess=sess, coord=coord)  # 啟動檔案讀取執行緒
    try:
        while not coord.should_stop():
            # 輸入多個op
            # key_data, txt_data = sess.run([key, value])

            # 輸入單獨op
            key_data = sess.run(key)
            txt_data = sess.run(value)

            print "key:" + key_data
            print "value:\n" + txt_data
            print "-------------------------"

    except tf.errors.OutOfRangeError:
        print('Done reading, file queue ended.')
    finally:
        coord.request_stop()

    coord.join(threads)
    sess.close()

輸出:

gandalfdeMacBook-Air:test gandalf$ python sessrun.multi.test.py 

2018-08-19 20:03:07.207565: I tensorflow/core/platform/cpu_feature_guard.cc:141] Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX2 FMA

key:/Users/gandalf/WorkSpace/test/inputtexts/a.txt

value:

4 4 4

5 5 5

6 6 6

-------------------------

Done reading, file queue ended.

原理:

第一輪迴圈:

執行key_data = sess.run(key)時就已經針對第一個檔案a.txt執行完了一遍graph,所以列印的key_data是:

/Users/gandalf/WorkSpace/test/inputtexts/a.txt

執行txt_data = sess.run(value)後,已經針對第二個檔案b.txt執行完了一遍graph,所以列印的txt_data是b檔案的內容。

此時,進入第二輪迴圈:

當執行key_data = sess.run(key),處理完第三個檔案c.txt。

當執行txt_data = sess.run(value)時,觸發檔案佇列結束異常,跳出迴圈,結束程式碼執行。