在 Keras 中使用 Tensorflow 数据集 API 的问题
Issues at using the Tensorflow Datasets API with Keras
我正在尝试拟合 CNN Keras 模型,为其提供由来自 Tensorflow 的数据集 API 处理的数据。然而,尽管遵循了官方文档(请参阅 there),我还是一次又一次地遇到相同的异常:
ValueError: No data provided for "conv2d_8_input". Need data for each key in: ['conv2d_8_input']
# conv2d_8 is the first Conv2D layer of my model, see below
我正在使用来自 tensorflow-datasets
的 MNIST 数据集,图像被归一化并且 class 标签被转换为单热编码。您可以从下面的代码中看到摘录。
test_data, train_data = tfds.load("mnist", split=Split.ALL.subsplit([1, 3]))
# [...] Images are normalized using Dataset.map method
# [...] Labels are converted into one-hot encodings as well, using tf.one_hot function
model = keras.Sequential([
keras.layers.Conv2D(
32,
kernel_size=5,
padding="same",
input_shape=(28, 28, 1),
activation="relu",
),
keras.layers.MaxPooling2D(
(2, 2),
padding="same"
),
keras.layers.Conv2D(
64,
kernel_size=5,
padding="same",
activation="relu"
),
keras.layers.MaxPooling2D(
(2, 2),
padding="same"
),
keras.layers.Flatten(),
keras.layers.Dense(
512,
activation="relu"
),
keras.layers.Dropout(rate=0.4),
keras.layers.Dense(10, activation="softmax")
])
model.compile(
optimizer=tf.train.AdamOptimizer(0.01),
loss="categorical_crossentropy",
metrics=["accuracy"]
)
train_data = train_data.batch(32).repeat()
test_data = test_data.batch(32).repeat()
model.fit(
train_data,
epochs=10,
steps_per_epoch=30,
validation_data=test_data,
validation_steps=3
) # The exception occurs at this step
我不明白为什么它不起作用,我尝试用一次性迭代器而不是数据集来提供 fit 方法,但我得到了相同的结果。我不习惯 Keras 和 TensorFlow(我通常使用 PyTorch),所以我想我可能遗漏了一些明显的东西。
好的,我知道了。我启用了 eager execution 以查看 Keras 是否会产生更精确的异常,我得到了这个:
ValueError: Output of generator should be a tuple `(x, y, sample_weight)` or `(x, y)`. Found: {'image': <tf.Tensor: id=1012, shape=(32, 28, 28, 1), dtype=float64, numpy=array([...])>, 'label': <tf.Tensor: id=1013, shape=(32, 10), dtype=uint8, numpy=array([...]), dtype=uint8)>}
事实上,我的数据集的组成部分(图像及其相关标签)具有名称("image" 和 "label"),因为这是 tensorflow_datasets
加载它们的方式。因此,数据集上的迭代器会生成一个包含两个值的字典:"image" 和 "label".
但是,Keras expects a tuple 的两个值 (inputs, targets)
(或三个值 (inputs, targets, sample_wheights)
),它不喜欢数据集迭代器生成的字典(因此我得到了错误).
我在model.fit
之前添加了以下代码:
train_data = train_data.map(lambda x: tuple(x.values()))
test_data = test_data.map(lambda x: tuple(x.values()))
而且有效。
您可以使用 as_supervised
以元组形式直接从 tensorflow-datasets
加载数据
test_data, train_data = tfds.load("mnist", split=tfds.Split.ALL.subsplit([1, 3]), as_supervised=True)
对于那些在完成有关加载图像的 TF 2.0 Beta 教程 (https://www.tensorflow.org/beta/tutorials/load_data/images) 之后来到此页面的用户:
我能够通过在 preprocess_image 函数中返回一个元组来避免错误
def preprocess_image(image):
image = tf.image.decode_jpeg(image, channels=3)
image = tf.image.resize(image, [192, 192])
image /= 255.0 # normalize to [0,1] range
return (image,image)
我没有在用例中使用标签,因此您可能需要进行其他更改才能遵循教程
我正在尝试拟合 CNN Keras 模型,为其提供由来自 Tensorflow 的数据集 API 处理的数据。然而,尽管遵循了官方文档(请参阅 there),我还是一次又一次地遇到相同的异常:
ValueError: No data provided for "conv2d_8_input". Need data for each key in: ['conv2d_8_input']
# conv2d_8 is the first Conv2D layer of my model, see below
我正在使用来自 tensorflow-datasets
的 MNIST 数据集,图像被归一化并且 class 标签被转换为单热编码。您可以从下面的代码中看到摘录。
test_data, train_data = tfds.load("mnist", split=Split.ALL.subsplit([1, 3]))
# [...] Images are normalized using Dataset.map method
# [...] Labels are converted into one-hot encodings as well, using tf.one_hot function
model = keras.Sequential([
keras.layers.Conv2D(
32,
kernel_size=5,
padding="same",
input_shape=(28, 28, 1),
activation="relu",
),
keras.layers.MaxPooling2D(
(2, 2),
padding="same"
),
keras.layers.Conv2D(
64,
kernel_size=5,
padding="same",
activation="relu"
),
keras.layers.MaxPooling2D(
(2, 2),
padding="same"
),
keras.layers.Flatten(),
keras.layers.Dense(
512,
activation="relu"
),
keras.layers.Dropout(rate=0.4),
keras.layers.Dense(10, activation="softmax")
])
model.compile(
optimizer=tf.train.AdamOptimizer(0.01),
loss="categorical_crossentropy",
metrics=["accuracy"]
)
train_data = train_data.batch(32).repeat()
test_data = test_data.batch(32).repeat()
model.fit(
train_data,
epochs=10,
steps_per_epoch=30,
validation_data=test_data,
validation_steps=3
) # The exception occurs at this step
我不明白为什么它不起作用,我尝试用一次性迭代器而不是数据集来提供 fit 方法,但我得到了相同的结果。我不习惯 Keras 和 TensorFlow(我通常使用 PyTorch),所以我想我可能遗漏了一些明显的东西。
好的,我知道了。我启用了 eager execution 以查看 Keras 是否会产生更精确的异常,我得到了这个:
ValueError: Output of generator should be a tuple `(x, y, sample_weight)` or `(x, y)`. Found: {'image': <tf.Tensor: id=1012, shape=(32, 28, 28, 1), dtype=float64, numpy=array([...])>, 'label': <tf.Tensor: id=1013, shape=(32, 10), dtype=uint8, numpy=array([...]), dtype=uint8)>}
事实上,我的数据集的组成部分(图像及其相关标签)具有名称("image" 和 "label"),因为这是 tensorflow_datasets
加载它们的方式。因此,数据集上的迭代器会生成一个包含两个值的字典:"image" 和 "label".
但是,Keras expects a tuple 的两个值 (inputs, targets)
(或三个值 (inputs, targets, sample_wheights)
),它不喜欢数据集迭代器生成的字典(因此我得到了错误).
我在model.fit
之前添加了以下代码:
train_data = train_data.map(lambda x: tuple(x.values()))
test_data = test_data.map(lambda x: tuple(x.values()))
而且有效。
您可以使用 as_supervised
tensorflow-datasets
加载数据
test_data, train_data = tfds.load("mnist", split=tfds.Split.ALL.subsplit([1, 3]), as_supervised=True)
对于那些在完成有关加载图像的 TF 2.0 Beta 教程 (https://www.tensorflow.org/beta/tutorials/load_data/images) 之后来到此页面的用户:
我能够通过在 preprocess_image 函数中返回一个元组来避免错误
def preprocess_image(image):
image = tf.image.decode_jpeg(image, channels=3)
image = tf.image.resize(image, [192, 192])
image /= 255.0 # normalize to [0,1] range
return (image,image)
我没有在用例中使用标签,因此您可能需要进行其他更改才能遵循教程