Я пытаюсь получить данные из двух разных источников dataset
с тензорным потоком. Я написал следующий код:
Сначала я пробовал следующее:
import tensorflow as tf
import numpy as np
iters = []
def return_data1():
d1 = tf.data.Dataset.range(1, 2000)
iter1 = d1.make_initializable_iterator()
iters.append(iter1)
data1 = iter1.get_next()
return data1
def return_data2():
d2 = tf.data.Dataset.range(2000, 4000)
iter2 = d2.make_initializable_iterator()
iters.append(iter2)
data2 = iter2.get_next()
return data2
test = tf.placeholder(dtype=tf.bool)
data = tf.cond(test, lambda: return_data1(), lambda: return_data2())
iter1 = iters[0]
iter2 = iters[1]
init_op = tf.global_variables_initializer()
with tf.Session() as sess:
sess.run(init_op)
sess.run([iter1.initializer, iter2.initializer])
for i in range(2000):
if i < 1000:
print(sess.run(data, feed_dict={test: True}), "..")
else:
print(sess.run(data, feed_dict={test: False}), "--")
И я получил следующую ошибку:
ValueError: Operation 'cond/MakeIterator' has been marked as not fetchable.
1- Я хотел бы знать, почему я получаю такое поведение.
Затем я попытался исправить свой код, поэтому написал следующее:
d1 = tf.data.Dataset.range(1, 2000)
d2 = tf.data.Dataset.range(2000, 4000)
iter1 = d1.make_initializable_iterator()
iter2 = d2.make_initializable_iterator()
data1 = iter1.get_next()
data2 = iter2.get_next()
def return_data1():
return data1
def return_data2():
return data2
test = tf.placeholder(dtype=tf.bool)
data = tf.cond(test, lambda: return_data1(), lambda: return_data2())
init_op = tf.global_variables_initializer()
with tf.Session() as sess:
sess.run(init_op)
sess.run([iter1.initializer, iter2.initializer])
for i in range(2000):
if i < 1000:
print(sess.run(data, feed_dict={test: True}), "..")
else:
print(sess.run(data, feed_dict={test: False}), "--")
И из print
я получаю цифры от 1 до 1000 от первого набора данных, но когда i
становлюсь больше 1000, он начинает печатать 3000 → 4000
. Поэтому я пришел к выводу, что по мере того, как первый набор данных был запущен или как я был доставлен 1000
элементов из второго набора данных, но они были проигнорированы.
Позже, когда я исправил свой код, переместив data1 = iter1.get_next()
и data2 = iter2.get_next()
в определение функции как:
def return_data1():
data1 = iter1.get_next()
return data1
А ТАКЖЕ
def return_data2():
data2 = iter2.get_next()
return data2
Код работает, и теперь печатает числа 1 → 1000
и 2000 → 3000
.
Я хотел бы понять, почему это происходит, чтобы избежать подобных ошибок в будущем.
Я обнаружил такую же проблему с tf.control_dependency
, которая принимает операцию как аргумент и эта операция не должна создаваться вне. Это поведение немного смутило меня, и все же я хотел бы знать, почему это происходит с тензорным потоком.
Во-вторых, если я хотел бы выбрать из более чем двух источников наборов данных и запускать их отдельно, как это сделать в тензорном потоке?
Любая помощь приветствуется!!!
Вот как получить данные из нескольких наборов данных отдельно. Тем не менее, я хотел бы узнать ответ на мои другие вопросы относительно поведения тензорного потока и почему в data2 = iter2.get_next()
должен быть определен data2 = iter2.get_next()
.
import tensorflow as tf
import numpy as np
d1 = tf.data.Dataset.range(1, 1000)
iter1 = d1.make_initializable_iterator()
d2 = tf.data.Dataset.range(1000, 2000)
iter2 = d2.make_initializable_iterator()
d3 = tf.data.Dataset.range(2000, 3000)
iter3 = d3.make_initializable_iterator()
d4 = tf.data.Dataset.range(3000, 4000)
iter4 = d4.make_initializable_iterator()
def return_data1_2():
data1 = iter1.get_next()
data2 = iter2.get_next()
return data1, data2
def return_data2_3():
data2 = iter2.get_next()
data3 = iter3.get_next()
return data2, data3
def return_data3_4():
data3 = iter3.get_next()
data4 = iter4.get_next()
return data3, data4
def return_data4_1():
data4 = iter4.get_next()
data1 = iter1.get_next()
return data4, data1
index1 = tf.placeholder(dtype=tf.int32)
index2 = tf.placeholder(dtype=tf.int32)
data = tf.case(pred_fn_pairs=[
(tf.logical_and(tf.equal(index1, 1), tf.equal(index2, 2)), lambda: return_data1_2()),
(tf.logical_and(tf.equal(index1, 2), tf.equal(index2, 3)), lambda: return_data2_3()),
(tf.logical_and(tf.equal(index1, 3), tf.equal(index2, 4)), lambda: return_data3_4()),
(tf.logical_and(tf.equal(index1, 4), tf.equal(index2, 1)), lambda: return_data4_1())], exclusive=False)
init_op = tf.global_variables_initializer()
with tf.Session() as sess:
sess.run(init_op)
sess.run([iter1.initializer, iter2.initializer, iter3.initializer, iter4.initializer])
for i in range(2000):
try:
if i < 500:
print(sess.run(data, feed_dict={index1: 1, index2: 2}), "1-2")
elif i < 1000:
print(sess.run(data, feed_dict={index1: 2, index2: 3}), "2-3")
elif i < 1500:
print(sess.run(data, feed_dict={index1: 3, index2: 4}), "3-4")
elif i < 2000:
print(sess.run(data, feed_dict={index1: 4, index2: 1}), "4-1")
except tf.errors.OutOfRangeError as error:
print("error")