Parallel Convolutions using Keras - python

What i am trying to do is create a text classification model which combines CNNS and word embeddings.The basic idea is that we have an Embedding layer at the start of the network and then 2 parallel convolutional networks for find 2,3 - grams.
Each of these convolution layers takes the output of the embedding layer as input.
After the outputs of the two cnn layers are concatenated,flattend and feeded to a Dense.
My input is tokenized,numerical sentences of length 27(shape = (None,27)) and i have 1244 of these sentences.
I've managed to create a sequential model wit ha single cnn layer but struggle wit hthe above
My code so far :
input_shape = Embedding(voc, 100,weights=[embedding_matrix], input_length=X.shape[1])
tower_1 = Conv1D(filters=100, kernel_size=2, activation='relu')(input_shape)
tower_1 = MaxPooling1D(pool_size=2)(tower_1)
tower_2 = Conv1D(filters=100, kernel_size=3, activation='relu')(input_shape)
tower_2 = MaxPooling1D(pool_size=2)(tower_2)
merged = keras.layers.concatenate([tower_1, tower_2,], axis=1)
merged = Flatten()(merged)
out = Dense(3, activation='softmax')(merged)
model = Model(input_shape, out)
This produces this error:
TypeError: Inputs to a layer should be tensors. Got: <keras.layers.embeddings.Embedding object at 0x7fadca016dd0>
i have also trid replacing
input_shape = Embedding(voc, 100,weights=[embedding_matrix], input_length=X.shape[1])
with:
input_tensor = Input(shape=(1244,27))
input_shape = Embedding(voc, 100,weights=[embedding_matrix], input_length=X.shape[1])(input_tensor)
which gives me this error:
ValueError: Input 0 of layer "max_pooling1d_23" is incompatible with the layer: expected ndim=3, found ndim=4. Full shape received: (None, 1244, 26, 100)

You should define your Input layer without the number of samples. Just the sentence length:
import tensorflow as tf
inputs = tf.keras.layers.Input((27,))
embedded = tf.keras.layers.Embedding(50, 100, input_length=27)(inputs)
tower_1 = tf.keras.layers.Conv1D(filters=100, kernel_size=2, activation='relu')(embedded)
tower_1 = tf.keras.layers.MaxPooling1D(pool_size=2)(tower_1)
tower_2 = tf.keras.layers.Conv1D(filters=100, kernel_size=3, activation='relu')(embedded)
tower_2 = tf.keras.layers.MaxPooling1D(pool_size=2)(tower_2)
merged = tf.keras.layers.concatenate([tower_1, tower_2,], axis=1)
merged = tf.keras.layers.Flatten()(merged)
out = tf.keras.layers.Dense(3, activation='softmax')(merged)
model = tf.keras.Model(inputs, out)
print(model.summary())
Usage:
samples = 5
random_input = tf.random.uniform((samples, 27), maxval=50, dtype=tf.int32)
print(model(random_input))
tf.Tensor(
[[0.31525075 0.33163014 0.3531191 ]
[0.3266019 0.3295619 0.34383622]
[0.32351935 0.32669052 0.34979013]
[0.32954428 0.33178467 0.33867106]
[0.32966062 0.3283257 0.34201372]], shape=(5, 3), dtype=float32)

Related

Input Shape in Keras Autoencoder

