I am trying to follow this tutorial but with my data: https://www.tensorflow.org/tutorials/structured_data/feature_columns
All of my data is numerical values.
when I ran this part of code:
model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy']) history = model.fit(train_ds, validation_data=test_ds, epochs=100, use_multiprocessing=True)
I am getting this type of warning for all of the parameters:
WARNING:tensorflow:Layers in a Sequential model should only have a single input tensor, but we receive a <class 'dict'> input: {'age': <tf.Tensor 'ExpandDims_8:0' shape=(None, 1) dtype=int64>,
I am getting this warning twice for each variable!
and then I am getting this error:
UnimplementedError: Cast string to float is not supported [[node sequential_7/dense_features_7/calprotectin/Cast (defined at <ipython-input-103-5689ba5df442>:5) ]] [Op:__inference_train_function_4860]
What is the problem and how can I fix it?
Edit1
I tried to mimic my code and error using sample data and I came up with this code.
The code doesn’t generate an error but generates a warning. so the problem is with the data that I am reading. What can go wrong with the input data that generate such an error?
( it is a jupyter code, how can I post it here?) :
%reset import numpy as np import pandas as pd import tensorflow as tf from tensorflow import keras from tensorflow import feature_column from sklearn.model_selection import train_test_split RANDOM_SEED = 42 data=pd.DataFrame() data['sex']=[1,2,2,1,2,2,1,1,2,1] data['age']=[10,11,13,45,67,34,23,62,82,78] data['bmi']=[22.5,28.8,19,23.3,26,18.4,27.5,29,30.3,25.9] data['smoker']=[1,2,2,3,3,2,2,1,1,1] data['lab1']=[144,124,126,146,130,124,171,147,131,138] data['lab2']=[71,82,75,65,56,89,55,74,78,69] data['result']=[1,2,2,4,3,2,1,3,2,4] feature_columns = [] for header in ['sex','age', 'bmi','smoker', 'lab1', 'lab2']: feature_columns.append(tf.feature_column.numeric_column(header)) def create_dataset(dataframe, batch_size=32): dataframe = dataframe.copy() labels = dataframe.pop('result') return tf.data.Dataset.from_tensor_slices((dict(dataframe), labels)) .shuffle(buffer_size=len(dataframe)) .batch(batch_size) train, test = train_test_split(data, test_size=0.2, random_state=RANDOM_SEED) train_ds = create_dataset(train) test_ds = create_dataset(test) model = tf.keras.models.Sequential([ tf.keras.layers.DenseFeatures(feature_columns=feature_columns), tf.keras.layers.Dense(128, activation='relu'), tf.keras.layers.Dense(128, activation='relu'), tf.keras.layers.Dropout(.1), tf.keras.layers.Dense(1) ]) model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy']) history = model.fit(train_ds, validation_data=test_ds, epochs=100, use_multiprocessing=True)
when I run the above code, I am getting this warning:
Epoch 1/100 WARNING:tensorflow:Layers in a Sequential model should only have a single input tensor, but we receive a <class 'dict'> input: {'sex': <tf.Tensor 'ExpandDims_4:0' shape=(None, 1) dtype=int64>, 'age': <tf.Tensor 'ExpandDims:0' shape=(None, 1) dtype=int64>, 'bmi': <tf.Tensor 'ExpandDims_1:0' shape=(None, 1) dtype=float64>, 'smoker': <tf.Tensor 'ExpandDims_5:0' shape=(None, 1) dtype=int64>, 'lab1': <tf.Tensor 'ExpandDims_2:0' shape=(None, 1) dtype=int64>, 'lab2': <tf.Tensor 'ExpandDims_3:0' shape=(None, 1) dtype=int64>} Consider rewriting this model with the Functional API. WARNING:tensorflow:Layers in a Sequential model should only have a single input tensor, but we receive a <class 'dict'> input: {'sex': <tf.Tensor 'ExpandDims_4:0' shape=(None, 1) dtype=int64>, 'age': <tf.Tensor 'ExpandDims:0' shape=(None, 1) dtype=int64>, 'bmi': <tf.Tensor 'ExpandDims_1:0' shape=(None, 1) dtype=float64>, 'smoker': <tf.Tensor 'ExpandDims_5:0' shape=(None, 1) dtype=int64>, 'lab1': <tf.Tensor 'ExpandDims_2:0' shape=(None, 1) dtype=int64>, 'lab2': <tf.Tensor 'ExpandDims_3:0' shape=(None, 1) dtype=int64>} Consider rewriting this model with the Functional API. 1/1 [==============================] - ETA: 0s - loss: -22.8739 - accuracy: 0.2500WARNING:tensorflow:Layers in a Sequential model should only have a single input tensor, but we receive a <class 'dict'> input: {'sex': <tf.Tensor 'ExpandDims_4:0' shape=(None, 1) dtype=int64>, 'age': <tf.Tensor 'ExpandDims:0' shape=(None, 1) dtype=int64>, 'bmi': <tf.Tensor 'ExpandDims_1:0' shape=(None, 1) dtype=float64>, 'smoker': <tf.Tensor 'ExpandDims_5:0' shape=(None, 1) dtype=int64>, 'lab1': <tf.Tensor 'ExpandDims_2:0' shape=(None, 1) dtype=int64>, 'lab2': <tf.Tensor 'ExpandDims_3:0' shape=(None, 1) dtype=int64>} Consider rewriting this model with the Functional API.
When model fit finished, the accuracy is zero. I know that the data is not valid, bit having an accuracy of zero is also not expected.
Advertisement
Answer
The reason you have no improvement when training the model because you using BinaryCrossentropy
loss for multi-labels, deal this error wrt following two case
For binary classification:
Let, e.g
data['result']=[1,0,0,1,0,0,1,0,0,1]
and usingloss=tf.keras.losses.BinaryCrossentropy(from_logits=True)
For multiclass classification:
Using
loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True)
, and modify the output layer of model so it outputs shape match the number of labels, e.gtf.keras.layers.Dense(5)
when you have 5 classes
That WARNING
from tf.keras.models.Sequential()
is simply telling you what it expect from layer within it in order for it to work properly, if you don’t using tf.keras.models.Sequential()
then WARNING
will disappear, e.g define model using:
inputs = {} for header in ['sex','age', 'bmi','smoker', 'lab1', 'lab2']: inputs[header] = tf.keras.Input(shape=(1,), name=header) x = tf.keras.layers.DenseFeatures(feature_columns=feature_columns)(inputs) x = tf.keras.layers.Dense(128, activation='relu')(x) x = tf.keras.layers.Dense(128, activation='relu')(x) x = tf.keras.layers.Dropout(.1)(x) x = tf.keras.layers.Dense(1)(x) model = tf.keras.models.Model(inputs=inputs, outputs=x)
The reason you get that error of Cast string to float
probably due to you try to convert all the columns to numeric column
like you did in that example code you post (i.e maybe better to convert sex
columns to categorical columns
)