我在玩tensorflow,以更加熟悉整个工作流.为了做到这一点,我认为应该从为众所周知的Iris数据集创建一个简单的分类器开始.
我使用以下方式加载数据集:
ds = tfds.load('iris', split='train', shuffle_files=True, as_supervised=True)
我使用以下分类器:
model = keras.Sequential([
keras.layers.Dense(10,activation="relu"),
keras.layers.Dense(10,activation="relu"),
keras.layers.Dense(3, activation="softmax")
])
model.compile(
optimizer=tf.keras.optimizers.Adam(0.001),
loss=tf.keras.losses.SparseCategoricalCrossentropy(),
metrics=[tf.keras.metrics.SparseCategoricalAccuracy()],
)
然后,我try 使用以下方法拟合模型:
model.fit(ds,batch_size=50, epochs=100)
这会产生以下错误:
Input 0 of layer "dense" is incompatible with the layer: expected min_ndim=2, found ndim=1. Full shape received: (4,)
Call arguments received by layer "sequential" (type Sequential):
• inputs=tf.Tensor(shape=(4,), dtype=float32)
• training=True
• mask=None
我还try 使用函数API定义模型(因为这是我最初学习的目标)
inputs = keras.Input(shape=(4,), name='features')
first_hidden = keras.layers.Dense(10, activation='relu')(inputs)
second_hidden = keras.layers.Dense(10, activation="relu")(first_hidden)
outputs = keras.layers.Dense(3, activation='softmax')(second_hidden)
model = keras.Model(inputs=inputs, outputs=outputs, name="test_iris_classification")
我现在得到了与之前相同的错误,但这次有一个警告:
WARNING:tensorflow:Model was constructed with shape (None, 4) for input KerasTensor(type_spec=TensorSpec(shape=(None, 4), dtype=tf.float32, name='features'), name='features', description="created by layer 'features'"), but it was called on an input with incompatible shape (4,).
我怀疑这是一个很基本的问题,我还没有理解,但我一直没有弄明白,尽管我在谷歌上搜索了几个小时.
PS:
我是这样读的:
ds = pd.read_csv("iris.data", header=None)
labels = []
for name in ds[4]:
if name == "Iris-setosa":
labels.append(0)
elif name == "Iris-versicolor":
labels.append(1)
elif name == "Iris-virginica":
labels.append(2)
else:
raise ValueError(f"Name wrong name: {name}")
labels = np.array(labels)
features = np.array(ds[[0,1,2,3]])
并按如下方式安装:
model.fit(features, labels,batch_size=50, epochs=100)
我能够将模型与这个数据集相匹配,而不会对序列API和函数API产生任何问题.这让我怀疑我的误解与tensorflow_数据集的工作方式有关.