使用Tensorflow数据集拟合Keras模型

我正在阅读Aurélien Géron的书,在第13章,我尝试使用Tensorflow数据集(而不是Numpy数组)来训练Keras模型。

1. 数据集

数据集来自sklearn.datasets.fetch_california_housing,我已将其导出为CSV格式。前几行看起来像这样:

MedInc,HouseAge,AveRooms,AveBedrms,Population,AveOccup,Latitude,Longitude,MedHouseVal3.3083,20.0,5.387832699619772,1.0,853.0,3.2433460076045626,37.53,-120.79,1.0832.1932,29.0,5.164444444444444,1.1288888888888888,726.0,3.2266666666666666,37.53,-120.8,0.9061.875,15.0,5.327102803738318,1.1495327102803738,189.0,1.766355140186916,37.53,-120.81,1.813

如你所见,这里有8个特征和1个目标(MedHouseVal,在最后一列)。

我使用以下代码重新导入它:

def parse_csv_line(line: bytes) -> Tuple[tf.Tensor, tf.Tensor]:    parsed = tf.io.decode_csv(line, record_defaults=[0.]*9)    return parsed[:-1], parsed[-1:]def load_dataset_csv(paths: Union[str, List[str]]) -> tf.Dataset:    return tf.data.Dataset.list_files(paths)                        \        .interleave(lambda p: tf.data.TextLineDataset(p).skip(1))   \        .map(parse_csv_line)                                        \        .prefetch(1)train_set = load_dataset_csv("./housing.train.csv")val_set = load_dataset_csv("./housing.val.csv")test_set = load_dataset_csv("./housing.test.csv")

到目前为止一切顺利:

>>> list(test_set.take(1))[(<tf.Tensor: shape=(8,), dtype=float32, numpy=  array([   3.3083   ,   20.       ,    5.3878326,    1.       ,          853.       ,    3.243346 ,   37.53     , -120.79     ],        dtype=float32)>,  <tf.Tensor: shape=(1,), dtype=float32, numpy=array([1.083], dtype=float32)>)]

2. 模型,第一次尝试

然后我定义了我的模型:

model = keras.models.Sequential(    [        keras.layers.Dense(30, input_shape=(8,)),        keras.layers.BatchNormalization(),        keras.layers.Dense(1),    ],)model.compile(loss="mean_squared_error")model.fit(    train_set,    epochs=1,  # debugging    validation_data=val_set,)

但我得到了以下错误:

ValueError: Input 0 of layer sequential_63 is incompatible with the layer: expected axis -1 of input shape to have value 8 but received input with shape (8, 1)

3. 模型,第二次尝试

如果我将输入形状设置为(8, 1)而不是(8,),我会得到以下警告

WARNING:tensorflow:Model was constructed with shape (None, 8, 1) for input KerasTensor(type_spec=TensorSpec(shape=(None, 8, 1), dtype=tf.float32, name='input_15'), name='input_15', description="created by layer 'input_15'"), but it was called on an input with incompatible shape (8, 1, 1).

当我尝试进行预测时,我得到了这个奇怪的结果:

>>> model.predict(test_set.take(1))WARNING:tensorflow:Model was constructed with shape (None, 8, 1) for input KerasTensor(type_spec=TensorSpec(shape=(None, 8, 1), dtype=tf.float32, name='dense_159_input'), name='dense_159_input', description="created by layer 'dense_159_input'"), but it was called on an input with incompatible shape (8, 1, 1).WARNING:tensorflow:6 out of the last 174 calls to <function Model.make_predict_function.<locals>.predict_function at 0x169f02b80> triggered tf.function retracing. Tracing is expensive and the excessive number of tracings could be due to (1) creating @tf.function repeatedly in a loop, (2) passing tensors with different shapes, (3) passing Python objects instead of tensors. For (1), please define your @tf.function outside of the loop. For (2), @tf.function has experimental_relax_shapes=True option that relaxes argument shapes that can avoid unnecessary retracing. For (3), please refer to https://www.tensorflow.org/guide/function#controlling_retracing and https://www.tensorflow.org/api_docs/python/tf/function for  more details.array([[[2.592609 ]],       [[2.591457 ]],       [[2.5924652]],       [[2.592768 ]],       [[2.533997 ]],       [[2.5926137]],       [[2.590248 ]],       [[2.601169 ]]], dtype=float32)

我理解Tensorflow对张量的形状不满意,但为什么它给了我8个预测结果呢?

4. 模型,第三次尝试

在这一点上,我不太确定该怎么做,所以我尝试添加一个Flatten层:

model = keras.models.Sequential(    [        keras.layers.Flatten(),        keras.layers.Dense(30, input_shape=(8,)),        keras.layers.BatchNormalization(),        keras.layers.Dense(1),    ],)

这次我没有得到警告或错误,但当我尝试进行预测时,我仍然得到了8个结果:

>>> model.predict(test_set.take(1))array([[2.5953178],       [2.5949838],       [2.5952766],       [2.5953639],       [2.5783124],       [2.5953195],       [2.594633 ],       [2.5978017]], dtype=float32)

我真的不明白我做错了什么。尝试使用Numpy数组训练第一个模型(输入形状为(8,)且没有Flatten)工作得很好。

任何帮助都将不胜感激。

提前感谢!


回答:

正如官方文档中对tf.keras.Sequential的建议,当inputstf.data.Dataset的实例时,在调用tf.keras.Sequential.fit()时不需要提供batch_size

整数或None。每梯度更新的样本数。如果未指定,batch_size将默认为32。如果您的数据是以数据集、生成器或keras.utils.Sequence实例的形式提供的,请勿指定batch_size(因为它们会生成批次)。

tf.data.Dataset的情况下,fit()方法期望一个批处理数据集。

要对tf.data.Dataset进行批处理,请使用batch()方法,

batched_ds = ds.batch( batch_size )

这样,数据集将提供批处理数据(形状为( batch_size , 8 ))而不是整个数据(形状为( num_samples , 8 ))。

提示:

要取消数据集的批处理,即将数据重新整形为( num_samples , 8 ),请使用提供的unbatch()方法。

Related Posts

使用LSTM在Python中预测未来值

这段代码可以预测指定股票的当前日期之前的值,但不能预测…

如何在gensim的word2vec模型中查找双词组的相似性

我有一个word2vec模型,假设我使用的是googl…

dask_xgboost.predict 可以工作但无法显示 – 数据必须是一维的

我试图使用 XGBoost 创建模型。 看起来我成功地…

ML Tuning – Cross Validation in Spark

我在https://spark.apache.org/…

如何在React JS中使用fetch从REST API获取预测

我正在开发一个应用程序,其中Flask REST AP…

如何分析ML.NET中多类分类预测得分数组?

我在ML.NET中创建了一个多类分类项目。该项目可以对…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注