代码之家  ›  专栏  ›  技术社区  ›  I. A Ziang Yan

使用dataset api从两个不同的数据源获取数据时了解tensorflow行为

  •  1
  • I. A Ziang Yan  · 技术社区  · 7 年前

    我试图从两个不同的 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.
    

    我想知道我为什么会有这种行为。

    然后,我试图修复我的代码,所以我写了以下内容:

    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 ,它接受该操作作为参数,并且该操作不应在外部创建。这种行为让我困惑了一段时间,但我想知道为什么TensorFlow会发生这种情况。

    第二,如果我想从两个以上的数据源中进行选择并分别运行它们,在tensorflow中如何做到这一点?

    任何帮助都将不胜感激!!!

    1 回复  |  直到 7 年前
        1
  •  0
  •   I. A Ziang Yan    7 年前

    下面是如何分别从多个数据集中获取数据。但是我想知道关于tensorflow行为的其他问题的答案,为什么 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")
    
    推荐文章