i'm trying to train an autoencoder in the following code:
encoder_input = keras.layers.Input(shape=(x_Train.shape[1]), name='img')
encoder_out = keras.layers.Dense(1, activation = "relu")(encoder_input)
encoder = keras.Model(encoder_input, encoder_out, name="encoder")
decoder_input = keras.layers.Dense(602896, activation = "relu")(encoder_out)
decoder_output = keras.layers.Reshape((769, 28, 28))(decoder_input)
opt = keras.optimizers.RMSprop(learning_rate=1e-3)
autoencoder = keras.Model(encoder_input, decoder_output, name = "autoencoder")
autoencoder.summary()
autoencoder.compile(opt, loss='mse')
autoencoder.fit(x_Train, x_Train, epochs=10, batch_size=64, validation_split = 0.1)
However, it returns the error:
"tensorflow:Model was constructed with shape (None, 28) for input KerasTensor(type_spec=TensorSpec(shape=(None, 28), dtype=tf.float32, name='img'), name='img', description="created by layer 'img'"), but it was called on an input with incompatible shape (None, 28, 28)."
I don't know how to deal with that or to resize my input. My x_train is a vector with size [769,28,28]
Could someone help me to handle the error?
That's the summary
Thanks
Your input shape for your autoencoder is a little weird, your training data has a shaped of 28x28, with 769 as your batch, so the fix should be like this:
encoder_input = keras.layer.Input(shape=(28, 28), name='img')
encoder_out = keras.layers.Dense(1, activation = "relu")(encoder_input)
# For ur decoder, you need to change a bit as well
decoder_input = keras.layers.Dense(784, activation = "sigmoid")(encoder_out) # Flatten until 28x28 =784
decoder_output = keras.layers.Reshape((28, 28))(decoder_input) # From there reshape back to 28x28
The problem (apart from the wrong shape in the input layer (has to be shape=(28, 28) and the output layer (has to be (28,28)) like in Edwin Cheong 's answer) is that you forgot a flatten layer after your input layer. This leads to the incompatible shape.
Adapted the answer from above:
encoder_input = keras.layer.Input(shape=(28, 28), name='img')
encoder_input = keras.layer.Flatten()(encoder_input)
encoder_out = keras.layers.Dense(1, activation = "relu")(encoder_input)
decoder_input = keras.layers.Dense(784, activation = "sigmoid")(encoder_out)
decoder_output = keras.layers.Reshape((28, 28))(decoder_input)

Input 0 is incompatible with layer lstm_34: expected ndim=3, found ndim=2

I'm inputting a 2D array of (822222, 2) into this model:
regressor = Sequential()
regressor.add (LSTM (2, activation = 'sigmoid', dropout = .1))
regressor.add (Dense (2, activation = 'tanh'))
regressor.compile (optimizer = 'rmsprop', loss = 'mean_squared_error')
regressor.fit (x = document, y = document, batch_size = 32, epochs = 1000)
but this returns an error on the last line, only accepting an array with ndim = 3:
Input 0 is incompatible with layer lstm_34: expected ndim=3, found ndim=2
I tried reshaping, but most configurations I come up with make the data unusable. What would make the model accept my inputs?

TensorFlow: How do I use make a convolutional layer for tabular (1-D) features?

Using TensorFlow in Python, I am making a neural network that has a 1 dimensional array as input. I would like to add a convolutional layer to the network, but can't seem to get it to work.
My training data looks something like this:
n_samples = 20
length_feature = 10
features = np.random.random((n_samples, length_feature))
labels = np.array([1 if sum(e)>5 else 0 for e in features])
If I make a neural network like this one
model = keras.Sequential([
keras.layers.Dense(10, activation='relu', input_shape=(length_feature, )),
keras.layers.Dense(2, activation='softmax')
])
model.compile(optimizer='adam',
loss='sparse_categorical_crossentropy',
metrics=['accuracy'])
history = model.fit(features, labels, batch_size=5, validation_split = 0.2, epochs=10)
and this works just fine. But if I add a convolutional layer like this
model = keras.Sequential([
keras.layers.Dense(10, activation='relu', input_shape=(length_feature, )),
keras.layers.Conv1D(kernel_size = 3, filters = 2),
keras.layers.Dense(2, activation='softmax')
])
then I get the error
ValueError: Input 0 of layer conv1d_4 is incompatible with the layer: expected ndim=3, found ndim=2. Full shape received: [None, 10]
How can I add a convolutional layer to my neural network?
Conv1D expects a 3D output( batch_size, width, channels). But the dense layers produces a 2D output. Simply change your model to the following,
model = keras.Sequential([
keras.layers.Dense(10, activation='relu', input_shape=(length_feature, )),
keras.layers.Lambda(lambda x: K.expand_dims(x, axis=-1))
keras.layers.Conv1D(kernel_size = 3, filters = 2),
keras.layers.Dense(2, activation='softmax')
])
Where K is either keras.backend or tf.keras.backend depending on which one you used to get layers.

How to replace dense layer with convolutional one?

I wanted to replace the Dense_out layer with a convolution one, can anybody tell me how to do it?
code:
model = Sequential()
conv_1 = Conv2D(filters = 32,kernel_size=(3,3),activation='relu')
model.add(conv_1)
conv_2 = Conv2D(filters=64,kernel_size=(3,3),activation='relu')
model.add(conv_2)
pool = MaxPool2D(pool_size = (2,2),strides = (2,2), padding = 'same')
model.add(pool)
drop = Dropout(0.5)
model.add(drop)
model.add(Flatten())
Dense_1 = Dense(128,activation = 'relu')
model.add(Dense_1)
Dense_out = Dense(57,activation = 'softmax')
model.add(Dense_out)
model.compile(optimizer='Adam',loss='categorical_crossentropy',metric=['accuracy'])
model.fit(train_image,train_label,epochs=10,verbose = 1,validation_data=(test_image,test_label))
print(model.summary())
when I'm trying this code :
model = Sequential()
conv_01 = Conv2D(filters = 32,kernel_size=(3,3),activation='relu')
model.add(conv_01)
conv_02 = Conv2D(filters=64,kernel_size=(3,3),activation='relu')
model.add(conv_02)
pool = MaxPool2D(pool_size = (2,2),strides = (2,2), padding = 'same')
model.add(pool)
conv_11 = Conv2D(filters=64,kernel_size=(3,3),activation='relu')
model.add(conv_11)
pool_2 = MaxPool2D(pool_size=(2,2),strides=(2,2),padding='same')
model.add(pool_2)
drop = Dropout(0.3)
model.add(drop)
model.add(Flatten())
Dense_1 = Dense(128,activation = 'relu')
model.add(Dense_1)
Dense_2 = Dense(64,activation = 'relu')
model.add(Dense_2)
conv_out = Conv2D(filters= 64,kernel_size=(3,3),activation='relu')
model.add(Dense_out)
model.compile(optimizer='Adam',loss='categorical_crossentropy',metrics=['accuracy'])
model.fit(train_image,train_label,epochs=10,verbose = 1,validation_data=(test_image,test_label))
I get the following error
ValueError: Input 0 of layer conv2d_3 is incompatible with the layer:
expected ndim=4, found ndim=2. Full shape received: [None, 64]
I am new at this so an explanation would greatly help
You will need to reshape to be able to use a 2x2 filter as needed in a conv2D layer.
You can use:
out = keras.layers.Reshape(target_shape)
model.add(out)
and then do the convolution:
conv_out = Conv2D(filters=3,kernel_size=(3,3),activation='softmax')
model.add(conv_out)
with filters being the number of channels you want in you output layer (3 for RGB).
More info about the layers and parameters in Keras Documentation

Concatenate multiple Convolution Layers

Text classification by extracting tri-grams and quad-grams features of character level inputs using multiple concatenated CNN layers and passing it to BLSTM layer
submodels = []
for kw in (3, 4): # kernel sizes
model = Sequential()
model.add(Embedding(vocab_size, 16,input_length=maxlen,input_shape=(maxlen,vocab_size))
model.add(Convolution1D(nb_filter=64, filter_length=kw,
border_mode='valid', activation='relu'))
submodels.append(model)
big_model = Sequential()
big_model.add(keras.layers.Concatenate(submodels))
big_model.add(Bidirectional(LSTM(100, return_sequences=False)))
big_model.add(Dense(n_out,activation='softmax'))
Model summary of individual conv layers:
Layer (type) Output Shape Param
------------ ------------ -----
embedding_49 (Embedding) (None, 1024, 16) 592
conv1d_41 (Conv1D) (None, 1024, 64) 4160
But, I am getting this error:
ValueError: Input 0 is incompatible with layer conv1d_22: expected
ndim=3, found ndim=4
UPDATE NOW USING FUNCTIONAL KERAS API
x = Input(shape=(maxlen,vocab_size))
x=Embedding(vocab_size, 16, input_length=maxlen)(x)
x=Convolution1D(nb_filter=64, filter_length=3,border_mode='same',
activation='relu')(x)
x1 = Input(shape=(maxlen,vocab_size))
x1=Embedding(vocab_size, 16, input_length=maxlen)(x1)
x1=Convolution1D(nb_filter=64, filter_length=4,border_mode='same',
activation='relu')(x1)
x2 = Bidirectional(LSTM(100, return_sequences=False))
x2=Dense(n_out,activation='softmax')(x2)
big_model = Model(input=keras.layers.Concatenate([x,x1]),output=x2)
big_model.compile(loss='categorical_crossentropy', optimizer='adadelta',
metrics=['accuracy'])
Still the same error!
from keras import Input
from keras import Model
vocab_size = 1000
maxlen = 100
n_out = 1000
input_x = Input(shape=(None,))
x=layers.Embedding(vocab_size, 16, input_length=maxlen)(input_x)
x=layers.Convolution1D(nb_filter=64, filter_length=3,border_mode='same',activation='relu')(x)
input_x1 = Input(shape=(None,))
x1=layers.Embedding(vocab_size, 16, input_length=maxlen)(input_x1)
x1=layers.Convolution1D(nb_filter=64, filter_length=4,border_mode='same',
activation='relu')(x1)
concatenated = layers.concatenate([x,x1],axis = -1)
x2 = layers.Bidirectional(layers.LSTM(100, return_sequences=False))(concatenated)
x2=layers.Dense(n_out,activation='softmax')(x2)
big_model = Model([input_x,input_x1],output=x2)
big_model.compile(loss='categorical_crossentropy', optimizer='adadelta',
metrics=['accuracy'])

Categories