作为 TF 的新手,我对 BatchDataset 在训练模型中的使用感到有点困惑。
让我们以 MNIST 为例。在这个分类任务中,我们可以加载数据并将x_trian、y_train的ndarray直接输入到模型中。
mnist = tf.keras.datasets.mnist
(x_train, y_train), (x_test, y_test) = mnist.load_data()
x_train, x_test = x_train / 255.0, x_test / 255.0
model = tf.keras.models.Sequential([
tf.keras.layers.Flatten(input_shape=(28, 28)),
tf.keras.layers.Dense(128, activation='relu'),
tf.keras.layers.Dropout(0.2),
tf.keras.layers.Dense(10, activation='softmax')
])
model.compile(optimizer='adam',
loss='sparse_categorical_crossentropy',
metrics=['accuracy'])
model.fit(x_train,y_train, epochs=5)
Run Code Online (Sandbox Code Playgroud)
训练结果为:
Epoch 1/5
2021-02-17 15:43:02.621749: I tensorflow/stream_executor/platform/default/dso_loader.cc:48] Successfully opened dynamic library cublas64_10.dll
1/1875 [..............................] - ETA: 0s - loss: 2.2977 - accuracy: 0.0938WARNING:tensorflow:Callbacks method `on_train_batch_end` is slow compared to the batch time (batch time: 0.0000s vs `on_train_batch_end` time: 0.0010s). Check your callbacks.
1875/1875 [==============================] - 2s 1ms/step - loss: 0.3047 - accuracy: 0.9117
Epoch 2/5
1875/1875 [==============================] - 2s 1ms/step - loss: 0.1473 - accuracy: 0.9569
Epoch 3/5
1875/1875 [==============================] - 2s 1ms/step - loss: 0.1097 - accuracy: 0.9673
Epoch 4/5
1875/1875 [==============================] - 2s 1ms/step - loss: 0.0905 - accuracy: 0.9724
Epoch 5/5
1875/1875 [==============================] - 2s 1ms/step - loss: 0.0759 - accuracy: 0.9764
Run Code Online (Sandbox Code Playgroud)
我们还可以使用 tf.data.Dataset.from_tensor_slices 生成 BatchDataset 并将其输入到 fit 函数中。
mnist = tf.keras.datasets.mnist
(x_train, y_train), (x_test, y_test) = mnist.load_data()
x_train, x_test = x_train / 255.0, x_test / 255.0
train_ds = tf.data.Dataset.from_tensor_slices(
(x_train, y_train)).shuffle(10000).batch(32)
test_ds = tf.data.Dataset.from_tensor_slices((x_test, y_test)).batch(32)
model = tf.keras.models.Sequential([
tf.keras.layers.Flatten(input_shape=(28, 28)),
tf.keras.layers.Dense(128, activation='relu'),
tf.keras.layers.Dropout(0.2),
tf.keras.layers.Dense(10, activation='softmax')
])
model.compile(optimizer='adam',
loss='sparse_categorical_crossentropy',
metrics=['accuracy'])
model.fit(train_ds, epochs=5)
Run Code Online (Sandbox Code Playgroud)
训练过程的结果如下。
Epoch 1/5
2021-02-17 15:30:34.698718: I tensorflow/stream_executor/platform/default/dso_loader.cc:48] Successfully opened dynamic library cublas64_10.dll
1875/1875 [==============================] - 3s 1ms/step - loss: 0.2969 - accuracy: 0.9140
Epoch 2/5
1875/1875 [==============================] - 3s 1ms/step - loss: 0.1462 - accuracy: 0.9566
Epoch 3/5
1875/1875 [==============================] - 3s 1ms/step - loss: 0.1087 - accuracy: 0.9669
Epoch 4/5
1875/1875 [==============================] - 3s 1ms/step - loss: 0.0881 - accuracy: 0.9730
Epoch 5/5
1875/1875 [==============================] - 3s 1ms/step - loss: 0.0765 - accuracy: 0.9759
Run Code Online (Sandbox Code Playgroud)
通过2种方法都可以成功训练模型,但是它们之间有什么区别吗?使用数据集进行训练是否有一些额外的优势?如果在这种情况下两种方法没有区别,那么生成训练数据集的典型用法是什么以及何时应该使用此方法?
谢谢。
当我们使用Model.fit(x=None, y=None, ...
- 时,我们可以将训练对参数作为纯numpy
数组 or keras.utils.Sequence
or传递tf.data
。
当我们如下使用时,我们将每个训练对 (x
和y
) 作为直接 numpy 数组分别传递给函数fit
。
# data
(x_train, y_train), (_, _) = tf.keras.datasets.mnist.load_data()
# fit
model.fit(x = x_train, y = y_train, ...
# check
print(x_train.shape, y_train.shape)
print(type(x_train), type(y_train))
# (60000, 28, 28) (60000,)
# <class 'numpy.ndarray'> <class 'numpy.ndarray'>
Run Code Online (Sandbox Code Playgroud)
另一方面,tf.data
我们Sequence
将训练对作为元组的形状传递,并且数据类型仍然是ndarray
。根据医生的说法,
tf.data
数据集。inputs
应该返回 ( , targets
)的元组keras.utils.Sequence
返回 ( inputs
, targets
)IE
# data
train_ds = tf.data.Dataset.from_tensor_slices((x_train, y_train)).shuffle(10000).batch(2)
# check
next(iter(train_ds))
(<tf.Tensor: shape=(2, 28, 28), dtype=uint8, numpy= array([[[...], [[...]]], dtype=uint8)>,
<tf.Tensor: shape=(2,), dtype=uint8, numpy=array([7, 8], dtype=uint8)>)
Run Code Online (Sandbox Code Playgroud)
这就是为什么 ifx
是tf.data
、generator
、 或keras.utils.Sequence
实例,y
不应被指定(因为目标将从 获得x
)。
# fit
model.fit(train_ds, ...
Run Code Online (Sandbox Code Playgroud)
在这三种方法中,tf.data
数据管道是最有效的方法,其次是generator
. 当数据集足够小时,主要选择第一种方法(x
和)。y
但是当数据集变得足够大时,您就会考虑tf.data
或generator
高效的输入管道。所以这些的选择完全取决于。
来自 Keras 的帖子:
NumPy 数组,就像 Scikit-Learn 和许多其他基于 Python 的库一样。如果您的数据适合内存,那么这是一个不错的选择。
TensorFlow 数据集对象。这是一个高性能选项,更适合不适合内存的数据集以及从磁盘或分布式文件系统流式传输的数据集。
生成批量数据的Python 生成器(例如 keras.utils.Sequence 类的自定义子类)。
归档时间: |
|
查看次数: |
1733 次 |
最近记录: |