代码之家  ›  专栏  ›  技术社区  ›  DocDriven

如何在使用输入管道时替换feed\u dict?

  •  2
  • DocDriven  · 技术社区  · 8 年前

    假设您有一个与 feed_dict 到目前为止,我们还没有将数据注入到图形中。每隔几个时期,我都会将其中一个数据集中的一批数据输入到我的图表中,以此来评估训练和测试损失。

    现在,出于性能原因,我决定使用一个输入管道。看看这个虚拟示例:

    import tensorflow as tf
    import numpy as np
    
    dataset_size = 200
    batch_size= 5
    dimension = 4
    
    # create some training dataset
    dataset = tf.data.Dataset.\
        from_tensor_slices(np.random.normal(2.0,size=(dataset_size,dimension)).
        astype(np.float32))
    
    dataset = dataset.batch(batch_size) # take batches
    
    iterator = dataset.make_initializable_iterator()
    x = tf.cast(iterator.get_next(),tf.float32)
    w = tf.Variable(np.random.normal(size=(1,dimension)).astype(np.float32))
    
    loss_func = lambda x,w: tf.reduce_mean(tf.square(x-w)) # notice that the loss function is a mean!
    loss = loss_func(x,w) # this is the loss that will be minimized
    train_op = tf.train.GradientDescentOptimizer(0.1).minimize(loss)
    
    with tf.Session() as sess:
        sess.run(tf.global_variables_initializer())
    
        # train one epoch
        sess.run(iterator.initializer)
        for i in range(dataset_size//batch_size):
            # the training step will update the weights based on ONE batch of examples each step
            loss1,_ = sess.run([loss,train_op])
            print('train step {:d}.  batch loss {:f}.'.format(i,loss1))
    
            # I want to print the loss from another dataset (test set) here
    

    打印丢失的训练数据是没有问题的,但是如何为另一个数据集执行此操作? 使用时 ,我简单地从所说的集合中得到一批,然后给它一个x值。

    1 回复  |  直到 8 年前
        1
  •  2
  •   javidcf    8 年前

    你可以为此做几件事。一个简单的选择可能是拥有两个数据集和迭代器并使用 tf.cond 在它们之间切换。但是,更强大的方法是使用直接支持它的迭代器。请参见上的指南 how to create iterators 各种迭代器类型的描述。例如,使用一个可重新初始化的迭代器,可以得到如下结果:

    import tensorflow as tf
    import numpy as np
    
    dataset_size = 200
    dataset_test_size = 20
    batch_size= 5
    dimension = 4
    
    # create some training dataset
    dataset = tf.data.Dataset.\
        from_tensor_slices(np.random.normal(2.0,size=(dataset_size,dimension)).
        astype(np.float32))
    
    dataset = dataset.batch(batch_size) # take batches
    
    # create some test dataset
    dataset_test = tf.data.Dataset.\
        from_tensor_slices(np.random.normal(2.0,size=(dataset_test_size,dimension)).
        astype(np.float32))
    
    dataset_test = dataset_test.batch(batch_size) # take batches
    
    iterator = tf.data.Iterator.from_structure(dataset.output_types,
                                               dataset.output_shapes)
    
    dataset_init_op = iterator.make_initializer(dataset)
    dataset_test_init_op = iterator.make_initializer(dataset_test)
    
    x = tf.cast(iterator.get_next(),tf.float32)
    w = tf.Variable(np.random.normal(size=(1,dimension)).astype(np.float32))
    
    loss_func = lambda x,w: tf.reduce_mean(tf.square(x-w)) # notice that the loss function is a mean!
    loss = loss_func(x,w) # this is the loss that will be minimized
    train_op = tf.train.GradientDescentOptimizer(0.1).minimize(loss)
    
    with tf.Session() as sess:
        sess.run(tf.global_variables_initializer())
    
        # train one epoch
        sess.run(dataset_init_op)
        for i in range(dataset_size//batch_size):
            # the training step will update the weights based on ONE batch of examples each step
            loss1,_ = sess.run([loss,train_op])
            print('train step {:d}.  batch loss {:f}.'.format(i,loss1))
    
        # print test loss
        sess.run(dataset_test_init_op)
        for i in range(dataset_test_size//batch_size):
            loss1 = sess.run(loss)
            print('test step {:d}.  batch loss {:f}.'.format(i,loss1))
    

    你可以用feedable迭代器做一些类似的事情,这取决于你觉得什么更方便,我想甚至可以用一个可初始化的迭代器,例如,生成一个布尔数据集,然后用它映射到一些数据 tf.条件 ,尽管这不是一个很自然的方法。


    下面是如何用一个可初始化的迭代器来实现它,实际上比我最初想的更简洁,所以也许你更喜欢这样:

    import tensorflow as tf
    import numpy as np
    
    dataset_size = 200
    dataset_test_size = 20
    batch_size= 5
    dimension = 4
    
    # create data
    data = tf.constant(np.random.normal(2.0,size=(dataset_size,dimension)), tf.float32)
    data_test = tf.constant(np.random.normal(2.0,size=(dataset_test_size,dimension)), tf.float32)
    # choose data
    testing = tf.placeholder_with_default(False, ())
    current_data = tf.cond(testing, lambda: data_test, lambda: data)
    # create dataset
    dataset = tf.data.Dataset.from_tensor_slices(current_data)
    dataset = dataset.batch(batch_size)
    # create iterator
    iterator = dataset.make_initializable_iterator()
    
    x = tf.cast(iterator.get_next(),tf.float32)
    w = tf.Variable(np.random.normal(size=(1,dimension)).astype(np.float32))
    
    loss_func = lambda x,w: tf.reduce_mean(tf.square(x-w)) # notice that the loss function is a mean!
    loss = loss_func(x,w) # this is the loss that will be minimized
    train_op = tf.train.GradientDescentOptimizer(0.1).minimize(loss)
    
    with tf.Session() as sess:
        sess.run(tf.global_variables_initializer())
    
        # train one epoch
        sess.run(iterator.initializer)
        for i in range(dataset_size//batch_size):
            # the training step will update the weights based on ONE batch of examples each step
            loss1,_ = sess.run([loss,train_op])
            print('train step {:d}.  batch loss {:f}.'.format(i,loss1))
    
        # print test loss
        sess.run(iterator.initializer, feed_dict={testing: True})
        for i in range(dataset_test_size//batch_size):
            loss1 = sess.run(loss)
            print('test step {:d}.  batch loss {:f}.'.format(i,loss1))
    
    推荐文章