TensorFlow官方教程翻譯2:線程和隊列

原文地址https://www.tensorflow.org/programmersguide/threadingand_queues

主要內容

隊列使用概述
Coordinator
QueueRunner
處理異常

隊列對于使用TensorFlow來進行異步計算是一個強大的機制。
像所有的TensorFlow中的東西一樣,一個隊列是一個TensorFlow圖中的一個節點。這是個狀態節點,像一個變量:其他節點可以修改它的內容。特別的來說,其他節點可以將新的元素加入隊列,或者從隊列中出隊現存的元素。
為了找點對于隊列概念的感覺,讓我們來考慮一個簡單的例子。我們會創建一個“先進,先出”的隊列(FIFOQueue),并且用0填充這個隊列。然后,我們構建了一個圖,出隊一個元素,將這個元素加1,然后將這個元素放回到這個隊列的尾部。于是,隊列中的數字都在逐漸增加。

Example1:Enqueue and Dequeue Op

Enqueue,EnqueueMany和Dequeue都是特殊的節點。他們保存著指向隊列的指針而不是一般的數值,這樣使得它們能夠修改隊列。我們建議你將這些方法認為是和隊列的方法類似。實際上,在Python的API中,他們是隊列對象的方法(例如q.enqueue(…))。
注意:隊列的方法(例如q.enqueue())必須和隊列本身運行在相同的硬件上。在創建這些操作的時候,不一致的硬件部署指令會被忽略。
現在你應該對于隊列有些感覺了,那讓我們深入細節。

隊列使用概述

例如像tf.FIFOQueue和tf.RandomShuffleQueue這樣的隊列,對于在圖中異步計算張量而言,是非常重要的TensorFlow對象。
舉例來說,一個典型的輸入架構就是使用RandomShuffleQueue來為訓練模型準備輸入:

  • 多線程準備訓練數據,并將其壓入隊列。
  • 一個訓練線程運行訓練操作,這個操作從隊列中出隊小批量的數據。

這個架構有很多好處,正如Reading data中所強調的那樣,同時這篇文章也一些簡化構建輸入管道的函數的概述。
TensorFlow的Session對象是多線程的,因此多線程可以很容易的使用相同的圖,和并行的運行操作。但是實現一個如上所述的使用線程的Python程序,并不總是那么容易。所有的線程必須能夠同時停止,異常需要被捕捉并通知(reported),而隊列比如在線程停止的時候,被恰當的關閉。
TensorFlow提供兩個類來幫助上述任務的實現:tf.train.Coordinator和tf.train.QueueRunner。這兩個類被設計為同時使用。Coordinator類幫助多線程同時停止,并向那些等待他們停止的程序報告異常。QueueRunner類被用來創建多個線程,這些線程用來協作在相同的隊列中入隊張量。

Coordinator

Coordinator類幫助多線程同時停止。 它的關鍵方法為:

  • tf.train.Coordinator.should_stop:如果線程應該停止,那么返回True
  • tf.train.Coordinator.request_stop:請求停止線程、
  • tf.train.Coordinator.join:等待,直到指定的線程已經停止

你首先創建一個Coordinator對象,然后創建一些線程來使用Coordinator。通常,線程運行循環,而這個循環會在should_stop()返回為True的時候終止。
任何線程可以決定這次計算應該終止。它僅僅需要調用requeststop(),然后其他線程會隨著shouldstop()返回為True而終止。

# Thread body: loop until the coordinator indicates a stop was requested.
# If some condition becomes true, ask the coordinator to stop.
def MyLoop(coord):
  while not coord.should_stop():
...do something...
if ...some condition...:
  coord.request_stop()

# Main thread: create a coordinator.
coord = tf.train.Coordinator()

# Create 10 threads that run 'MyLoop()'
threads = [##threading.Thread(target=MyLoop, args=(coord,)) for i in xrange(10)]

# Start the threads and wait for all of them to stop.
for t in threads:
  t.start()
coord.join(threads)

顯然,協調器能管理線程做不同的事情。他們并不需要像上述例子中一樣,全都是做同樣的事情。協調器同樣支持捕捉和報告異常。參見tf.train.Coordinator文檔獲取更詳細的信息。

QueueRunner

QueueRunner類創建一些線程,來反復的運行入隊操作。這些線程可以使用一個協調器來同時終止。除此之外,一個隊列運行器運行一個關系更為密切的線程,它在協調器報告異常的情況下,自動的關閉隊列。
你可以使用隊列UN星期來實現上述的架構。
首先構建一個圖,使用TenorFlow的隊列(比如tf.RandomShuffleQueue)來輸入樣本。然后添加操作來處理樣本,并講他們入隊。最后,添加以出隊元素開始的訓練操作。

example = ...ops to create one example...
# Create a queue, and an op that enqueues examples one at a time in the queue.
queue = tf.RandomShuffleQueue(...)
enqueue_op = queue.enqueue(example)
# Create a training graph that starts by dequeuing a batch of examples.
inputs = queue.dequeue_many(batch_size)
train_op = ...use 'inputs' to build the training part of the graph...  
在Python的訓練程序中,創建一個QueueRunner對象,會運行多個線程來處理和入隊樣本。創建一個Coordinator的對象,并用coordinator(協調器)來要求隊列運行器來啟動它的線程。編寫訓練的循環也可以使用coordinator(協調器)。
# Create a queue runner that will run 4 threads in parallel to enqueue
# examples.
qr = tf.train.QueueRunner(queue, [enqueue_op] * 4)

# Launch the graph.
sess = tf.Session()
# Create a coordinator, launch the queue runner threads.
coord = tf.train.Coordinator()
enqueue_threads = qr.create_threads(sess, coord=coord, start=True)
# Run the training loop, controlling termination with the coordinator.
for step in xrange(1000000):
    if coord.should_stop():
        break
    sess.run(train_op)
# When done, ask the threads to stop.
coord.request_stop()
# And wait for them to actually do it.
coord.join(enqueue_threads)  

處理異常

以隊列運行器開始的線程不僅僅是運行入隊操作。它們也會捕捉并處理由隊列產生的異常,這些異常包括tf.errors.OutOfRangeError異常,這個異常被用來報道隊列被關閉。
使用協調器的訓練程序必須在其主循環中,同樣地捕捉并報道異常。
這里是上面訓練循環的增強版。

try:
    for step in xrange(1000000):
        if coord.should_stop():
            break
        sess.run(train_op)
except Exception, e:
    # Report exceptions to the coordinator.
    coord.request_stop(e)
finally:
    # Terminate as usual. It is safe to call `coord.request_stop()` twice.
    coord.request_stop()
    coord.join(threads)
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容