Skip to content
Advertisement

why am I getting warning/error when working with tensorflow (use functional API and not implemented error)

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

  1. For binary classification:

    Let, e.g data['result']=[1,0,0,1,0,0,1,0,0,1] and using loss=tf.keras.losses.BinaryCrossentropy(from_logits=True)

  2. 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.g tf.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)

Advertisement