详解TensorFlow的 tf.data.Dataset.from_tensor_slices 函数:从张量创建数据集

  • Post category:Python

TensorFlow中的tf.data.Dataset.from_tensor_slices函数可以使用一个给定的张量(例如numpy数组),返回一个tf.data.Dataset对象,即数据集。每个张量(数组)的第一个维度大小表示生成的数据集中样本的数量。通常,我们会将输入数据作为一个张量,并使用该函数来加载数据集。下面是函数的完整使用方法和说明。

tf.data.Dataset.from_tensor_slices函数的语法

dataset = tf.data.Dataset.from_tensor_slices(tensor)

tf.data.Dataset.from_tensor_slices函数的参数

  • tensor: 数据集,要从每个轴切片。入参可以是numpy数组,也可以是张量,转换为tf.Tensor类型。

tf.data.Dataset.from_tensor_slices函数返回值

返回一个tf.data.Dataset对象

tf.data.Dataset.from_tensor_slices函数的用途

加载大型训练数据的最佳方式是将数据存储在分布式文件系统上。而此函数用于将存储在张量中的“小数据”批量传输到模型中。

使用tf.data.Dataset.from_tensor_slices函数的流程如下:
1. 将训练数据和标签存储在numpy数组中。
2. 构建用于训练和评估模型的数据管道。
3. 在管道的迭代器对象上丰富数据,例如Batch、Shuffle、Map等。

以下是两个具体的实例,以说明该函数的应用。

实例一

考虑一个数据集, 编号为 $x_i$, 对应一个标记集 $y_i$。 它们保存在numpy数组中,我们想通过TensorFlow的数据管道API,将x数据集按顺序合并到y数据集中。

import tensorflow as tf
import numpy as np

x = np.array([
    [1.0, 2.0, 3.0, 4.0], 
    [5.0, 6.0, 7.0, 8.0], 
    [9.0, 10.0, 11.0, 12.0]])

y = np.array([
    [0, 1, 0], 
    [1, 0, 0], 
    [0, 0, 1]])

dataset = tf.data.Dataset.from_tensor_slices((x,y))

for element in dataset:
  print(element)

输出如下:

(<tf.Tensor: id=11, shape=(4,), dtype=float64, numpy=array([1., 2., 3., 4.])>, <tf.Tensor: id=12, shape=(3,), dtype=int64, numpy=array([0, 1, 0])>)
(<tf.Tensor: id=13, shape=(4,), dtype=float64, numpy=array([5., 6., 7., 8.])>, <tf.Tensor: id=14, shape=(3,), dtype=int64, numpy=array([1, 0, 0])>)
(<tf.Tensor: id=15, shape=(4,), dtype=float64, numpy=array([ 9., 10., 11., 12.])>, <tf.Tensor: id=16, shape=(3,), dtype=int64, numpy=array([0, 0, 1])>)

实例二

让我们考虑MNIST数据集,其中有60,000个训练图像和10,000个测试图像。每个图像是 $28\times 28$ 像素。我们将训练数据集按照标签进行分类,并从中随机选择batch_size大小的样本。

import tensorflow as tf
from tensorflow.keras.datasets import mnist
(x_train, y_train), (x_test, y_test) = mnist.load_data()

# 将数据类型转为float32,并标准化数据
x_train, x_test = x_train / 255.0, x_test / 255.0

# 获取训练数据量和测试数据量
train_data_size = len(x_train)
test_data_size = len(x_test)

# 将标签转换为one-hot编码
y_train = tf.one_hot(y_train, depth=10).numpy()
y_test = tf.one_hot(y_test, depth=10).numpy()

# 构建数据管道并打印前n个样本
batch_size = 128
train_dataset = tf.data.Dataset.from_tensor_slices((x_train, y_train)).shuffle(train_data_size).batch(batch_size)
test_dataset = tf.data.Dataset.from_tensor_slices((x_test, y_test)).batch(batch_size)

for step, (x_train_batch, y_train_batch) in enumerate(train_dataset):
    if step < 2:
        print('step:', step, ', x_train_batch_shape:', x_train_batch.shape, ' y_train_batch_shape:', y_train_batch.shape)

输出如下:

step: 0 , x_train_batch_shape: (128, 28, 28)  y_train_batch_shape: (128, 10)
step: 1 , x_train_batch_shape: (128, 28, 28)  y_train_batch_shape: (128, 10)

这里,from_tensor_slices从输入数据中创建Dataset对象,我们也可以使用shufflebatch方法对数据集进行操作,这能够提高训练的效率和准确性。