Stack CNN with GRU for image - python-3.x

I am trying to stack CNN 2D with GRU.
I have success to get a way to stack the CNN but I have an error GRU.
Here is my code :
model = Sequential()
#model.add(Dropout(0.25))
model.add(Conv2D(filters = 64, kernel_size = (5,5),padding = 'Same',
activation ='relu', input_shape = (35,152,1)))
model.add(MaxPool2D(pool_size=(2,2)))
model.add(Conv2D(filters = 64, kernel_size = (5,5),padding = 'Same',
activation ='relu'))
model.add(GRU(50,return_sequences=True))
model.add(layers.Dense(nb_labels))
model.summary()
model.compile(optimizer=RMSprop(), loss='mae')
history = model.fit(x_train_pad, y_train_pad,
batch_size=batch_size,
epochs=100,
shuffle=True,
verbose=2,
validation_data=(x_test_pad, y_test_pad), callbacks=[TQDMNotebookCallback(leave_inner=True, leave_outer=True)]) #callbacks=[TQDMNotebookCallback()]
Here is my error:
Anaconda3\lib\site-packages\keras\engine\base_layer.py in assert_input_compatibility(self, inputs)
309 self.name + ': expected ndim=' +
310 str(spec.ndim) + ', found ndim=' +
--> 311 str(K.ndim(x)))
312 if spec.max_ndim is not None:
313 ndim = K.ndim(x)
ValueError: Input 0 is incompatible with layer gru_16: expected ndim=3, found ndim=4
Thanks in advance for your helps

As the ValueError explains, the GRU layer is waiting for a 3-dimensional input but the output of your last Conv2D is of dimension 4 (In your case the dimension is:(None, 17, 76, 64)). Depending on what you need to do, you need to reduce the dimension shape before feeding the GRU layer. For example you can use pooling techniques.

Related

How to fix error validation split in MLP using Keras?

I'm newbie in Neural Network. I'm going to do a text classification research using MLP model with keras. Input layer consisting of 900 nodes, 2 hidden layers, and 2 outputs.
The code I use is as follows:
#Split data training & testing (90:10)
Train_X, Test_X, Train_Y, Test_Y = model_selection.train_test_split(dataset['review'],dataset['sentimen'],test_size=0.2, random_state=8)
Encoder = LabelEncoder()
Train_Y = Encoder.fit_transform(Train_Y)
Test_Y = Encoder.fit_transform(Test_Y)
Tfidf_vect = TfidfVectorizer(max_features=None)
Tfidf_vect.fit(dataset['review'])
Train_X_Tfidf = Tfidf_vect.transform(Train_X)
Test_X_Tfidf = Tfidf_vect.transform(Test_X)
#ANN Architecture
model = Sequential()
model.add(Dense(units = 100, activation = 'sigmoid', input_shape=(32, 900)))
model.add(Dense(units = 100, activation = 'sigmoid'))
model.add(Dense(units = 2, activation = 'sigmoid'))
opt = Adam (learning_rate=0.001)
model.compile(loss = 'binary_crossentropy', optimizer = opt,
metrics = ['accuracy'])
print(model.summary())
#Hyperparameter
epochs= 100
batch_size= 32
es = EarlyStopping(monitor="val_loss",mode='min',patience=10)
model_prediction = model.fit(Train_X_Tfidf, Train_Y, epochs=epochs,
batch_size=batch_size, verbose=1,
validation_split=0.1, callbacks =[es])
But getting Error:
/usr/local/lib/python3.8/dist-packages/keras/engine/data_adapter.py in train_validation_split(arrays, validation_split)
1478 unsplitable = [type(t) for t in flat_arrays if not _can_split(t)]
1479 if unsplitable:
-> 1480 raise ValueError(
1481 "`validation_split` is only supported for Tensors or NumPy "
1482 "arrays, found following types in the input: {}".format(unsplitable))
ValueError: `validation_split` is only supported for Tensors or NumPy arrays, found following types in the input: [<class 'scipy.sparse.csr.csr_matrix'>]
How to Fix it? Thank you so much.

