TensorFlow学习(十五):使用tf.data来创建输入流(上)

Posted 谢小小XH

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了TensorFlow学习(十五):使用tf.data来创建输入流(上)相关的知识,希望对你有一定的参考价值。

本文将讲解深度学习使用数据的一整套流水线. 将使用tensorflow新的tf.data 的一系列API来讲解. Dataset能够有效简化数据读取和使用等等一些的复杂程度,是现在官方推荐的数据使用方式.
官方文档:Module: tf.data

一.使用Dataset

使用 Dataset 需要遵循三个步骤:

载入数据:为数据创建一个Dataset实例。
创建一个迭代器:通过使用创建的Dataset构建一个迭代器来对数据集进行迭代。
使用数据:通过使用创建的迭代器,可以找到可传输给模型的数据集元素。

接下来按照上面的三个步骤来分别讲一下怎么创建和使用Dataset.

Ⅰ.创建Dataset对象

首先其实只要重点掌握from_tensor_slices 这个函数就差不多了.当然还有一些相似的函数,可以自己看文档来使用.
tf.data.Data.from_tensor_slices(tensors)
作用:Creates a Dataset whose elements are slices of the given tensors.

参数:
tensors: 嵌套结构的tensors,在第0维上面都有想用的size.

返回:
一个Dataset对象

Dataset对象有一个常见的属性:output_shapes,这个属性的作用是现实dataset对象中 一个元素的形状.

下面举一个例子:

import tensorflow as tf
import numpy as np

dataset1=tf.data.Dataset.from_tensors(np.array([1.,2.,3.,4.,5.]))
dataset2=tf.data.Dataset.from_tensor_slices(tensors=np.array([[1.,2.,3.,4.,5.],[3.,4.,5.,6.,7.]]))

print("element shape of dataset1:",dataset1.output_shapes)
print("element shape of dataset2:",dataset2.output_shapes)
print("element type of dataset2:",dataset2.output_types)

结果:

element shape of dataset1: (5,)
element shape of dataset2: (5,)
element type of dataset2: <dtype: 'float64'>

from_tensors() 这个函数会把传入的tensor当做一个元素,但是from_tensor_slices() 会把传入的tensor除开第一维之后的大小当做元素个数.比如上面2x5 的向量,我们得到的元素是其中每一个形状为(5,)的tensor.

再举一个例子就明白了:

import tensorflow as tf
import numpy as np

dataset1=tf.data.Dataset.from_tensors(np.zeros(shape=(10,5,2),dtype=np.float32))

dataset2=tf.data.Dataset.from_tensor_slices(tensors=np.zeros(shape=(10,5,2),dtype=np.float32))

print("element shape of dataset1:",dataset1.output_shapes)
print("element shape of dataset2:",dataset2.output_shapes)
print("element type of dataset2:",dataset2.output_types)

iterator=dataset1.make_one_shot_iterator()
iterator2=dataset2.make_one_shot_iterator()

element=iterator.get_next()
element2=iterator2.get_next()
with tf.Session() as sess:
    print("elements of dataset1:")
    print(sess.run(element))

    print("elements of dataset2:")
    for i in range(5):
        print(sess.run(element2))

结果:

element shape of dataset1: (10, 5, 2)
element shape of dataset2: (5, 2)
element type of dataset2: <dtype: 'float32'>

