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)時,觸發檔案佇列結束異常,跳出迴圈,結束程式碼執行。