三三文章网 - 科技知识大全是专业科技新媒体网站。网站著眼于新一代科技新闻的全面及时处理报导,让网民在外面第二时间交待全球新一代的科技资讯。内容涵括AI+、互联网、IT、创业投资、核定、区块链、智能硬件等领域

数据加载太慢吗?TensorFlow加速指南-有量子比特

  • 时间:
  • 浏览:0

机器学习算法深入人心,网络结构会随手绊倒,但当数据集加载花费大量时间时,整个培训时间会大大增加。

这个问题可能困扰着许多使用大规模数据集训练的炼丹师们。最近,Francesco Zuppichini的medium上的一篇文章从使用Dataset函数的三个步骤介绍了相应的解决方案。

以下内容翻译成他的文章。

阅读本文后,不要使用默认输入函数feed-dict。

本文将TensorFlow1.5作为标准函数库。根据以往的经验,在TensorFlow中,feed-dict函数是最慢的数据加载方法,可能是尽可能少的方法。在模型中输入数据的最佳方法是使用输入管线确保GPU不需要等待新数据输入。

幸运的是,TensorFlow有一个名为Dataset的内置接口。此接口在1.3版中提出,以便更容易地实现数据输入。本教程介绍如何创建输入管线并有效地将数据输入模型。

本文还描述了Dataset接口的基本原理,包括最常见的几种用法。

所有代码都可以从该网站获取

https://github.com/FrancescoSaverioZuppichini/Tensorflow-Dataset-Tutorial/blob/master/dataset_tutorial.ipynb

要使用数据集接口,请执行以下三个步骤:。

1.导入数据并从特定数据创建数据集实例。

2.使用现有数据集创建迭代实例,并创建迭代器iterator来迭代数据集。

3.使用创建的迭代器从数据集中检索元素,并消耗要输入到模型中的数据。

首先,可以通过以下方法将数据部署到数据集中:。

使用数字

这是一种常见的方法,在tensorflow中输入空数组。

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

您还可以输入多个空数组。一个典型的例子是根据特征和标签对一些数据进行分类

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

使用Tensors

当然,可以使用Tensor初始化数据集。

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

使用放置架

此方法非常适合需要多次更改数据集函数中的数据,稍后将详细说明。

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

使用生成器

还可以使用生成器生成器生成器初始化数据集。用于处理不同长度的元素,例如序列。

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

在这种情况下,为了获得适当的Tensor,还必须指定输入数据的类型和形状。

上面介绍了数据集的制作方法,如何取出里面的数据呢。这里使用迭代器Iterator遍历整个数据集并检索数据的实际值。有四种类型:。

One shot迭代器

这是最简单的迭代器,使用上节示例1:

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

然后,get_next()函数用于获取以下数据张量:。

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

然后执行el函数以获得输出值。

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

可初始化迭代器

如果要构建动态数据集并在运行时更改源数据,则必须选择占位符placeholder来创建数据集,并使用经典的feed-dict方法初始化占位符。您可以使用“使用Placeholder”部分中的示例使用可初始化的迭代器来执行这些操作。

# using a placeholderx = 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 iteratorel = 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范围内,执行initializer函数传递数据。这里首先以随机数组为例。

在这里,我们构建了培训集和测试集。

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 datasetEPOCHS = 10x, y = tf.placeholder(tf.float32, shape=[None,2]),tf.placeholder(tf.float32, shape=[None,1])dataset = tf.dataset.from _ tensor-slices )x,y) train_data=(np.随机.sample)100,2、,np.随机.sample)1100)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])

它是一个可重新初始化的小望远镜

这是像刚才那样动态切换数据的概念。但是,上面是在同一数据集中输入新数据,这里是切换数据集。以同样的方式创建训练数据集和测试数据集

# making fake data using numpytrain_data=(np.random.sample)100,2、,np.随机.sample)1100)test_data=(np.随机.sample)10,2、,np.随机.sample(10,1、

可以创建两个数据集

#create two datasets,one for training and one for testrain_dataset = tf.datet.from _ tensor.slices (train_data)test_dataset = tf.datet.from _ tensor.slices (train_data)test_dataset=tf.dataset。tf.data.datet.from _ tensor.slices(test_data)