ValueError: Input 0 of layer "lstm" is incompatible with the layer: expected ndim=3, found ndim=2 in a LSTM model

I have this code:
EMBEDDING_DIM = 100
MAXLEN = 16
TRUNCATING = 'post'
PADDING = 'post'
OOV_TOKEN = "<OOV>"
MAX_EXAMPLES = 160000
TRAINING_SPLIT = 0.9
# Initialize an empty numpy array with the appropriate size
EMBEDDINGS_MATRIX = np.zeros((VOCAB_SIZE+1, EMBEDDING_DIM))
# Iterate all of the words in the vocabulary and if the vector representation for
# each word exists within GloVe's representations, save it in the EMBEDDINGS_MATRIX array
for word, i in word_index.items():
embedding_vector = GLOVE_EMBEDDINGS.get(word)
if embedding_vector is not None:
EMBEDDINGS_MATRIX[i] = embedding_vector
# Define the model
def create_model(vocab_size, embedding_dim, maxlen, embeddings_matrix):
model = tf.keras.Sequential([
# Set the Embedding layer when using pre-trained embeddings
tf.keras.layers.Embedding(vocab_size+1, embedding_dim, input_length=maxlen, weights=[embeddings_matrix], trainable=False),
tf.keras.layers.Dropout(0.2),
tf.keras.layers.Conv1D(64, 6, activation='relu'),
# tf.keras.layers.AveragePooling1D(pool_size=4),
tf.keras.layers.GlobalAveragePooling1D(),
tf.keras.layers.LSTM(64),
tf.keras.layers.Dense(8, activation='relu'),
tf.keras.layers.Dense(1, activation='sigmoid')
])
model.compile(loss='binary_crossentropy',
optimizer='adam',
metrics=['accuracy'])
return model.summary()
model = create_model(VOCAB_SIZE, EMBEDDING_DIM, MAXLEN, EMBEDDINGS_MATRIX)
# Train the model
history = model.fit(train_pad_trunc_seq, train_labels, epochs=20, validation_data=(val_pad_trunc_seq, val_labels))
which brings me this error,
ValueError Traceback (most recent call last)
Input In [26], in <cell line: 2>()
1 # Create your untrained model
----> 2 model = create_model(VOCAB_SIZE, EMBEDDING_DIM, MAXLEN, EMBEDDINGS_MATRIX)
4 # Train the model and save the training history
5 history = model.fit(train_pad_trunc_seq, train_labels, epochs=20, validation_data=(val_pad_trunc_seq, val_labels))
Input In [25], in create_model(vocab_size, embedding_dim, maxlen, embeddings_matrix)
4 def create_model(vocab_size, embedding_dim, maxlen, embeddings_matrix):
5
6 ### START CODE HERE
----> 8 model = tf.keras.Sequential([
9 # This is how you need to set the Embedding layer when using pre-trained embeddings
10 tf.keras.layers.Embedding(vocab_size+1, embedding_dim, input_length=maxlen, weights=[embeddings_matrix], trainable=False),
11 tf.keras.layers.Dropout(0.2),
12 tf.keras.layers.Conv1D(64, 6, activation='relu'),
13 # tf.keras.layers.AveragePooling1D(pool_size=4),
14 tf.keras.layers.GlobalAveragePooling1D(),
15 tf.keras.layers.LSTM(64),
16 tf.keras.layers.Dense(8, activation='relu'),
17 tf.keras.layers.Dense(1, activation='sigmoid')
18 ])
20 model.compile(loss='binary_crossentropy',
21 optimizer='adam',
22 metrics=['accuracy'])
24 ### END CODE HERE
File ~\.conda\envs\tf-gpu\lib\site-packages\tensorflow\python\training\tracking\base.py:629, in no_automatic_dependency_tracking.<locals>._method_wrapper(self, *args, **kwargs)
627 self._self_setattr_tracking = False # pylint: disable=protected-access
628 try:
--> 629 result = method(self, *args, **kwargs)
630 finally:
631 self._self_setattr_tracking = previous_value # pylint: disable=protected-access
File ~\.conda\envs\tf-gpu\lib\site-packages\keras\utils\traceback_utils.py:67, in filter_traceback.<locals>.error_handler(*args, **kwargs)
65 except Exception as e: # pylint: disable=broad-except
66 filtered_tb = _process_traceback_frames(e.__traceback__)
---> 67 raise e.with_traceback(filtered_tb) from None
68 finally:
69 del filtered_tb
File ~\.conda\envs\tf-gpu\lib\site-packages\keras\engine\input_spec.py:214, in assert_input_compatibility(input_spec, inputs, layer_name)
212 ndim = shape.rank
213 if ndim != spec.ndim:
--> 214 raise ValueError(f'Input {input_index} of layer "{layer_name}" '
215 'is incompatible with the layer: '
216 f'expected ndim={spec.ndim}, found ndim={ndim}. '
217 f'Full shape received: {tuple(shape)}')
218 if spec.max_ndim is not None:
219 ndim = x.shape.rank
ValueError: Input 0 of layer "lstm_2" is incompatible with the layer: expected ndim=3, found ndim=2. Full shape received: (None, 64)
So I need to have an input parameter such as input = (?,?,?) for my LSTM layer instead of (None, 64), but what should it be?
I have also tried to change GlobalAveragePooling1D() to AveragePooling1D(pool_size=4).
It brings up the summary but gives me a different error:
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
embedding_3 (Embedding) (None, 16, 100) 12829400
dropout_3 (Dropout) (None, 16, 100) 0
conv1d_3 (Conv1D) (None, 11, 64) 38464
average_pooling1d_1 (Averag (None, 2, 64) 0
ePooling1D)
lstm_3 (LSTM) (None, 64) 33024
dense_6 (Dense) (None, 8) 520
dense_7 (Dense) (None, 1) 9
=================================================================
Total params: 12,901,417
Trainable params: 72,017
Non-trainable params: 12,829,400
AttributeError Traceback (most recent call last)
Input In [24], in <cell line: 5>()
2 model = create_model(VOCAB_SIZE, EMBEDDING_DIM, MAXLEN, EMBEDDINGS_MATRIX)
4 # Train the model and save the training history
----> 5 history = model.fit(train_pad_trunc_seq, train_labels, epochs=20, validation_data=(val_pad_trunc_seq, val_labels))
AttributeError: 'NoneType' object has no attribute 'fit'
Please help?
I haven't used it before, but refer to https://www.tensorflow.org/api_docs/python/tf/keras/layers/GlobalAveragePooling1D. It seems that if the input tensor is of dimension n, then GlobalAveragePooling 1D output a tensor with dimension n-1. GlobalAveragePooling1D do pooling along an axis, so it reduces the dim.
If the output tensor shape after conv1d is (None, 11, 64), then the output for GlobalAveragePooling 1D is (None, 64), which is of dimension 2, not 3, so the first attempt results in an error.
Things are different for AveragePooling1D. It does local average pooling, so the dimension of output tensor is the same as input tensor.
https://www.tensorflow.org/api_docs/python/tf/keras/layers/AveragePooling1D
For the second question, refer to https://www.tensorflow.org/api_docs/python/tf/keras/Model#summary. model.summary() just prints a string summary of the network. (I guess the function return value is None). You should return a model with return model, because class Model has the method fit

