将Tensorflow Datasets API与Keras结合使用时遇到的问题

时间:2019-05-14 15:33:22

标签: python tensorflow machine-learning keras tensorflow-datasets

我正在尝试拟合CNN Keras模型,向其提供由Tensorflow的Datasets API处理的数据。但是,尽管遵循了官方文档(请参阅there),我还是一次次地遇到相同的Exception:

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数据集,对图像进行了归一化,并将类标签转换为一键编码。您可以从下面的代码中看到摘录。

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一起工作),所以我认为我可能缺少明显的东西。

3 个答案:

答案 0 :(得分:3)

对于遵循TF 2.0 Beta教程中有关加载图像(https://www.tensorflow.org/beta/tutorials/load_data/images)之后的用户:

我能够通过在preprocess_image函数中返回一个元组来避免该错误

x = pd.HDFStore('model_weight.hdf5', mode='w',complevel=9,complib='bzip2')

我没有在用例中使用标签,因此您可能必须进行其他更改才能遵循本教程

答案 1 :(得分:1)

好,知道了。我启用了急切的执行程序,以查看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)),它不喜欢Dataset迭代器生成的字典(因此我得到了错误)。

我在model.fit之前添加了以下代码:

train_data = train_data.map(lambda x: tuple(x.values()))
test_data = test_data.map(lambda x: tuple(x.values()))

它有效。

答案 2 :(得分:1)

您可以使用tensorflow-datasets直接从as_supervised作为元组加载数据

test_data, train_data = tfds.load("mnist", split=tfds.Split.ALL.subsplit([1, 3]), as_supervised=True)