Montana Burr
Montana Burr

Reputation: 287

Tensor conversion requested dtype string for Tensor with dtype float32 (lambda input)

I am using Keras' Lambda layer with TensorFlow Hub to download word embeddings from a pre-built embedder.

import tensorflow_hub as hub
from tensorflow.dtypes import as_string
def embedding(x):
    print(x.shape)
    module = hub.Module("https://tfhub.dev/google/nnlm-en-dim128/1")
    return module(x)
answers_network_rnn = Sequential()
print(trainingData["question"].shape)
answers_network_rnn.add(Lambda(embedding,output_shape=(128,)))
answers_network_rnn.add(Dense(16))
answers_network_rnn.add(Dense(Y_2_train_num.shape[1]))
answers_network_rnn.summary()
answers_network_rnn.compile("adam","categorical_crossentropy",metrics=['accuracy',f1]) answers_network_rnn_checkpoint = ModelCheckpoint('answers_network-rnn-best.h5', verbose=1, monitor='val_f1',save_best_only=True, mode='auto') answers_network_rnn.fit(x=X_2_train_text.values,y=Y_2_train_num) 

I expect Keras to have built a model with a list of 128 word embeddings for each word in my inputs. In reality, the Lambda layer causes the following error when it runs on the "embedding" function.

"ValueError: Tensor conversion requested dtype string for Tensor with dtype float32: 'Tensor("sequential_5_input:0", shape=(?, 2), dtype=float32)'"

According to user nuric on a GitHub issue (https://github.com/keras-team/keras/issues/10021) this problem is caused by Keras attempting to infer the output shape. As you can see, I have attempted to resolve this issue by specifying the desired output shape.

Here's the input and desired output for the neural network:

Input

[['to whom did the virgin mary allegedly appear in 1858 in lourdes france?'
  'architecturally, the school has a catholic character. atop the main building\'s gold dome is a golden statue of the virgin mary. immediately in front of the main building and facing it, is a copper statue of christ with arms upraised with the legend "venite ad me omnes". next to the main building is the basilica of the sacred heart. immediately behind the basilica is the grotto, a marian place of prayer and reflection. it is a replica of the grotto at lourdes, france where the virgin mary reputedly appeared to saint bernadette soubirous in 1858. at the end of the main drive (and in a direct line that connects through 3 statues and the gold dome), is a simple, modern stone statue of mary.']
 ['what is in front of the notre dame main building?'
  'architecturally, the school has a catholic character. atop the main building\'s gold dome is a golden statue of the virgin mary. immediately in front of the main building and facing it, is a copper statue of christ with arms upraised with the legend "venite ad me omnes". next to the main building is the basilica of the sacred heart. immediately behind the basilica is the grotto, a marian place of prayer and reflection. it is a replica of the grotto at lourdes, france where the virgin mary reputedly appeared to saint bernadette soubirous in 1858. at the end of the main drive (and in a direct line that connects through 3 statues and the gold dome), is a simple, modern stone statue of mary.']
 ['the basilica of the sacred heart at notre dame is beside to which structure?'
  'architecturally, the school has a catholic character. atop the main building\'s gold dome is a golden statue of the virgin mary. immediately in front of the main building and facing it, is a copper statue of christ with arms upraised with the legend "venite ad me omnes". next to the main building is the basilica of the sacred heart. immediately behind the basilica is the grotto, a marian place of prayer and reflection. it is a replica of the grotto at lourdes, france where the virgin mary reputedly appeared to saint bernadette soubirous in 1858. at the end of the main drive (and in a direct line that connects through 3 statues and the gold dome), is a simple, modern stone statue of mary.']

Desired output:

[[0. 0. 0. ... 0. 0. 0.]
 [0. 0. 0. ... 0. 0. 0.]
 [0. 0. 0. ... 0. 0. 0.]
 ...
 [0. 0. 0. ... 0. 0. 0.]
 [0. 0. 0. ... 0. 0. 0.]
 [1. 0. 0. ... 0. 0. 0.]]

Upvotes: 1

Views: 3092

Answers (1)

josh
josh

Reputation: 126

I just tried it out and it works for me when I remove "input_shape = [None],". So this code should work:

import tensorflow_hub as hub
from tensorflow.dtypes import as_string
def embedding(x):
    print(x.shape)
    module = hub.Module("https://tfhub.dev/google/nnlm-en-dim128/1")
    return module(x)
answers_network_rnn = Sequential()
print(trainingData["question"].shape)
from keras.layers import InputLayer
answers_network_rnn.add(Lambda(embedding,output_shape=(128,)))
answers_network_rnn.add(Dense(16))
answers_network_rnn.add(Dense(Y_2_train_num.shape[1]))
answers_network_rnn.summary()

EDIT

This keras model should be equal to the SequentialModel (except the explicit input layer):

input_text = tf.keras.layers.Input(shape=(1,), dtype=tf.string)
embedding_layer = tf.keras.layers.Lambda(embedding,output_shape=(128,))(input_text)
dense = tf.keras.layers.Dense(16)(embedding_layer)
outputs = tf.keras.layers.Dense(Y_2_train_num.shape[1])(dense)

answers_network_rnn = tf.keras.Model(inputs=[input_text], outputs=outputs)
answers_network_rnn.compile(...)

Running this works for me ...

with tf.Session() as session:
  session.run([tf.global_variables_initializer(), tf.tables_initializer()])
  answers_network_rnn.fit(...)

... after changing this in the lambda function:

#return module(x)
return module(tf.squeeze(tf.cast(x, tf.string)),signature="default", as_dict=True)["default"]

Upvotes: 2

Related Questions