"ValueError: Input 0 is incompatible with layer conv1d_1: expected ndim=3, found ndim=4"

I am loading VGG19 model and tring to apply 1d conv to decrease depth but I am getting the following error:
"ValueError: Input 0 is incompatible with layer conv1d_1: expected ndim=3, found ndim=4"
This is the function I am using:
def getModel():
base_model = VGG19(weights='imagenet')
model = Model(inputs=base_model.input, outputs=base_model.get_layer('block4_conv4').output)
#model.output=(None, 28, 28, 512)
layer=keras.layers.Conv1D(96, (512), padding='same')
model.summary()
out=(layer)(model.output)
model = Model(inputs=base_model.input, outputs=out)
model.summary()
return model
The problem is that the last output is an output produced by a Conv2D layer which has the shape [batch size, height, width, channels]. This cannot be consumed by a Conv1D. Conv1D consumes [batch size, width, channels] inputs. In your case, since you're interested in cutting down the number of filters, all you need to do is convert your Conv1D to Conv2D.
Simply change your function to,
def getModel():
base_model = VGG19(weights='imagenet')
model = Model(inputs=base_model.input, outputs=base_model.get_layer('block4_conv4').output)
# Here we are using Conv2D not Conv1D which gives 96 filters at the end.
layer=keras.layers.Conv2D(96, (3,3), padding='same')
model.summary()
out=(layer)(model.output)
model = Model(inputs=base_model.input, outputs=out)
model.summary()
return model
Here,
96 - Is the number of filters
(3,3) - Is the kernel height and width of the convolution layer.

