How to resolve the error, Cast int64 to string is not supported de tensorflow?

Viewed 45

Good evening, I would like to perform a small recommendation system withtensorflow recommenders, but I have one with my data, so here is my code.

In fact, I would like to recover the data from a remote database and apply the directives of the QuickStar documentation of tensorflow recommender(https://www.tensorflow.org/recommenders/examples/quickstart), but there is still an error

import sqlalchemy as engines
import tensorflow as tf
import pandas as pd

class BaseEngine():
    """BaseEngine class"""
    def __init__(self, url: str):
        self.engines = engines.create_engine(url)
    
    # get table     
    def get_table(self, name):
        data = pd.read_sql_query("SELECT * from {}".format(name), self.engines)
        # data.to_csv('data/{}'.format(name))
        return data
    
    # select features
    def multi_features(self, tablename: str): # , feature: str, user_id: str
        # data = tf.convert_to_tensor(self.get_table(tablename))
        data = tf.data.Dataset.from_tensor_slices(dict(self.get_table(tablename)))
        return data
        
    def feature(self, tablename: str): # , feature: str
        # data = tf.convert_to_tensor(self.get_table(tablename))
        data = tf.data.Dataset.from_tensor_slices(dict(self.get_table(tablename)))
        return data #.map(lambda x: x[feature])

This is my main file

from random import shuffle
from myengine.engines.ormengines.mysql_engine import MysqlEngine
import tensorflow as tf
import numpy as np

engine = MysqlEngine('sqlite:///base.db')

ratings = engine.feature('ratings')
movies = engine.feature('movies')

for x in ratings.take(1).as_numpy_iterator():
    print(x)
    
for x in movies.take(1).as_numpy_iterator():
    print(x)


# step 2
tf.random.set_seed(42)
shuffled = ratings.shuffle(100_000, seed=42, reshuffle_each_iteration=False)

train = shuffled.take(80_000)
test = shuffled.skip(80_000).take(20_000)


def iter_x(e):
    return {
        'userId': e['userId'],
        'movieId': e['movieId']
    }

def iter_y(e):
    return {
        'title': e['title'],
        'movieId': e['movieId']
    }

def mapping(x):
    return x['userId']

# step 3
movies = movies.batch(1_000).map(iter_y)
ratings = ratings.batch(1_000_000).map(iter_x)
print(ratings)
print(movies)

user_ids_vocabulary = tf.keras.layers.StringLookup(mask_token=None)
user_ids_vocabulary.adapt(ratings.map(mapping))

this the error code

2022-08-19 22:58:28.366801: W tensorflow/core/framework/op_kernel.cc:1722] OP_REQUIRES failed at cast_op.cc:121 : UNIMPLEMENTED: Cast int64 to string is not supported
Traceback (most recent call last):
  File "C:\Users\guera\OneDrive\Documents\recommender\project\app.py", line 48, in <module>
    user_ids_vocabulary.adapt(ratings.map(mapping))
  File "C:\Users\guera\AppData\Local\Programs\Python\Python310\lib\site-packages\keras\layers\preprocessing\string_lookup.py", line 396, in adapt
    super().adapt(data, batch_size=batch_size, steps=steps)
  File "C:\Users\guera\AppData\Local\Programs\Python\Python310\lib\site-packages\keras\engine\base_preprocessing_layer.py", line 249, in adapt
    self._adapt_function(iterator)
  File "C:\Users\guera\AppData\Local\Programs\Python\Python310\lib\site-packages\tensorflow\python\util\traceback_utils.py", line 153, in error_handler
    raise e.with_traceback(filtered_tb) from None
  File "C:\Users\guera\AppData\Local\Programs\Python\Python310\lib\site-packages\tensorflow\python\eager\execute.py", line 54, in quick_execute
    tensors = pywrap_tfe.TFE_Py_Execute(ctx._handle, device_name, op_name,
tensorflow.python.framework.errors_impl.UnimplementedError: Graph execution error:

Detected at node 'Cast' defined at (most recent call last):
    File "C:\Users\guera\OneDrive\Documents\recommender\project\app.py", line 48, in <module>     
      user_ids_vocabulary.adapt(ratings.map(mapping))
    File "C:\Users\guera\AppData\Local\Programs\Python\Python310\lib\site-packages\keras\layers\preprocessing\string_lookup.py", line 396, in adapt
      super().adapt(data, batch_size=batch_size, steps=steps)
    File "C:\Users\guera\AppData\Local\Programs\Python\Python310\lib\site-packages\keras\engine\base_preprocessing_layer.py", line 249, in adapt
      self._adapt_function(iterator)
    File "C:\Users\guera\AppData\Local\Programs\Python\Python310\lib\site-packages\keras\engine\base_preprocessing_layer.py", line 118, in adapt_step
      self.update_state(data)
    File "C:\Users\guera\AppData\Local\Programs\Python\Python310\lib\site-packages\keras\layers\preprocessing\index_lookup.py", line 531, in update_state
      data = utils.ensure_tensor(data, dtype=self.vocabulary_dtype)
    File "C:\Users\guera\AppData\Local\Programs\Python\Python310\lib\site-packages\keras\layers\preprocessing\preprocessing_utils.py", line 33, in ensure_tensor
      inputs = tf.cast(inputs, dtype)
Node: 'Cast'
Cast int64 to string is not supported
         [[{{node Cast}}]] [Op:__inference_adapt_step_117]
2 Answers

Your ratings are in int64 so you cannot do StringLookUp

user_ids_vocabulary = tf.keras.layers.StringLookup(mask_token=None)
user_ids_vocabulary.adapt(ratings.map(mapping))

This is not allowed.

I would suggest changing the ratings to str before using the adapt function.

I try to convert ratings to string as you told me but I have an error against it.

movies = movies.batch(1_000).map(iter_y)
ratings = tf.strings.as_string(
    ratings.batch(1_000_000).map(iter_x),
    precision=-1,
    scientific=False,
    shortest=False,
    width=-1,
    fill='',
    name=None
)

# ratings = tf.cast(ratings.batch(1_000_000).map(iter_x), str)
print(ratings)
print(movies)

# user_ids_vocabulary = tf.keras.layers.StringLookup(mask_token=None)
user_ids_vocabulary = tf.keras.layers.TextVectorization()
user_ids_vocabulary.adapt(ratings.map(mapping)) 

that is the error

    t = convert_to_eager_tensor(value, ctx, dtype)
  File "C:\Users\guera\AppData\Local\Programs\Python\Python310\lib\site-packages\tensorflow\python\framework\constant_op.py", line 102, in convert_to_eager_tensor
    return ops.EagerTensor(value, ctx.device_name, dtype)
ValueError: Attempt to convert a value (<MapDataset element_spec={'userId': TensorSpec(shape=(None,), dtype=tf.int64, name=None), 'movieId': TensorSpec(shape=(None,), dtype=tf.int64, name=None)}>) with an unsupported type (<class 'tensorflow.python.data.ops.dataset_ops.MapDataset'>) to a Tensor.
Related