elements of dataset1:
[[[0. 0.]
  [0. 0.]
  [0. 0.]
  [0. 0.]
  [0. 0.]]

 [[0. 0.]
  [0. 0.]
  [0. 0.]
  [0. 0.]
  [0. 0.]]

 [[0. 0.]
  [0. 0.]
  [0. 0.]
  [0. 0.]
  [0. 0.]]

 [[0. 0.]
  [0. 0.]
  [0. 0.]
  [0. 0.]
  [0. 0.]]

 [[0. 0.]
  [0. 0.]
  [0. 0.]
  [0. 0.]
  [0. 0.]]

 [[0. 0.]
  [0. 0.]
  [0. 0.]
  [0. 0.]
  [0. 0.]]

 [[0. 0.]
  [0. 0.]
  [0. 0.]
  [0. 0.]
  [0. 0.]]

 [[0. 0.]
  [0. 0.]
  [0. 0.]
  [0. 0.]
  [0. 0.]]

 [[0. 0.]
  [0. 0.]
  [0. 0.]
  [0. 0.]
  [0. 0.]]

 [[0. 0.]
  [0. 0.]
  [0. 0.]
  [0. 0.]
  [0. 0.]]]
elements of dataset2:
[[0. 0.]
 [0. 0.]
 [0. 0.]
 [0. 0.]
 [0. 0.]]
[[0. 0.]
 [0. 0.]
 [0. 0.]
 [0. 0.]
 [0. 0.]]
[[0. 0.]
 [0. 0.]
 [0. 0.]
 [0. 0.]
 [0. 0.]]
[[0. 0.]
 [0. 0.]
 [0. 0.]
 [0. 0.]
 [0. 0.]]
[[0. 0.]
 [0. 0.]
 [0. 0.]
 [0. 0.]
 [0. 0.]]

Ⅱ.建立迭代器和得到数据

迭代器有很多种不同的类型,这里列举几种常见的迭代器类型.并且讨论一下batch和shuffle在这里是怎么起到作用的.
这里只讲最简单的迭代器one-shot iterator. one-shot iterator是最简单的iterator,它只支持在一个dataset上迭代一次的操作,不需要显式初始化。One-shot iterators可以处理几乎所有的己存在的基于队列的input pipeline支持的情况,但它们不支持参数化(parameterization)
直接给一个例子来看一下怎么使用并且得到数据:

import tensorflow as tf
import numpy as np

dataset1=tf.data.Dataset.from_tensors(np.array([1.,2.,3.,4.,5.]))

dataset2=tf.data.Dataset.from_tensor_slices(tensors=np.array([1.,2.,3.,4.,5.,6.])).repeat().shuffle(buffer_size=2).batch(2)

print("element shape of dataset1:",dataset1.output_shapes)
print("element shape of dataset2:",dataset2.output_shapes)
print("element type of dataset2:",dataset2.output_types)

iterator=dataset1.make_one_shot_iterator()
iterator2=dataset2.make_one_shot_iterator()


element=iterator.get_next()
element2=iterator2.get_next()
with tf.Session() as sess:
    print("elements of dataset1:")
    print(sess.run(element))
    print("elements of dataset2:")
    for i in range(3):
        print("epoch:",i)
        for j in range(6//2):
            print("---mini_batch:",j,sess.run(element2))

结果:

element shape of dataset1: (5,)
element shape of dataset2: (?,)
element type of dataset2: <dtype: 'float64'>

elements of dataset1:
[1. 2. 3. 4. 5.]
elements of dataset2:
epoch: 0
---mini_batch: 0 [2. 3.]
---mini_batch: 1 [1. 4.]
---mini_batch: 2 [5. 1.]
epoch: 1
---mini_batch: 0 [6. 3.]
---mini_batch: 1 [2. 5.]
---mini_batch: 2 [4. 1.]
epoch: 2
---mini_batch: 0 [2. 6.]
---mini_batch: 1 [3. 5.]
---mini_batch: 2 [6. 4.]

以上是关于TensorFlow学习(十五):使用tf.data来创建输入流(上)的主要内容,如果未能解决你的问题,请参考以下文章

深度学习(五十五)tensorflow分布式训练

TensorFlow2深度学习实战(十五):目标检测算法 YOLOv4 实战

Sklearn 与 TensorFlow 机器学习实用指南第二版

TensorFlow学习(十六):使用tf.data来创建输入流(下)

TensorFlow学习(十六):使用tf.data来创建输入流(下)

第十五周学习进度