How to train on a tensorflow_datasets dataset

Vet*_*oie 7 python machine-learning keras tensorflow tensorflow-datasets

I\'m playing around with tensorflow to become a bit more familiar with the overall workflow. To do this I thought I should start with creating a simple classifier for the well known Iris dataset.

\n

I load the dataset using:

\n
ds = tfds.load(\'iris\', split=\'train\', shuffle_files=True, as_supervised=True)\n
Run Code Online (Sandbox Code Playgroud)\n

I use the following classifier:

\n
model = keras.Sequential([\n    keras.layers.Dense(10,activation="relu"),\n    keras.layers.Dense(10,activation="relu"),\n    keras.layers.Dense(3, activation="softmax")\n])\n\nmodel.compile(\n    optimizer=tf.keras.optimizers.Adam(0.001),\n    loss=tf.keras.losses.SparseCategoricalCrossentropy(),\n    metrics=[tf.keras.metrics.SparseCategoricalAccuracy()],\n)\n
Run Code Online (Sandbox Code Playgroud)\n

I then try to fit the model using:

\n
model.fit(ds,batch_size=50, epochs=100)\n
Run Code Online (Sandbox Code Playgroud)\n

This gives the following error:

\n
Input 0 of layer "dense" is incompatible with the layer: expected min_ndim=2, found ndim=1. Full shape received: (4,)\n\n    Call arguments received by layer "sequential" (type Sequential):\n      \xe2\x80\xa2 inputs=tf.Tensor(shape=(4,), dtype=float32)\n      \xe2\x80\xa2 training=True\n      \xe2\x80\xa2 mask=None\n
Run Code Online (Sandbox Code Playgroud)\n

I also tried defining the model using the functional API(as this was my orignal goal to learn)

\n
inputs = keras.Input(shape=(4,), name=\'features\')\n\nfirst_hidden = keras.layers.Dense(10, activation=\'relu\')(inputs)\nsecond_hidden = keras.layers.Dense(10, activation="relu")(first_hidden)\n\noutputs = keras.layers.Dense(3, activation=\'softmax\')(second_hidden)\n\nmodel = keras.Model(inputs=inputs, outputs=outputs, name="test_iris_classification")\n
Run Code Online (Sandbox Code Playgroud)\n

I now get the same error as before but this time with a warning:

\n
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,).\n
Run Code Online (Sandbox Code Playgroud)\n

I suspect this is something quite fundamental that haven\'t understood but I have not been able to figure it out, despite several hours of googling.

\n

PS:\nI also tried to download the whole dataset from the UCI Machine Learning Repository as a CSV file.

\n

I read it in like this:

\n
ds = pd.read_csv("iris.data", header=None)\nlabels = []\nfor name in ds[4]:\n    if name == "Iris-setosa":\n        labels.append(0)\n    elif name == "Iris-versicolor":\n        labels.append(1)\n    elif name == "Iris-virginica":\n        labels.append(2)\n    else:\n        raise ValueError(f"Name wrong name: {name}")\nlabels = np.array(labels)\nfeatures = np.array(ds[[0,1,2,3]])\n
Run Code Online (Sandbox Code Playgroud)\n

And fit it like this:

\n
model.fit(features, labels,batch_size=50, epochs=100)\n
Run Code Online (Sandbox Code Playgroud)\n

And I\'m able to fit the model to this dataset without any problems for both the sequential and the functional API. Which makes me suspect my misunderstanding has something to do with how the tensorflow_datasets works.

\n

Alo*_*her 5

Set the batch size when loading your data:

import tensorflow_datasets as tfds
import tensorflow as tf

ds = tfds.load('iris', split='train', shuffle_files=True, as_supervised=True, batch_size=10)
model = tf.keras.Sequential([
    tf.keras.layers.Dense(10,activation="relu"),
    tf.keras.layers.Dense(10,activation="relu"),
    tf.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()],
)
model.fit(ds, epochs=100)
Run Code Online (Sandbox Code Playgroud)

Also regarding model.fit, the docs state:

Integer or None. Number of samples per gradient update. If unspecified, batch_size will default to 32. Do not specify the batch_size if your data is in the form of datasets, generators, or keras.utils.Sequence instances (since they generate batches).