当前位置:   article > 正文

tensorflow读取数据的方式_用生成器为模型读入数据的方法

用生成器为模型读入数据的方法

1、第一种方式通过占位符feed_dict的方式读入;

2、通过dataset的方式读入:

1)导入数据:从一些数据中创建一个Dataset实例;

2)创建一个迭代器:通过使用创建的数据集来制作一个迭代器实例迭代遍历数据集;

3)使用数据:通过使用创建的迭代器,我们可以得到数据集的元素馈送给模型;

1 从numpy导入数据

常见的情况下,我们有一个numpy数组,我们想通过它传送到tensorflow。

# create a random vector of shape (100,2)
x = np.random.sample((100,2))
# make a dataset from a numpy array
dataset = tf.data.Dataset.from_tensor_slices(x) 

我们也可以通过多个numpy数组,一个典型的例子是当我们将数据分为特征和标签时

features, labels = (np.random.sample((100,2)), np.random.sample((100,1)))
dataset = tf.data.Dataset.from_tensor_slices((features,labels)) 

2 从tensor导入数据

当然,我们可以用一些张量来初始化我们的数据集

# using a tensor
dataset = tf.data.Dataset.from_tensor_slices(tf.random_uniform([100, 2]))

3 从placeholder(占位符)导入数据

当我们想动态地改变数据集里面的数据时,placeholder是很有用的,我们稍后会做。

x = tf.placeholder(tf.float32, shape=[None,2])
dataset = tf.data.Dataset.from_tensor_slices(x)

4 从生成器导入数据

我们也可以从一个生成器初始化一个数据集,当我们有一个长度不同的元素数组(例如一个序列)时,这种方法非常有用的:

sequence = np.array([[1],[2,3],[3,4]])
def generator():
    for el in sequence:
        yield el
dataset = tf.data.Dataset().from_generator(generator,
                                           output_types=tf.float32, 
                                           output_shapes=[tf.float32])

5创建迭代器(Iterator)

我们已经知道如何创建一个数据集,但是如何获取我们的数据呢? 那就必须使用迭代器,它使我们能够遍历数据集并找到数据的实际值。 有四种类型的迭代器。

1 One Shot迭代器

这是最简单的迭代器,请看下面的例子

x = np.random.sample((100,2))
# make a dataset from a numpy array
dataset = tf.data.Dataset.from_tensor_slices(x)
# create the iterator
iter = dataset.make_one_shot_iterator()

然后,您需要调用get_next()来获取包含你的数据的张量

...
# create the iterator
iter = dataset.make_one_shot_iterator()
el = iter.get_next()

我们可以运行el看到它的值

with tf.Session() as sess:
    print(sess.run(el)) # output: [ 0.42116176  0.40666069] 

2 可初始化迭代器

如果我们要构建一个动态数据集,我们可以实时更改数据源,可以使用占位符创建数据集。然后我们可以使用feed-dict机制来初始化占位符。这是用一个可初始化的迭代器完成的。使用上一节的示例三

# using a placeholder
x = tf.placeholder(tf.float32, shape=[None,2])
dataset = tf.data.Dataset.from_tensor_slices(x)
data = np.random.sample((100,2))
iter = dataset.make_initializable_iterator() # create the iterator
el = iter.get_next()
with tf.Session() as sess:
    # feed the placeholder with data
    sess.run(iter.initializer, feed_dict={ x: data }) 
    print(sess.run(el)) # output [ 0.52374458  0.71968478]

我们调用make_initializable_iterator。 然后,在sess范围内,我们运行初始化操作来传递我们的数据,在这种情况下数据是一个随机的numpy数组。

想象一下,在实际场景中,我们有一个训练集和一个测试集:

train_data = (np.random.sample((100,2)), np.random.sample((100,1)))
test_data = (np.array([[1,2]]), np.array([[0]]))

我们想训练模型,然后在测试数据集上评估它,这可以通过在训练之后再次初始化迭代器来完成

# initializable iterator to switch between dataset
EPOCHS = 10
x, y = tf.placeholder(tf.float32, shape=[None,2]), tf.placeholder(tf.float32,
 shape=[None,1])
dataset = tf.data.Dataset.from_tensor_slices((x, y))
train_data = (np.random.sample((100,2)), np.random.sample((100,1)))
test_data = (np.array([[1,2]]), np.array([[0]]))
iter = dataset.make_initializable_iterator()
features, labels = iter.get_next()
with tf.Session() as sess:
#     initialise iterator with train data
    sess.run(iter.initializer, feed_dict={ x: train_data[0], 
y: train_data[1]})
    for _ in range(EPOCHS):
        sess.run([features, labels])
#     switch to test data
    sess.run(iter.initializer, feed_dict={ x: test_data[0], y: test_data[1]})
    print(sess.run([features, labels]))

3 重新初始化的迭代器