Struggling to setup a basic LSTM based on numpy array input

I am trying to setup an LSTM in order to feed it with my numpy array features and labels.
Here is my first attempt:
nb_features =len(seq_cols)
print("initial shape:", X_train.shape)
print("nb features", nb_features)
# X_train = X_train.reshape(X_train.shape + (1,))
print("Seq length ", seq_length)
print('New shape ', X_train.shape)
model = Sequential()
model.add(LSTM(
input_shape=(nb_features, 1),
units=100,
return_sequences=True))
model.add(Dropout(0.2))
model.add(Dense(units=1, activation='sigmoid'))
model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])
model.fit(X_train, y_train, epochs=10, batch_size=200, verbose=1,
callbacks = [EarlyStopping(monitor='val_loss', min_delta=0, patience=0, verbose=0, mode='auto')])
Which gives me the output
initial shape: (175850, 4)
nb features 4
Seq length 50
New shape (175850, 4)
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-99-50959413cb62> in <module>()
1 model.fit(X_train, y_train, epochs=10, batch_size=200, verbose=1,
----> 2 callbacks = [EarlyStopping(monitor='val_loss', min_delta=0, patience=0, verbose=0, mode='auto')])
2 frames
/usr/local/lib/python3.6/dist-packages/keras/engine/training_utils.py in standardize_input_data(data, names, shapes, check_batch_axis, exception_prefix)
126 ': expected ' + names[i] + ' to have ' +
127 str(len(shape)) + ' dimensions, but got array '
--> 128 'with shape ' + str(data_shape))
129 if not check_batch_axis:
130 data_shape = data_shape[1:]
ValueError: Error when checking input: expected lstm_28_input to have 3 dimensions, but got array with shape (175850, 4)
So I am trying to reshape by uncommenting line 4
nb_features =len(seq_cols)
print("initial shape:", X_train.shape)
print("nb features", nb_features)
X_train = X_train.reshape(X_train.shape + (1,))
print("Seq length ", seq_length)
print('New shape ', X_train.shape)
model = Sequential()
model.add(LSTM(
input_shape=(nb_features, 1),
units=100,
return_sequences=True))
model.add(Dropout(0.2))
model.add(Dense(units=1, activation='sigmoid'))
model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])
model.fit(X_train, y_train, epochs=10, batch_size=200, verbose=1,
callbacks = [EarlyStopping(monitor='val_loss', min_delta=0, patience=0, verbose=0, mode='auto')])
which now gives me the error that I have wrong dimensions.
initial shape: (175850, 4)
nb features 4
Seq length 50
New shape (175850, 4, 1)
ValueError: Error when checking input: expected lstm_28_input to have 3 dimensions, but got array with shape (175850, 4)
I think I am just wondering around doing random changes.
Can anyone please give me an insight on what pieces I am missing from the puzzle? I am a beginner in the field and the errors are not helping me much.
P.S: X_train is a numpy array
Keras input_shape ignores the first dimension because it indicates the number of training examples, m. This is because Keras is able to work with any number of training examples, it only cares about the actual input dimensions.
For example, input_shape=(nb_features, 1)=(4,1) means it is expecting the input to be (None, 4, 1), where none is the number of training examples. You can also see this by typing model.summary() after you compile, but before you fit.
This is 3 dimensions, hence the "expected lstm_28_input to have 3 dimensions" error. You're feeding it (175850, 4) which is a two dimensional array.

