TensorFlow 睬坑以及某些特定用法

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

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