这个概念与上一个类似,我们要在数据之间进行动态切换。 但是,不是将新数据馈送到相同的数据集,而是切换数据集。和以前一样,我们要有一个训练数据集和一个测试数据集

# making fake data using numpy
train_data = (np.random.sample((100,2)), np.random.sample((100,1)))
test_data = (np.random.sample((10,2)), np.random.sample((10,1)))

我们可以创建两个数据集

# create two datasets, one for training and one for test
train_dataset = tf.data.Dataset.from_tensor_slices(train_data)
test_dataset = tf.data.Dataset.from_tensor_slices(test_data) 

现在要使用一个技巧,即创建一个通用的迭代器

# create a iterator of the correct shape and type
iter = tf.data.Iterator.from_structure(train_dataset.output_types,
                                           train_dataset.output_shapes) 

然后进行两次初始化操作:

# create the initialisation operations
train_init_op = iter.make_initializer(train_dataset)
test_init_op = iter.make_initializer(test_dataset)

我们像以前一样得到下一个元素

features, labels = iter.get_next()

现在,我们可以使用我们的会话直接运行两个初始化操作。综合起来,我们得到:

# Reinitializable iterator to switch between Datasets
EPOCHS = 10
# making fake data using numpy
train_data = (np.random.sample((100,2)), np.random.sample((100,1)))
test_data = (np.random.sample((10,2)), np.random.sample((10,1)))
# create two datasets, one for training and one for test
train_dataset = tf.data.Dataset.from_tensor_slices(train_data)
test_dataset = tf.data.Dataset.from_tensor_slices(test_data)
# create a iterator of the correct shape and type
iter = tf.data.Iterator.from_structure(train_dataset.output_types,
                                           train_dataset.output_shapes)
features, labels = iter.get_next()
# create the initialisation operations
train_init_op = iter.make_initializer(train_dataset)
test_init_op = iter.make_initializer(test_dataset)
with tf.Session() as sess:
    sess.run(train_init_op) # switch to train dataset
    for _ in range(EPOCHS):
        sess.run([features, labels])
    sess.run(test_init_op) # switch to val dataset
    print(sess.run([features, labels]))

4 可馈送的迭代器(Feedable Iterator)

老实说,我不认为这个方法是有用的。它不是在数据集之间切换,而是在迭代器之间切换,例如,您可以从make_one_shot_iterator()获得一个迭代器,而从make_initializable_iterator()获得另一个迭代器。

使用数据

 

在前面的例子中,我们使用会话来打印数据集中下一个元素的值

...
next_el = iter.get_next()
...
print(sess.run(next_el)) # will output the curr 

为了将数据传递给模型,我们必须通过张量从get_next()生成。在下面的代码片段中,我们有一个包含两个numpy数组的数据集,使用第一节中的示例。注意我们需要将.random.sample封装到另一个numpy数组中,以添加一个维度,我们需要批量处理数据

# using two numpy arrays
features, labels = (np.array([np.random.sample((100,2))]), 
                    np.array([np.random.sample((100,1))]))
dataset = tf.data.Dataset.from_tensor_slices((features,labels)).
repeat().batch(BATCH_SIZE)

然后像往常一样,我们创建一个迭代器

iter = dataset.make_one_shot_iterator()
x, y = iter.get_next() 

我们做一个模型,一个简单的神经网络

# make a simple model
net = tf.layers.dense(x, 8) # pass the first value from iter.get_next() 
as input
net = tf.layers.dense(net, 8)
prediction = tf.layers.dense(net, 1)
loss = tf.losses.mean_squared_error(prediction, y) # pass the second value 
from iter.get_net() as label
train_op = tf.train.AdamOptimizer().minimize(loss) 

我们直接使用iter.get_next()中的张量作为第一层的输入,并作为损失函数的标签。 一起封装:

EPOCHS = 10
BATCH_SIZE = 16
# using two numpy arrays
features, labels = (np.array([np.random.sample((100,2))]), 
                    np.array([np.random.sample((100,1))]))
dataset = tf.data.Dataset.from_tensor_slices((features,labels)).repeat().
batch(BATCH_SIZE)
iter = dataset.make_one_shot_iterator()
x, y = iter.get_next()
# make a simple model
net = tf.layers.dense(x, 8, activation=tf.tanh) # pass the first value 
from iter.get_next() as input
net = tf.layers.dense(net, 8, activation=tf.tanh)
prediction = tf.layers.dense(net, 1, activation=tf.tanh)
loss = tf.losses.mean_squared_error(prediction, y) # pass the second value 
from iter.get_net() as label
train_op = tf.train.AdamOptimizer().minimize(loss)
with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    for i in range(EPOCHS):
        _, loss_value = sess.run([train_op, loss])
        print("Iter: {}, Loss: {:.4f}".format(i, loss_value)) 
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小丑西瓜9/article/detail/123861
推荐阅读
相关标签
  

闽ICP备14008679号