数据集,又称为资料集、数据集合或资料集合,是一种由数据所组成的集合。机器学习需要大量的数据来训练模型,尤其是训练神经网络。在进行机器学习时,数据集一般会被划分为训练集和测试集,很多时候还会进一步划分出验证集(个别人称之为开发集)。在本章的内容中,将详细介绍制作TensorFlow数据集的知识。
2.1 使用tf.data处理数据集
从Tensorflow 2.0开始,提供了专门用于实现数据输入的接口tf.data.Dataset,能够以快速且可扩展的方式加载和预处理数据,帮助开发者高效的实现数据的读入、打乱(shuffle)、增强(augment)等功能。
2.1.1 制作数据集并训练和评估
请看下面的实例文件xun01.py,演示了使用tf.data创建数据集并进行训练和评估的过程。
# 首先,让我们创建一个训练数据集实例
train_dataset = tf.data.Dataset.from_tensor_slices((x_train, y_train))
# 洗牌并切片数据集.
train_dataset = train_dataset.shuffle(buffer_size=1024).batch(64)
# 现在我们得到了一个测试数据集.
test_dataset = tf.data.Dataset.from_tensor_slices((x_test, y_test))
test_dataset = test_dataset.batch(64)
#由于数据集已经处理批处理,所以我们不传递“batch\u size”参数。
model.fit(train_dataset, epochs=3)
#还可以对数据集进行评估或预测.
print("Evaluate评估:")
result = model.evaluate(test_dataset)
dict(zip(model.metrics_names, result))
在上述代码中,使用dataset的内置函数shuffle()将数据打乱,此函数的参数值越大,混乱程度就越大。另外,还可以使用dataset的其它内置函数操作数据:
- batch(4):按照顺序取出4行数据,最后一次输出可能小于batch;
- repeat():设置数据集重复执行指定的次数,在batch操作输出完毕后再执行。如果在之前,相当于先把整个数据集复制两次。为了配合输出次数,一般repeat()的参数默认为空。
在作者电脑中执行后会输出:
Epoch 1/3
782/782 [==============================] - 2s 2ms/step - loss: 0.3395 - sparse_categorical_accuracy: 0.9036
Epoch 2/3
782/782 [==============================] - 2s 2ms/step - loss: 0.1614 - sparse_categorical_accuracy: 0.9527
Epoch 3/3
782/782 [==============================] - 2s 2ms/step - loss: 0.1190 - sparse_categorical_accuracy: 0.9648
Evaluate评估:
157/157 [==============================] - 0s 2ms/step - loss: 0.1278 - sparse_categorical_accuracy: 0.9633
{'loss': 0.12783484160900116,
'sparse_categorical_accuracy': 0.9632999897003174}
另外需要注意,因为tf.data数据集会在每个周期结束时重置,所以可以在下一个周期中重复使用。如果只想在来自此数据集的特定数量批次上进行训练,则可以使用参数steps_per_epoch,此参数可以指定在继续下一个周期之前,当前模型应该使用此数据集运行多少训练步骤。如果执行此操作,则不会在每个周期结束时重置数据集,而是会继续绘制接下来的批次,tf.data数据集最终会用尽数据(除非它是无限循环的数据集)。
2.1.2 将tf.data做为验证数据集进行训练
如果只想对此数据集中的特定数量批次进行验证,则可以设置参数validation_steps,此参数可以指定在中断验证并进入下一个周期之前,模型应使用验证数据集运行多少验证步骤。请看下面的实例文件xun02.py,功能是通过参数validation_steps设置只使用数据集中的前10个batch批处理运行验证。
#准备训练数据集
train_dataset = tf.data.Dataset.from_tensor_slices((x_train, y_train))
train_dataset = train_dataset.shuffle(buffer_size=1024).batch(64)
#准备验证数据集
val_dataset = tf.data.Dataset.from_tensor_slices((x_val, y_val))
val_dataset = val_dataset.batch(64)
model.fit(
train_dataset,
epochs=1,
#通过参数“validation_steps”,设置只使用数据集中的前10个批处理运行验证
validation_data=val_dataset,
validation_steps=10,
)
验证会在当前epoch结束后进行,通过validation_steps设置了验证使用的 batch数量,假如validation batch size(没必要和train batch相等)=64,而validation_steps=100,steps相当于batch数,则会从validation data中取6400个数据用于验证。如果在一次step后,在验证数据中剩下的数据足够下一次step,则会继续从剩下的数据中选取,如果不够则会重新循环。在作者电脑中执行后会输出:
782/782 [==============================] - 2s 2ms/step - loss: 0.3299 - sparse_categorical_accuracy: 0.9067 - val_loss: 0.2966 - val_sparse_categorical_accuracy: 0.9250
<tensorflow.python.keras.callbacks.History at 0x7f698e35e400>
注意:当时用Dataset对象进行训练时,不能使用参数 validation_split(从训练数据生成预留集),因为在使用validation_split功能时需要为数据集样本编制索引,而 Dataset API 通常无法做到这一点。