Why does Keras tell me "ValueError: setting an array element with a sequence." despite having all arrays as numpy arrays?

I am trying to train a 2D neural network using keras. I have a weird error message, "ValueError: setting an array element with a sequence." when I try to use model.fit function in keras. Specifically, the error says that my "tensor_train_labels" is a sequence instead of an array. But my labels are indeed numpy arrays (not a sequence). I am not sure why does keras complain about it ?
I am following this tutorial for building my network
tensor_train_data.shape
#TensorShape([Dimension(209), Dimension(64), Dimension(64), Dimension(3)])
tensor_test_data.shape
#TensorShape([Dimension(50), Dimension(64), Dimension(64), Dimension(3)])
tensor_train_labels = tf.reshape(tensor_train_labels, [209,1])
tensor_test_labels = tf.reshape(tensor_test_labels, [50,1])
batch_size = 10
epochs = 8
model = tf.keras.Sequential()
model.add(tf.keras.layers.Conv2D(32, kernel_size=(3,3), activation='relu',
input_shape=(64, 64, 3)))
model.add(tf.keras.layers.MaxPooling2D(pool_size=(2,2)))
model.add(tf.keras.layers.Dropout(0.25))
model.add(tf.keras.layers.Flatten())
model.add(tf.keras.layers.Dense(128, activation = 'relu'))
model.add(tf.keras.layers.Dropout(0.5))
model.add(tf.keras.layers.Dense(2, activation = 'softmax'))
model.compile(loss='categorical_crossentropy', optimizer =
tf.keras.optimizers.Adam(lr=0.0001, decay=1e-6), metrics=['accuracy'])
model.fit(tensor_train_data/255.0,
tf.keras.utils.to_categorical(tensor_train_labels),
batch_size = batch_size,
shuffle = True,
epochs = epochs,
validation_data = (tensor_test_data/ 255.0,
tf.keras.utils.to_categorical(tensor_test_labels)))
scores = model.evaluate(tensor_test_labels/ 255.0,
tf.keras.utils.to_categorical(tensor_test_labels))
print('Loss: %.3f' % scores[0])
print('Accuracy: %.3f' % scores[1])
The Error :
ValueError Traceback (most recent call last)
<ipython-input-224-80431a1b3e79> in <module>
1 model.compile(loss='categorical_crossentropy', optimizer = tf.keras.optimizers.Adam(lr=0.0001, decay=1e-6), metrics=['accuracy'])
----> 2 model.fit(tensor_train_data/255.0, tf.keras.utils.to_categorical(tensor_train_labels),
3 batch_size = batch_size,
4 shuffle = True,
5 epochs = epochs,
~\AppData\Local\conda\conda\envs\deeplearning\lib\site-packages\tensorflow\python\keras\utils\np_utils.py in to_categorical(y,
num_classes)
37 last.
38 """
---> 39 y = np.array(y, dtype='int')
40 input_shape = y.shape
41 if input_shape and input_shape[-1] == 1 and len(input_shape) > 1:
ValueError: setting an array element with a sequence.
The possible error is that you have arrays of different sizes when you are trying to convert it into the numpy array. Possible solution : https://stackoverflow.com/a/49617425/8185479

Resources