【发布时间】:2021-08-12 13:41:00
【问题描述】:
我正在阅读Aurélien Géron's book,在第 13 章中,我正在尝试使用 Tensorflow 数据集(而不是 Numpy 数组)来训练 Keras 模型。
1。数据集
数据集来自sklearn.datasets.fetch_california_housing,我已将其导出为 CSV。前几行如下所示:
MedInc,HouseAge,AveRooms,AveBedrms,Population,AveOccup,Latitude,Longitude,MedHouseVal
3.3083,20.0,5.387832699619772,1.0,853.0,3.2433460076045626,37.53,-120.79,1.083
2.1932,29.0,5.164444444444444,1.1288888888888888,726.0,3.2266666666666666,37.53,-120.8,0.906
1.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)效果很好。
任何帮助将不胜感激。
提前致谢!
【问题讨论】:
-
您可以尝试对数据集进行批处理。对 Keras 模型使用
dataset.batch( batch_size )。见here。 -
感谢您的回答!这似乎解决了问题。
-
我在下面提供了详细的答案。
标签: python numpy tensorflow machine-learning keras