Tensorflow--tf.FIFOQueue詳解
Tensorflow–tf.FIFOQueue詳解
描述
tf.FIFOQueue根據先進先出(FIFO)的原則建立一個佇列。佇列是Tensorflow的一種資料結構,每個佇列的元素都是包含一個或多個張量的元組,每個元組都有靜態的型別和尺寸。入列和出列可以支援一次一個元素,或一次一批元素。它繼承於Tensorflow佇列執行的基類tf.QueueBase。佇列是Tensorflow計算圖非同步處理張量的重要物件。
初始化
init
__init__( capacity, dtypes, shapes=None, names=None, shared_name=None, name='fifo_queue' )
建立一個佇列元素按照先進先出的順序出列的佇列。
屬性
- capacity
整形數字,標識佇列可以儲存的元素的最大數量 - dtypes
一個Dtype物件的列表,長度等於佇列元素中的張量個數 - shapes
佇列元素中的每個組成部分的尺寸物件組成的列表 - name
佇列操作的命名 - shared_name
佇列在不同session共享時使用的名稱 - names
佇列元素中的每個組成部分的命名組成的列表
方法
- close
close( cancel_pending_enqueues=False, name=None )
此方法用來關閉佇列,標示沒有元素再入列,如果佇列中還有元素,則出列操作可以執行,否則會失敗。
引數:
cancel_pending_enqueues: 可選,boolean型別,預設False,為True的時候,掛起的請求將被取消;
name:可選,佇列操作的名稱
返回:
返回佇列的關閉操作
- dequeue
dequeue(name=None)
從佇列中移出一個元素。當佇列為空的時候,將會阻止此操作,直到有一個元素可以出列。
佇列關閉的情況下,操作會報錯。如果佇列為空且沒有入列操作可執行,則報 tf.errors.OutOfRangeError錯誤。 如果執行此操作的session關閉, 將報tf.errors.CancelledError錯誤。
引數:
name:可選,佇列操作的名稱
返回:
返回包含出列張量的元組
- dequeue_many
dequeue_many(
n,
name=None
)
將n個元素連線到一起移出佇列。本操作會將張量的第0維連線到一起形成一個張量出列,所以所有出列的元素組成的元組的第0維的尺寸為n。
如果佇列已經關閉,或是佇列中剩餘的元素少於n個且沒有要執行的入列操作會填充佇列,則會報 OutOfRange exception的錯。如果session關閉,則會報 tf.errors.CancelledError的錯。
引數:
n: 出列張量包含的元素個數
name:可選,佇列操作的名稱
返回:
一組連線在一起出列張量組成的列表。
- dequeue_up_to
dequeue_up_to(
n,
name=None
)
將n個元素連線到一起移出佇列。本操作會將張量的第0維連線到一起形成一個張量出列,所以如果佇列沒有關閉,所有出列的元素組成的元組的第0維的尺寸為n。
如果佇列已經關閉且佇列中剩餘的元素大於0少於n,則不會像dequeue_many報 OutOfRange exception的錯,而是會立即返回少於n的元素。如果佇列已經關閉且佇列中剩餘的元素等於0,則會像dequeue_many一樣報OutOfRange exception的錯。其他的操作和dequeue_many一樣。
注意:不是所有的佇列都支援這個操作,如果佇列不支援這個操作,會報tf.errors.UnimplementedError錯。
引數:
n: 出列張量包含的元素個數
name:可選,佇列操作的名稱
返回:
一組連線在一起出列張量組成的元組。
- enqueue
enqueue(
vals,
name=None
)
佇列中入列一個元素。如果執行的時候佇列已滿,將會阻止操作。如果佇列關閉,執行會報tf.errors.CancelledError錯。如果佇列關閉的時候設定cancel_pending_enqueues=True或session關閉,操作會阻止且報tf.errors.CancelledError錯誤。
引數:
vals: 入列的資料,可以是張量、張量組成的列表或元組,或是字典
name:可選,佇列操作的名稱
返回:
一組張量的入列操作
- enqueue_many
enqueue_many(
vals,
name=None
)
入列0或多個元素。本操作將每個元素的第0維切分出來組成多個佇列元素作為輸入,輸入的張量第0維的大小要相同。如果佇列已滿,操作會被阻止。如果佇列關閉,將報tf.errors.CancelledError錯。如果佇列關閉的時候設定cancel_pending_enqueues=True或session關閉,操作會阻止且報tf.errors.CancelledError錯誤。
引數:
vals: 入列的資料,可以是張量、張量組成的列表或元組,或是字典
name:可選,佇列操作的名稱
返回:
一批張量的入列操作
- is_closed
is_closed(name=None)
佇列關閉,返回true;否則,返回false
引數:
name:可選,佇列操作的名稱
返回:
佇列關閉,返回true;否則,返回false
- size
size(name=None)
計算佇列的元素數目
引數:
name:可選,佇列操作的名稱
返回:
包含佇列元素數目的張量
示例
舉幾個例子幫助理解佇列的出列和入列
import tensorflow as tf
input_data=[[3.,2.,1.],[11.,22.,33.],[111.,222.,333.]]
q=tf.FIFOQueue(3,dtypes=[tf.float32])
init=q.enqueue(input_data)
output_data=q.dequeue()
with tf.Session() as sess:
init.run()
init.run()
print('1:',sess.run(output_data))
print('2:',sess.run(output_data))
print('3:',sess.run(output_data))
sess.run(q.close(cancel_pending_enqueues=True))
print(sess.run(q.is_closed()))
執行結果為
1: [3. 2. 1.]
2: [3. 2. 1.]
True
import tensorflow as tf
input_data=[[3.,2.,1.],[11.,22.,33.],[111.,222.,333.]]
input_data1=[[33.,22.,11.],[11.,22.,33.],[111.,222.,333.]]
q=tf.FIFOQueue(3,dtypes=[tf.float32])
init=q.enqueue(input_data)
init1=q.enqueue(input_data1)
output_data=q.dequeue()
with tf.Session() as sess:
init.run()
init1.run()
print('1:',sess.run(output_data))
print('2:',sess.run(output_data))
print('3:',sess.run(output_data))
sess.run(q.close(cancel_pending_enqueues=True))
print(sess.run(q.is_closed()))
執行結果為
1: [3. 2. 1.]
2: [33. 22. 11.]
True
enqueue()每次入列一個元素,對於同一個輸入資料,多次入列會重複入列相同元素。dequeue()每次出列一個元素。
import tensorflow as tf
input_data=[[3.,2.,1.],[11.,22.,33.],[111.,222.,333.]]
print(tf.shape(input_data))
q=tf.FIFOQueue(3,dtypes=[tf.float32],shapes=[[]])
init=q.enqueue_many(input_data)
output_data=q.dequeue()
with tf.Session() as sess:
init.run()
print('1:',sess.run(output_data))
print('2:',sess.run(output_data))
print('3:',sess.run(output_data))
sess.run(q.close(cancel_pending_enqueues=True))
print(sess.run(q.is_closed()))
執行結果:
Tensor("Shape:0", shape=(2,), dtype=int32)
1: 3.0
2: 2.0
3: 1.0
True
因為shapes=[[]],所以輸入資料input_data=[[3.,2.,1.],[11.,22.,33.],[111.,222.,333.]]只有[3.,2.,1.]入列,所有第0維的張量為3.,2.,1.,enqueue_many會將他們組合在一起輸入佇列,所以佇列的元素為3.,2.,1.
修改程式碼為:
import tensorflow as tf
input_data=[[3.,2.,1.],[11.,22.,33.],[111.,222.,333.]]
print(tf.shape(input_data))
q=tf.FIFOQueue(3,dtypes=[tf.float32,tf.float32],shapes=[[],[]])
init=q.enqueue_many(input_data)
output_data=q.dequeue()
with tf.Session() as sess:
init.run()
print('1:',sess.run(output_data))
print('2:',sess.run(output_data))
print('3:',sess.run(output_data))
sess.run(q.close(cancel_pending_enqueues=True))
print(sess.run(q.is_closed()))
執行結果為
Tensor("Shape:0", shape=(2,), dtype=int32)
1: [3.0, 11.0]
2: [2.0, 22.0]
3: [1.0, 33.0]
True
因為shapes=[[],[]],所以輸入資料input_data=[[3.,2.,1.],[11.,22.,33.],[111.,222.,333.]]有[[3.,2.,1.],[11.,22.,33.]]入列,先將[3.,2.,1.]和[11.,22.,33.]第0維的3.和11.組合成一個張量[3.0, 11.0],然後2.和22.就變為0維度,組成第二個張量[2.0, 22.0],最後1.和33.變為0維度,組成第三個張量[1.0, 33.0],所以佇列的元素為 [3.0, 11.0],[2.0, 22.0],[1.0, 33.0]
修改程式碼
import tensorflow as tf
input_data=[[3.,2.,1.],[11.,22.,33.],[111.,222.,333.]]
q=tf.FIFOQueue(3,dtypes=[tf.float32,tf.float32],shapes=[[],[]])
init = q.enqueue_many(input_data)
output_data_many=q.dequeue_many(2)
with tf.Session() as sess:
init.run()
print("Many:", sess.run(output_data_many))
sess.run(q.close(cancel_pending_enqueues=True))
print(sess.run(q.is_closed()))
執行結果
Many: [array([3., 2.], dtype=float32), array([11., 22.], dtype=float32)]
True
如上例佇列的元素為 [3.0, 11.0],[2.0, 22.0],[1.0, 33.0],dequeue_many(2)將佇列元素的第0維3.,2.,1.中取2個數據組成[3., 2.],然後11.,22.,33.變為第0維,再取2個數據組成[11., 22.],所以出列的資料為[[3., 2.],[11., 22.],]
import tensorflow as tf
input_data=[[[3.,2.,1.],[11.,22.,33.],[111.,222.,333.]],[[23.,22.,21.],[211.,222.,233.],[2111.,2222.,2333.]]]
print(tf.shape(input_data))
q=tf.FIFOQueue(3,tf.float32)
init=q.enqueue_many(input_data)
output_data=q.dequeue()
with tf.Session() as sess:
init.run()
print('1:',sess.run(output_data))
print('2:',sess.run(output_data))
print('3:',sess.run(output_data))
sess.run(q.close(cancel_pending_enqueues=True))
print(sess.run(q.is_closed()))
執行結果:
Tensor("Shape:0", shape=(3,), dtype=int32)
1: [3. 2. 1.]
2: [11. 22. 33.]
3: [111. 222. 333.]
True
輸入資料input_data=[[[3.,2.,1.],[11.,22.,33.],[111.,222.,333.]],[[23.,22.,21.],[211.,222.,233.],[2111.,2222.,2333.]]]為三維,所有第0維的張量為[3. 2. 1.],[11. 22. 33.], [111. 222. 333.],enqueue_many會將他們組合在一起輸入佇列,所以佇列的元素為[3. 2. 1.],[11. 22. 33.], [111. 222. 333.]