人工智能AI培訓_TensorFlow 隊列與線程
深度學習的模型訓練過程往往需要大量的數據,而將這些數據一次性的讀入和預處理需要大量的時間開銷,所以通常采用隊列與多線程的思想解決這個問題,而且TensorFlow為我們提供了完善的函數。
本文介紹了TensorFlow的線程和隊列。在使用TensorFlow進行異步計算時,隊列是一種強大的機制。正如TensorFlow中的其他組件一樣,隊列就是TensorFlow圖中的節點。這是一種有狀態的節點,就像變量一樣:其他節點可以修改它的內容。具體來說,其他節點可以把新元素插入到隊列后端(rear),也可以把隊列前端(front)的元素刪除。
在Python中是沒有提供直接實現隊列的函數的,所以通常會使用列表模擬隊列。而TensorFlow提供了整套實現隊列的函數和方法,在TensorFlow中,隊列和變量類似,都是計算圖上有狀態的節點。操作隊列的函數主要有:
FIFOQueue():創建一個先入先出(FIFO)的隊列
RandomShuffleQueue():創建一個隨機出隊的隊列
enqueue_many():初始化隊列中的元素
dequeue():出隊 enqueue():入隊
與隊列Queue有關的有以下三個概念:
Queue是TF隊列和緩存機制的實現
QueueRunner是TF中對操作Queue的線程的封裝
Coordinator是TF中用來協調線程運行的工具
雖然它們經常同時出現,但這三樣東西在TensorFlow里面是可以單獨使用的,不妨先分開來看待。
1.Queue,隊列
根據實現的方式不同,分成具體的幾種類型,例如:
tf.FIFOQueue 按入列順序出列的隊列
tf.RandomShuffleQueue 隨機順序出列的隊列
tf.PaddingFIFOQueue 以固定長度批量出列的隊列
tf.PriorityQueue 帶優先級出列的隊列
...
這些類型的Queue除了自身的性質不太一樣外,創建、使用的方法基本是相同的,以下介紹兩個最常用的
1)tf.FIFOQueue(capacity, dtypes, name='fifo_queue') 創建一個以先進先出的順序對元素進行排隊的隊列
參數:
capacity:整數??赡艽鎯υ诖岁犃兄械脑財盗康纳舷?br> dtypes:DType對象列表。長度dtypes必須等于每個隊列元 素中的張量數,dtype的類型形狀,決定了后面進隊列元素形狀
方法:
q.dequeue()獲取隊列的數據
q.enqueue(值)將一個數據添加進隊列
q.enqueue_many(列表或者元組)將多個數據添加進隊列
q.size() 返回隊列的大小
2)、tf.RandomShuffleQueue() 隨機出的隊列
Queue主要包含入列(enqueue)和出列(dequeue)兩個操作。enqueue操作返回計算圖中的一個Operation節點,dequeue操作返回一個Tensor值。Tensor在創建時同樣只是一個定義(或稱為“聲明”),需要放在Session中運行才能獲得真正的數值。下面是一個單獨使用Queue的例子:
2. QueueRunner,隊列管理器
tf.train.QueueRunner(queue, enqueue_ops=None)
參數:
queue:A Queue
enqueue_ops:添加線程的隊列操作列表,[]*2,指定兩個線程
create_threads(sess, coord=None,start=False) 創建線程來運行給定會話的入隊操作
start:布爾值,如果True啟動線程;如果為False調用者 必須調用start()啟動線程
coord:線程協調器 用于線程的管理
Tensorflow的計算主要在使用CPU/GPU和內存,而數據讀取涉及磁盤操作,速度遠低于前者操作。因此通常會使用多個線程讀取數據,然后使用一個線程消費數據。QueueRunner就是來管理這些讀寫隊列的線程的。
QueueRunner需要與Queue一起使用(這名字已經注定了它和Queue脫不開干系),但并不一定必須使用Coordinator??聪旅孢@個例子:
增加計數的進程會不停的后臺運行,執行入隊的進程會先執行10次(因為隊列長度只有10),然后主線程開始消費數據,當一部分數據消費被后,入隊的進程又會開始執行。最終主線程消費完20個數據后停止,但其他線程繼續運行,程序不會結束。
3.Coordinator,線程協調器
tf.train.Coordinator() 線程協調員,實現一個簡單的機制來協調一 組線程的終止
方法: 返回的是線程協調實例
request_stop() 請求停止
join(threads=None, stop_grace_period_secs=120) 等待線程終止
Coordinator是個用來保存線程組運行狀態的協調器對象,它和TensorFlow的Queue沒有必然關系,是可以單獨和Python線程使用的。例如:
將這個程序運行起來,主線程會等待所有子線程都停止后結束,從而使整個程序結束。由此可見,只要有任何一個線程調用了Coordinator的request_stop方法,所有的線程都可以通過should_stop方法感知并停止當前線程。
將QueueRunner和Coordinator一起使用,實際上就是封裝了這個判斷操作,從而使任何一個現成出現異常時,能夠正常結束整個程序,同時主線程也可以直接調用request_stop方法來停止所有子線程的執行。