其中最重要的是构建通用的操作器

# create a iterator of the correct shape and typeiter = tf.data. iterator .from_structure(train_dataset.output_types,train_dataset.output_shapes。

然后初始化数据集

# create the initialisation operationstrain_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 DatasetsEPOCHS = 10# making fake data using numpytrain_data=10。(np.随机.sample)100,2、,np.随机.sample)1100)test_data=(np.随机.sample)10,2、,np.random.sample(10,1、#create two datasets,one for training and one for testtrain_dataset = tf.datet.from _ tensor.slices (train_data)test_dataset = tf.datet.from _ tensor.slices (train_data)test_dataset=tf.dataset。tf.data.datet.from _ tensor.slices (test_data)# create a iterator of the correct shape and typeiter =tf.data.iterator.from _structure(train_dataset.output_types, train_dataset.output_shapes)features,labels = iter.get_next()# create the initialisation operationstrain_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)

提供遥测数据

我想,这些方法可能行不通。基本上不是切换数据集,而是切换小程序。make_one_shot_iterator函数和make_initializable_可以用iterator函数创建两个小程序。

在前面的示例中,Session用于输出数据集元素next的值:

…next_el = iter.get_next()…print(sess.run(next_el)#will output the current element

将数据传递给模型的步骤get_next函数生成的张量

以下代码段包含两个空数组的数据集在这里使用第一节中的示例来满足数据批量化的维要求。将random.sample函数包装到另一个numpy数组中。

# using two numpy arraysfeatures, labels = (np.array([np.random.sample)100,2、]),np.array([np.random.sample)100,1、])dataset =tf.data.datet.from _ tensor.slices )features,labels).repeat().batch(batch _ size)

然后我们做一个小望远镜,和上面一样

iter = dataset.make_one_ sht _iterator()x, y = iter.get_next()

建立一个简单的神经网络模型

#makeasimplemodelnet=TF.layers.dense(x,8、#passthefirstvaluefromIter.get_next)asinputnet=TF.layers.) 8、prediction=TF.layers.dense(net,1、loss=TF.losses.mean_squared_error)prediction,y)#passthesection

我们直接从iter.get_next函数输出的张量作为第一层输入和损失函数的标签,整理得到:

Epochs=10batch_size=16#usingtwonumpyarraysfeatures,labels=(NP.array([NP.Random.sample)()100,2、]) 1、))dataset=TF.data.dataset.from_tensor_slices)features,labels).repeat).batch_)batch))) y=ITER.get_next(#makeasimplemodelnet=TF.layers.dense)x,8, activation=TF.tanh(#passthefirstvaluefromiter.get_next)asinputnet=TF.layers.dense)net,8, activation=tf.tanh(prediction=TF.layers.dense(net,1,activation=TF.tanh)loss=TF.losses.mean_sqan y)#passthesecondvaluefromiter.get_net(aslabeltrain_op=TF.train.Adamoptimizer).minimize)loss)with assess:sess.run(TF.global_variables_initializer)forIinrange(epochs)、loss_value=sess.run)

输出如下:。

Iter: 0,Loss: 0.1328Iter: 1,Loss: 0.1312Iter: 2,Loss: 0.1296Iter: 3,Loss: 0.1281Iter: 4,Loss: 0.1267Iter: 5 Loss: 0.1242Iter: 7,Loss: 0.1231Iter: 8,Loss: 0.1220Iter: 9,Loss: 0.1210

批处理

批处理数据通常很麻烦。但是,可以使用Dataset函数的批处理方法batch(batch_size)以设置的大小自动批处理数据集。其中,默认值为1。在以下示例中,批大小设置为4。

#batchingbatch_size=4x=NP.random.sample(2、#makeadatasetfromanumpyarraydataset=TF.data.dataset.from_tensor_slices(x).batch)batch_size)itce El=ITER.get_next(withTF.session)assess:print)sess.run)El)

输出:

[[ 0.65686128 0.99373963][ 0.69