1. 程式人生 > >Tensorflow--tf.FIFOQueue詳解

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.]