我有典型的/通用TF(R1.3)配置,其中讀取單個tf.record文件和結果進行解碼來查詢一些記錄值:TensorFlow:tf.Session.run()讀取並執行依賴性
import os, tensorflow as tf
# path to TF record file containing single record
record_file_path = os.path.join(os.getcwd(),'tf.record')
# init a finite file queue with num_epochs=1
file_queue = tf.train.string_input_producer([record_file_path],name='file_queue',num_epochs=1)
# init record reader
reader = tf.TFRecordReader()
# read the record file
_, tfrecord_read_op = reader.read(file_queue)
tfrecord = tf.parse_single_example(
tfrecord_read_op,
features={
'image/height' : tf.FixedLenFeature([], tf.int64),
'image/width' : tf.FixedLenFeature([], tf.int64),
'image/label' : tf.FixedLenFeature([], tf.int64),
'image/encoded': tf.FixedLenFeature([], tf.string)
},
name='features'
)
# since exported as tf.int64 there is no need for tf.decode_raw
heightT = tfrecord['image/height']
widthT = tfrecord['image/width' ]
with tf.Session() as sess:
# init vars
sess.run(tf.global_variables_initializer())
sess.run(tf.local_variables_initializer())
# Start populating the filename queue
queue_coordinator = tf.train.Coordinator()
queue_worker_threads = tf.train.start_queue_runners(coord=queue_coordinator)
# kaboom!
height = sess.run(heightT)
width = sess.run(widthT)
# why does this work ??
#height, width = sess.run([heightT, widthT])
# close down the queue
queue_coordinator.request_stop()
queue_coordinator.join(queue_worker_threads)
print('image height x width : {}x{}'.format(height,width))
請注意,文件隊列被鉗位在num_epochs=1
,所以只能爲TFRecordReader
一次生成單個文件。
在計算曲線圖,二者heightT
和widthT
張量-OPS取決於tfrecord
取決於tfrecord_read_op
因此,tfrecord
被評估的任何時間,計算圖形的依賴應調用從file_queue
另一個出隊。確實如此評估heightT
和widthT
中的單獨tf.Session
run()
調用。
另外,如果num_epoch=None
(即單個文件的無限出隊),單獨的調用將成功(!?)並且,num_epochs=None
是默認值。
現在,最後,問題:如何/爲什麼單個run()
調用與多個提取成功評估張量操作?也就是說,爲什麼
height,width = sess.run([heightT,widthT])
成功,但
height = sess.run(heightT)
width = sess.run(widthT)
失敗?
事實上,使用佔位符(D型= tf.string)持有tfrecord_read_op的結果,並在執行佔位減輕tf.parse_single_example
這種效果,但並沒有真正揭示什麼是在圖形評估發生的情況下,任何光線(s)在上面突出顯示。
最後一個問題 - 如果您在單次運行調用中獲取高度/寬度,它將重用任何共享張量(即單隊列出隊)。在2次調用中,它會觸發2個出隊 –
因此,每次session.run調用都不會評估超過一次op?在圖遍歷意義上,op被標記爲評估/看到,如果在同一運行調用中評估另一個fetch時遇到同一個op/node,則op將不會被重新評估。如果計算圖中有一個循環,但對共享文件讀取器等事物不太清晰,則更明顯。可能最簡單的重用示例就像'out1,out2 = sess.run([op,op])'只對'out1'評估'op',並將結果重用爲out2。 –