LSTM: return_sequences has to be set "true" or validation is not working - tensorflow

I'm working on timeseries prediction LSTM.
My problem is model compiles and fit only if
model.add(LSTM(lstmUnits, activation=activation_, return_sequences=True))
model.add(Dense(features, activation=activationOutput_))
model.fit(bx,by,epochs=maxEpoch,validation_split=0.2)
but it does not fit if return_sequences is set to False.
model.add(LSTM(lstmUnits, activation=activation_, return_sequences=False))
model.add(Dense(features, activation=activationOutput_))
model.fit(bx,by,epochs=maxEpoch,validation_split=0.2)
In that case I have got an error like
ValueError: Shapes (None, 30, 2) and (None, 2) are incompatible
pointing fix function line.
Is this possible that fix() build-in validation require LSTM output to be "sequenced" ?
So how can I validate time prediction LSTM?

Related

AttributeError: Exception encountered when calling layer 'lstm' (type LSTM)

I have this error when I add TimeDistributed function to LSTM:
AttributeError: Exception encountered when calling layer 'lstm' (type LSTM). 'LSTMCell' object has no attribute 'kernel'
for this code :
model = Sequential()
# define CNN model
model.add(TimeDistributed(LSTM(64, return_sequences=True, input_shape=(80, 1))))
# model.add(TimeDistributed(LSTM(128, input_shape=(80,1), return_sequences=True)))
# define LSTM model
# model.add(LSTM(64, return_sequences=True))
model.add(LSTM(64))
model.add(TimeDistributed(Dense(100, activation='softmax')))
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
print('Train...')
historyCNN = model.fit(traininp, trainout, epochs=100 ,validation_data=(validinp, validout))
I upgraded keras and tensorflow, I got sure that I m using correct input and output data.
But I have no idea what can the problem be
LSTM layer is already time distributed layer, you don't need to add TimeDistributed to it. Please try just:
model.add(LSTM(64, return_sequences=True, input_shape=(80, 1)))

Incompatible input shape

I have a CNN-LSTM model where the CNN model takes as input data with shape (None, 301,4,1) and outputs data with shape (None, 606). To adapt the cnn output to the input of the LSTM, I added a TimeDistributed Layer where it call the CNN model each window-size=100, so the input shape of this layer=(None, 100,301,4,1), and then we have some stacked LSTM layers.
This is the architecture of the CNN model:
This is the architecture of the LSTM model:
The code for this architecture is the following :
input_layer1=Input(shape=(301,4,1))
...
merge_layer=Concatenate(axis=1)([global_max_pooling, lambda_14])
cnn_model = Model(inputs= input_layer1, outputs=merge_layer) cnn_model.compile(optimizer=RMSprop(),loss="mean_squared_error",metrics=['mse', 'mae'])
input_lstm = Input(shape=(100,301,4,1))
cnn_output = TimeDistributed(cnn_model)(input_lstm)
...
output_layer=Dense(1,activation="linear")(lstm3)
cnn_lstm_model = Model(inputs= input_lstm, outputs=output_layer)
cnn_lstm_model.compile(optimizer=RMSprop(),loss="mean_squared_error",metrics=['mse', 'mae'])
Then saved only the cnn_lstm_model model.
For the training, this is my code:
batchsize=100
epoch=20
cnn_lstm_model.fit(train_data_force_temp_X,data_Y,
batch_size=batchsize,
epochs=epoch,
verbose=1,
shuffle=True,
validation_data=(test_data_force_temp_X,test_Y),
callbacks=[TensorBoard(log_dir="./CNN_LSTM")])
Where train_data_force_temp_X.shape = (1960, 301, 4, 1) , PS: 1960 is number of samples.
But I have this issue :
ValueError: Input 0 is incompatible with layer model_1: expected
shape=(None, 100, 301, 4, 1), found shape=(None, 301, 4, 1)
I understood that passed the wrong shape to the cnn_lstm_model but I thought that it will pass the data first to the cnn model which have the shape=(None, 301, 4, 1) and then for each 100 CNN outputs it will call the time distributed layer and continue the process, It seems I have not understood the process correctly.
So my question is :
do I have to run the data first into the cnn model, do prediction and
then used those outputs as an input for the cnn_lstm model ?
How can I fix the training process ?
Thank you in advance for the help.

What is wrong with the simple code in Keras below?

I am struggling for the last hour to understand what i am doing wrong. I am a novice in NN, but this is not my first code.
def simple_model(lr=0.1):
X = Input(shape=(6144,))
out = Dense(1)(X)
model = Model(inputs=X, outputs=out)
opt = tf.keras.optimizers.SGD(learning_rate=lr)
model.compile(optimizer=opt, loss='mean_squared_error')
model.summary()
return model
mod = simple_model()
a = np.zeros(6144)
v = mod.predict(a)
running this i get the following error:
WARNING:tensorflow:Model was constructed with shape (None, 6144) for input Tensor("input_1:0", shape=(None, 6144), dtype=float32), but it was called on an input with incompatible shape (32, 1).
......
ValueError: Input 0 of layer dense is incompatible with the layer: expected axis -1 of input shape to have value 6144 but received input with shape [32, 1]
Where does this [32, 1] come from ?!
I am sure there is some silly mistake in my code, but can't see it :(
p.s. It does compile the mode and prints the summary before throwing an error
mod = simple_model()
a = np.zeros(6144)
#Add this line
a = np.expand_dims(a,axis=0)
v = mod.predict(a)
The reason why your error appears is that Keras + TensorFlow only allow batch predictions. When we use expand_dims function, we actually create a batch of dimension 1.

