[英]TensorFlow: Enqueue tuple of tensors throws TypeError
我有一個基於時間的數據集,該數據集由分類特征,實值特征,表示該給定特征是否存在的掩碼以及一個包含出現值以來的時間長度的“增量”數組組成。
我想建立一個由這些張量組成的元組隊列,以便可以將分類特征轉換為熱特征,以便可以在模型的不同部分中使用數據,掩碼和增量。 以下是我為此編寫的一些代碼:
import tensorflow as tf
import threading
import numpy as np
# Function to generate batches of data
def nextBatch(batch_size):
n_steps = 14
batch = []
for _ in range(batch_size):
# Create tuple of tensors
ex = (np.random.randint(0,5, (n_steps, 2)),
np.random.randn(n_steps, 10),
np.random.randint(0,2, (n_steps, 12)),
np.random.randint(0,2000, (n_steps, 12)))
batch.append(ex)
return batch
# Graph to enqueue data
tf.reset_default_graph()
q = tf.PaddingFIFOQueue(1000,
[np.uint16, tf.float32, tf.uint16, tf.uint16],
[(None,5), (None,48), (None,53), (None,53)])
def enqueue_op():
# Stop enqueuing after 11 ops
i = 0
while True:
q.enqueue_many(nextBatch(100))
i += 1
if i >11:
return
# Start enqueuing
t = threading.Thread(target=enqueue_op)
t.start()
當我運行它時,我得到一個TypeError:
TypeError:預期的uint16,取而代之的是'ndarray'類型的array(...)。
我不確定自己在做什么錯,創建隊列時是dtype定義嗎?
這里有一些問題:
您的線程反復調用q.enqueue_many()
。 盡管使用q.enqueue_many()
方法的名稱(有點令人困惑),它不會立即將數據放入隊列中,而是返回一個tf.Operation
,該操作必須傳遞給sess.run()
才能在隊列中添加張量。 在單獨的線程中運行的代碼將創建10個入隊操作並將其丟棄,這可能不是您想要的。
nextBatch(100)
的返回值是一個包含4個數組的100個元組的列表。 q.enqueue_many()
方法需要一個由4個數組組成的元組。 如果要排隊包含100個元組的列表,則需要運行q.enqueue()
op 100次, 或將每個元組組件的100個數組堆疊在一起,以使您擁有四個數組的單個元組。
nextBatch()
產生的數組與隊列組件的形狀不匹配。 假設n_steps
是可以變化的維度(出於填充目的),該函數應生成(n_steps, 5)
, (n_steps, 48)
, (n_steps, 53)
和(n_steps, 53)
以匹配隊列定義。
這是您假設可以正常使用的代碼版本:
import tensorflow as tf
import threading
import numpy as np
# Function to generate batches of data
def nextBatch(batch_size):
n_steps = 14
batch = []
for _ in range(batch_size):
# Create tuple of tensors
ex = (np.random.randint(0,5, (n_steps, 5)),
np.random.randn(n_steps, 48),
np.random.randint(0,2, (n_steps, 53)),
np.random.randint(0,2000, (n_steps, 53)))
batch.append(ex)
return batch
q = tf.PaddingFIFOQueue(1000,
[tf.uint16, tf.float32, tf.uint16, tf.uint16],
[(None, 5), (None, 48), (None, 53), (None, 53)])
# Define a single op for enqueuing a tuple of placeholder tensors.
placeholders = [tf.placeholder(tf.uint16, shape=(None, 5)),
tf.placeholder(tf.float32, shape=(None, 48)),
tf.placeholder(tf.uint16, shape=(None, 53)),
tf.placeholder(tf.uint16, shape=(None, 53))]
enqueue_op = q.enqueue(placeholders)
# Create a session in order to run the enqueue_op.
sess = tf.Session()
def enqueue_thread_fn():
for i in range(10):
batch = nextBatch(100)
for batch_elem in batch:
# Each call to `sess.run(enqueue_op, ...)` enqueues a single element in
# the queue.
sess.run(enqueue_op, feed_dict={placeholders[0]: batch_elem[0],
placeholders[1]: batch_elem[1],
placeholders[2]: batch_elem[2],
placeholders[3]: batch_elem[3]})
# Start enqueuing
t = threading.Thread(target=enqueue_thread_fn)
t.start()
t.join()
sess.close()
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.