1. 異步讀取圖片的時候報錯:
想在tf.train.slice_input_producer加入num_epoch參數,控制epoch 例如測試這種只讀入一個epoch場景,再配合
tf.train.batch(***, allow_smaller_final_batch=True) 進行驗證、測試集操作,報以下錯誤:
OutOfRangeError: FIFOQueue '_1758_batch_41/fifo_queue' is closed and has insufficient elements (requested 4, current size 0)
[[Node: batch_41 = QueueDequeueUpToV2[component_types=[DT_FLOAT, DT_INT32], timeout_ms=-1, _device="/job:localhost/replica:0/task:0/device:CPU:0"](batch_41/fifo_queue, batch_41/n)]]
Caused by op 'batch_41', defined at:
File "C:\ProgramData\Anaconda3\lib\runpy.py", line 193, in _run_module_as_main
"__main__", mod_spec)
*
。。。。。。。。。。。。
File "C:\ProgramData\Anaconda3\lib\site-packages\tensorflow\python\framework\ops.py", line 1470, in __init__
self._traceback = self._graph._extract_stack() # pylint: disable=protected-access
OutOfRangeError (see above for traceback): FIFOQueue '_1758_batch_41/fifo_queue' is closed and has insufficient elements (requested 4, current size 0)
[[Node: batch_41 = QueueDequeueUpToV2[component_types=[DT_FLOAT, DT_INT32], timeout_ms=-1, _device="/job:localhost/replica:0/task:0/device:CPU:0"](batch_41/fifo_queue, batch_41/n)]]
image_list1 = glob.glob(image_dir1)
image_list2 = glob.glob(image_dir2+'*.jpg')
image_list = image_list2 + image_list1
print(len(image_list))
image_tensor_list = tf.convert_to_tensor(image_list)
l = [np.random.randint(0,10) for _ in range(len(image_list))]
label_tensor_list = tf.convert_to_tensor(l)
input_queue = tf.train.slice_input_producer([image_tensor_list, label_tensor_list],
shuffle=False,num_epochs=3)
image_reader = tf.read_file(input_queue[0])
image = tf.image.decode_jpeg(image_reader,channels=3)
print(image.shape)
image = tf.image.resize_images(image, size=(100,100))
a,b = tf.train.batch([image, input_queue[1]],batch_size=4,enqueue_many=False,
allow_smaller_final_batch=True)
logits = tf.reduce_mean(tf.multiply(a, tf.constant(3, dtype=tf.float32)), axis=[1,2,3])
loss = tf.subtract(logits, tf.squeeze(tf.cast(b, dtype=tf.float32),))
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
coord = tf.train.Coordinator()
threads = tf.train.start_queue_runners(sess=sess, coord=coord)
for i in range(56):
k = sess.run([loss])
print (k,i)
coord.request_stop()
coord.join(threads)
在sess內部加入 sess.run(tf.local_variables_initializer())可解決,原因:
tf.global_variables_initializer()添加節點用於初始化所有的變量(GraphKeys.VARIABLES
)
tf.local_variables_initializer()返回一個初始化所有局部變量的操作(Op)。初始化局部變量(GraphKeys.LOCAL_VARIABLE
)。GraphKeys.LOCAL_VARIABLE
中的變量指的是被添加入圖中,但是未被儲存的變量。
上面的num_epochs=3 可能屬於後者,在run的的時候需要這個變量但是未配置,(猜測,可能不正確)
2.enqueue
queue = tf.FIFOQueue(...)
enqueue_op = queue.enqueue(example)
qr = tf.train.QueueRunner(queue, [enqueue_op] * num_theadings)
1.使用tf.train.add_queue_runner(qr)
tf.train.add_queue_runner(qr)
input = q.dequeue(...)
train(input).....
sess:
coord = tf.train.Coordinator()
threads = tf.train.start_queue_runners(sess=sess, coord=coord)#!!!!
#由於有可能 add_queue_runner(qr)添加了多個入隊qr,所以threadS!可能多個進程(每個進程可能多個入隊)
coord.request_stop()
coord.join(threads)
....其他都一樣
2.直接用qr創建進程
#tf.train.add_queue_runner(qr) 不再需要這一步!
input = q.dequeue(...)
train(input).....
sess:
coord = tf.train.Coordinator()
thread = qr.create_threads(sess, coord=coord, start=True) #!!!!相當於入隊操作的單一進程
coord.request_stop()
coord.join(threads)
在使用tf.train.start_queue_runners(sess=sess, coord=coord)的時候,前面肯定有
tf.train.add_queue_runner(qr) 相當於:
ops.GraphKeys.QUEUE_RUNNERS中的所有qr入隊進程
for qr in ops.get_collection(collection):
threads.extend(qr.create_threads(sess, coord=coord, daemon=daemon,
start=start))
return threads