0

I'm worked on sentiment analysis task using universal sentence encoder embed_size=512 with CNN but have an error says: Input 0 is incompatible with layer conv1d_6: expected ndim=3, found ndim=2. and wanna know if this is right to add universal sentence encoder with CNN in this way or not?

pickle_in=open("X.pickle","rb")
X=pickle.load(pickle_in)

X = X.tolist() #convert x to list as The embedding code works once I 
converted 
the pandas.series data type to list.
X = np.array(X, dtype=object)[:, np.newaxis]
pickle_in=open("Y.pickle","rb")
Y=pickle.load(pickle_in)
Y = np.asarray(pd.get_dummies(Y), dtype = np.int8)

import tensorflow as tf
import tensorflow_hub as hub
module_url = "https://tfhub.dev/google/universal-sentence-encoder-large/3"
embed = hub.Module(module_url)

X_train, X_test, Y_train, Y_test = train_test_split(X,Y, test_size = 0.15, 

random_state = 42)
X_train, X_Val, Y_train, Y_Val = train_test_split(X_train,Y_train, test_size 
= 0.15, random_state = 42)
print(X_train.shape,Y_train.shape)
print(X_test.shape,Y_test.shape)
print(X_Val.shape,Y_Val.shape)
type(Y_test)

embed_size = embed.get_output_info_dict()['default'].get_shape()[1].value
def UniversalEmbedding(x):
return embed(tf.squeeze(tf.cast(x, tf.string)), 
    signature="default", as_dict=True)["default"]

import keras

seed=7
np.random.seed(seed)

from keras.layers import Input, Dense, concatenate, Activation, 
GlobalMaxPooling1D
from keras import layers
from keras.models import Model

input_text = layers.Input(shape=(1,), dtype=tf.string)
embedding = layers.Lambda(UniversalEmbedding,
    output_shape=(embed_size,))(input_text)

bigram_branch = Conv1D(filters=64, kernel_size=1, padding='same', 
activation='relu', strides=1)(embedding)
bigram_branch = GlobalMaxPooling1D()(bigram_branch)
trigram_branch = Conv1D(filters=64, kernel_size=2, padding='same', 
activation='relu', strides=1)(embedding)
trigram_branch = GlobalMaxPooling1D()(trigram_branch)
fourgram_branch = Conv1D(filters=64, kernel_size=3, padding='same', 
activation='relu', strides=1)(embedding)
fourgram_branch = GlobalMaxPooling1D()(fourgram_branch)
merged = concatenate([bigram_branch, trigram_branch, fourgram_branch], 
axis=1)

merged = Dense(512, activation='relu')(merged)
merged = Dropout(0.8)(merged)
merged = Dense(2)(merged)
output = Activation('sigmoid')(merged)
model = Model(inputs=[tweet_input], outputs=[output])
adam=keras.optimizers.Adam(lr=0.001, beta_1=0.9, beta_2=0.999, epsilon=None, 
decay=0.0, amsgrad=False)
model.compile(loss='mean_squared_error',
                  optimizer= adam,
                  metrics=['accuracy'])
model.summary()
  • You need to change the input shape as follow: inputs = tf.placeholder(dtype=tf.float32, shape=(None, None, embedd_size), name="inputs") This means you are passing a batch of sentences and their vectors. Even with 1 sentence, you will have (1, 1, 512) and it's compatible with Conv1D. – Maziyar Jun 26 '20 at 14:08

1 Answers1

0

You can not directly pass Universal Sentence Encoder to Conv1D because Conv1D expected a tensor with shape [batch, sequence, feature] while the output of Universal Sentence Encoder is [batch, feature]. It is also stated in tfhub.dev:

The input is variable length English text and the output is a 512 dimensional vector.

How can I fix this?

In my view, the easiest possible solution is to use ELMo on Tensorhub. With ELMo you can map each sentence to [batch, sequence, feature] and then feed into the Conv1D.

Amir
  • 16,067
  • 10
  • 80
  • 119