我正在尝试完成一个简单的深度学习任务,以学习如何使用Tensorflow(特别是其Dataset工具)。任务如下:训练一个模型,该模型可以判断给定的一系列浮点数(长度固定)的总和是正数(标记为1)还是负数(标记为0)。
我在不使用tf.data.Dataset的情况下完成了这个任务,并且效果很好。
def get_rand_seq(): return [rand.uniform(-1, 1) for _ in range(6)]n = 1000X = np.array([get_rand_seq() for _ in range(n)])y = np.array([0 if sum(seq) < 0 else 1 for seq in X])model = tf.keras.models.Sequential()model.add(tf.keras.layers.Dense(16, input_shape=(6, ), activation='relu'))model.add(tf.keras.layers.Dense(4, activation='relu'))model.add(tf.keras.layers.Dense(1, activation='sigmoid'))model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['acc'])model.fit(X, y, epochs=10, batch_size=4)
然而,当我尝试使用tf.data.Dataset作为输入时,在训练步骤model.fit(...)
处遇到了错误。我的代码如下:
ds_X = tf.data.Dataset.from_tensor_slices(X)ds_y = tf.data.Dataset.from_tensor_slices(y)ds = tf.data.Dataset.zip((ds_X, ds_y))model = tf.keras.models.Sequential()model.add(tf.keras.layers.Dense(16, input_shape=(6, ), activation='relu'))model.add(tf.keras.layers.Dense(4, activation='relu'))model.add(tf.keras.layers.Dense(1, activation='sigmoid'))model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['acc'])model.fit(ds, epochs=10, batch_size=4)
我得到了以下错误:
ValueError: Input 0 of layer sequential_5 is incompatible with the layer: expected axis -1 of input shape to have value 6 but received input with shape [6, 1]
即使将input_shape更改为(6, 1)也无法解决问题。
有没有哪位善良的人可以指引我这个迷途的羔羊呢?
回答:
在使用tf.data.Dataset
时,不要在model.fit
中使用batch_size
参数。你应该直接对数据集进行操作(请记住,对数据集的任何操作,如批处理、洗牌等,不会就地更改数据集,这意味着会返回一个具有新属性的数据集副本,需要重新赋值数据集)。
此外,没有必要创建两个独立的数据集并将它们组合。你可以将一个元组提供给tf.data.Dataset.from_tensor_slices
的工厂方法。
import tensorflow as tf import numpy as npdef get_rand_seq(): return [np.random.uniform(-1, 1) for _ in range(6)]n = 1000X = np.array([get_rand_seq() for _ in range(n)])y = np.array([0 if sum(seq) < 0 else 1 for seq in X])ds = tf.data.Dataset.from_tensor_slices((X, y)).batch(4)# 等效的是 # ds = tf.data.Dataset.from_tensor_slices((X, y))# ds = ds.batch(4) # 不是就地操作model = tf.keras.models.Sequential()model.add(tf.keras.layers.Dense(16, input_shape=(6, ), activation='relu'))model.add(tf.keras.layers.Dense(4, activation='relu'))model.add(tf.keras.layers.Dense(1, activation='sigmoid'))model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['acc'])model.fit(ds, epochs=1000)