在 Tensorflow 2.0 上使用 tf.data.Dataset 和 Keras 输入层
Use of tf.data.Dataset with Keras input layer on Tensorflow 2.0
我正在试验 TensorFlow
2.0 alpha,我发现它在使用 Numpy
数组时按预期工作,但在使用 tf.data.Dataset
时出现输入维度错误.我使用 iris 数据集作为最简单的例子来证明这一点:
from sklearn import datasets
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler, OneHotEncoder
import tensorflow as tf
from tensorflow.python import keras
iris = datasets.load_iris()
scl = StandardScaler()
ohe = OneHotEncoder(categories='auto')
data_norm = scl.fit_transform(iris.data)
data_target = ohe.fit_transform(iris.target.reshape(-1,1)).toarray()
train_data, val_data, train_target, val_target = train_test_split(data_norm, data_target, test_size=0.1)
train_data, test_data, train_target, test_target = train_test_split(train_data, train_target, test_size=0.2)
train_dataset = tf.data.Dataset.from_tensor_slices((train_data, train_target))
train_dataset.batch(32)
test_dataset = tf.data.Dataset.from_tensor_slices((test_data, test_target))
test_dataset.batch(32)
val_dataset = tf.data.Dataset.from_tensor_slices((val_data, val_target))
val_dataset.batch(32)
mdl = keras.Sequential([
keras.layers.Dense(16, input_dim=4, activation='relu'),
keras.layers.Dense(8, activation='relu'),
keras.layers.Dense(8, activation='relu'),
keras.layers.Dense(3, activation='sigmoid')]
)
mdl.compile(
optimizer=keras.optimizers.Adam(0.01),
loss=keras.losses.categorical_crossentropy,
metrics=[keras.metrics.categorical_accuracy]
)
history = mdl.fit(train_dataset, epochs=10, steps_per_epoch=15, validation_data=val_dataset)
我收到以下错误:
ValueError: Error when checking input: expected dense_16_input to have shape (4,) but got array with shape (1,)
假设数据集只有一维。如果我通过 input_dim=1 我会得到一个不同的错误:
InvalidArgumentError: Incompatible shapes: [3] vs. [4]
[[{{node metrics_5/categorical_accuracy/Equal}}]] [Op:__inference_keras_scratch_graph_8223]
在具有 Tensorflow 2.0
的 Keras
模型上使用 tf.data.Dataset
的正确方法是什么?
一些更改应该可以修复您的代码。 batch()
数据集转换不会就地发生,因此您需要 return 新数据集。其次,你还应该添加一个repeat()
转换,以便数据集在所有数据都被看到后继续输出示例。
...
train_dataset = tf.data.Dataset.from_tensor_slices((train_data, train_target))
train_dataset = train_dataset.batch(32)
train_dataset = train_dataset.repeat()
val_dataset = tf.data.Dataset.from_tensor_slices((val_data, val_target))
val_dataset = val_dataset.batch(32)
val_dataset = val_dataset.repeat()
...
您还需要在 model.fit()
函数中添加 validation_steps
的参数:
history = mdl.fit(train_dataset, epochs=10, steps_per_epoch=15, validation_data=val_dataset, validation_steps=1)
对于您自己的数据,您可能需要调整验证数据集的 batch_size
和 validation_steps
,以便验证数据在每个步骤中只循环一次。
我正在试验 TensorFlow
2.0 alpha,我发现它在使用 Numpy
数组时按预期工作,但在使用 tf.data.Dataset
时出现输入维度错误.我使用 iris 数据集作为最简单的例子来证明这一点:
from sklearn import datasets
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler, OneHotEncoder
import tensorflow as tf
from tensorflow.python import keras
iris = datasets.load_iris()
scl = StandardScaler()
ohe = OneHotEncoder(categories='auto')
data_norm = scl.fit_transform(iris.data)
data_target = ohe.fit_transform(iris.target.reshape(-1,1)).toarray()
train_data, val_data, train_target, val_target = train_test_split(data_norm, data_target, test_size=0.1)
train_data, test_data, train_target, test_target = train_test_split(train_data, train_target, test_size=0.2)
train_dataset = tf.data.Dataset.from_tensor_slices((train_data, train_target))
train_dataset.batch(32)
test_dataset = tf.data.Dataset.from_tensor_slices((test_data, test_target))
test_dataset.batch(32)
val_dataset = tf.data.Dataset.from_tensor_slices((val_data, val_target))
val_dataset.batch(32)
mdl = keras.Sequential([
keras.layers.Dense(16, input_dim=4, activation='relu'),
keras.layers.Dense(8, activation='relu'),
keras.layers.Dense(8, activation='relu'),
keras.layers.Dense(3, activation='sigmoid')]
)
mdl.compile(
optimizer=keras.optimizers.Adam(0.01),
loss=keras.losses.categorical_crossentropy,
metrics=[keras.metrics.categorical_accuracy]
)
history = mdl.fit(train_dataset, epochs=10, steps_per_epoch=15, validation_data=val_dataset)
我收到以下错误:
ValueError: Error when checking input: expected dense_16_input to have shape (4,) but got array with shape (1,)
假设数据集只有一维。如果我通过 input_dim=1 我会得到一个不同的错误:
InvalidArgumentError: Incompatible shapes: [3] vs. [4]
[[{{node metrics_5/categorical_accuracy/Equal}}]] [Op:__inference_keras_scratch_graph_8223]
在具有 Tensorflow 2.0
的 Keras
模型上使用 tf.data.Dataset
的正确方法是什么?
一些更改应该可以修复您的代码。 batch()
数据集转换不会就地发生,因此您需要 return 新数据集。其次,你还应该添加一个repeat()
转换,以便数据集在所有数据都被看到后继续输出示例。
...
train_dataset = tf.data.Dataset.from_tensor_slices((train_data, train_target))
train_dataset = train_dataset.batch(32)
train_dataset = train_dataset.repeat()
val_dataset = tf.data.Dataset.from_tensor_slices((val_data, val_target))
val_dataset = val_dataset.batch(32)
val_dataset = val_dataset.repeat()
...
您还需要在 model.fit()
函数中添加 validation_steps
的参数:
history = mdl.fit(train_dataset, epochs=10, steps_per_epoch=15, validation_data=val_dataset, validation_steps=1)
对于您自己的数据,您可能需要调整验证数据集的 batch_size
和 validation_steps
,以便验证数据在每个步骤中只循环一次。