Efficientnet inputshape error with tf.data.Dataset

when feeding a tf.data.Dataset to train EfficientnetB0 model I get the following error:
ValueError: in converted code:
C:\Users\fconrad\AppData\Local\Continuum\anaconda3\envs\venv_spielereien\lib\site-packages\tensorflow_core\python\keras\engine\training_v2.py:677 map_fn
batch_size=None)
C:\Users\fconrad\AppData\Local\Continuum\anaconda3\envs\venv_spielereien\lib\site-packages\tensorflow_core\python\keras\engine\training.py:2410 _standardize_tensors
exception_prefix='input')
C:\Users\fconrad\AppData\Local\Continuum\anaconda3\envs\venv_spielereien\lib\site-packages\tensorflow_core\python\keras\engine\training_utils.py:573 standardize_input_data
'with shape ' + str(data_shape))
ValueError: Error when checking input: expected efficientnet-b0_input to have 4 dimensions, but got array with shape (224, 224, 3)
I realy wonder why this happens, since when I create a batch from my Dataset:
train_generator = (tf.data.Dataset
.from_tensor_slices((train_imgs, train_labels))
.map(read_img)
.map(flip_img)
.map(brightness)
.map(blur)
.map(noise)
.map(rotate_90)
.repeat()
.shuffle(512)
.batch(BATCH_SIZE)
.prefetch(True))
validation_generator = (tf.data.Dataset
.from_tensor_slices((validation_imgs, validation_labels))
.map(read_img)
)
print(train_generator.__iter__().__next__()[0].shape)
I get the expected result (64, 224, 224, 3).
But after creating the model the error above raises when I start training:
effn = tfkeras.EfficientNetB0(include_top=False, input_shape=img_shape, classes=4)
effn_model = tf.keras.Sequential()
effn_model.add(effn)
effn_model.add(tf.keras.layers.GlobalAveragePooling2D())
effn_model.add(tf.keras.layers.Dense(4, 'softmax'))
effn_model.compile(optimizer= 'adam', loss='categorical_crossentropy', metrics= ['categorical_accuracy'])
effn_model.fit(train_generator,
epochs=20,
steps_per_epoch=train_imgs.shape[0] // BATCH_SIZE,
validation_data= validation_generator)
Does anyone know why the slices from dataset have shape (64,224,224,3) but the model doesnt recognize the batch dimension? when I try to train a keras.application model, everything works fine.
I use tensorflow 2.1 and the pip install of efficientnet. Thanks
as explained here keras.io/api/applications/efficientnet/
input_shape: Optional shape tuple, only to be specified if include_top is False. It should have exactly 3 inputs channels.
as so try this->
from tensorflow.keras.applications.efficientnet import EfficientNetB0, EfficientNetB5
mm = EfficientNetB0(include_top=True, weights=None, input_tensor=None, input_shape=(128, 128, 3), pooling=None, classes=2, classifier_activation="sigmoid")
mm.summary()
note the input_shape=(128, 128, 3) It has 3 channels.

How to replace the input channel shape from (224, 224, 3) to (224, 224, 1) in VGG16?

I am using VGG16 for transfer learning. My images are grayscale. So, I need to change the input channel shape of Vgg16 from (224, 224, 3) to (224, 224, 1). I tried the following code and got error:
TypeError: build() takes from 1 to 2 positional arguments but 4 were given
Can anyone help me where Am I doing it wrong?
vgg16_model= load_model('Fetched_VGG.h5')
vgg16_model.summary()
# transform the model to Sequential
model= Sequential()
for layer in vgg16_model.layers[1:-1]:
model.add(layer)
# Freezing the layers (Oppose weights to be updated)
for layer in model.layers:
layer.trainable = False
model.build(224,224,1)
model.add(Dense(2, activation='softmax', name='predictions'))
you can't, even if you get rid of the input layer, this model has a graph that has already been compiled and your first conv layer expects an input with 3 channels. I don't think there is really an easy work around to make it accept 1 channel if there is any at all.
you need to repeat your data in third dimension and have the same grayscale image in all 3 bands instead of RGB, that works just fine.
if your image has the shape of : (224,224,1):
import numpy as np
gray_image_3band = np.repeat(gray_img, repeats = 3, axis = -1)
if your image has the shape of : (224,224)
gray_image_3band = np.repeat(gray_img[..., np.newaxis], repeats = 3, axis = -1)
you don't need to call the model.build() anymore this way, keep the input layer. but if you ever wanted to call it you need to pass the shape as a tuple like this:
model.build( (224, 224, 1) ) # this is correct, notice the parentheses