Working on using Keras VGG16 -- Trouble output shapes - python-3.x

I am trying to train the VGG16 model (from keras.applications) from scratch and I get a weird error
X_train shape is (73257, 48, 48, 3)
Y_train shape is (73257, 10)
I have no idea what's going on... I assume it has to do with the conv layer before it but since I'm importing the model directly from keras I'm having issues figuring out where I went wrong.
My dataset is comprised of 73,257 images which have (48,48,3) shape. I am essentially trying to do character recognition (think mnist flavor) but I am getting hung up on feeding this through the model (with weights set to 0).
model = keras.applications.vgg16.VGG16(include_top=False,
weights=None,
input_shape=(48, 48, 3),
input_tensor=None, pooling='avg', classes=10)
sgd = SGD(lr=.1)
model.compile(loss='categorical_crossentropy',
optimizer=sgd,
metrics=['accuracy'])
print('X_train shape is {}'.format(X_train.shape))
print('Y_train shape is {}'.format(y_train.shape))
model.fit(X_train, y_train,
epochs=20,
batch_size=128)
score = model.evaluate(X_test, y_test, batch_size=128)
This is the error I am getting
File "/home/codebrotherone/PycharmProjects/Computer Vision/deep_neural/dnn.py", line 169, in VGG16
batch_size=128)
File "/home/codebrotherone/anaconda2/envs/tensorflow/lib/python3.4/site-packages/keras/engine/training.py", line 1574, in fit
batch_size=batch_size)
File "/home/codebrotherone/anaconda2/envs/tensorflow/lib/python3.4/site-packages/keras/engine/training.py", line 1411, in _standardize_user_data
exception_prefix='target')
File "/home/codebrotherone/anaconda2/envs/tensorflow/lib/python3.4/site-packages/keras/engine/training.py", line 141, in _standardize_input_data
str(array.shape))
ValueError: Error when checking target: expected block5_pool to have 4 dimensions, but got array with shape (73257, 10)

Ideally, for classification problems, you should have include_top=True and classes=10.
This is enough. Since you're not including top, and are using a global pooling, you should end up with something like (73257,512). But the message you're getting suggests that you have not used the pooling in this attempt. Something is not quite matching.
Anyway, go with this:
model = keras.applications.vgg16.VGG16(include_top=True,
input_shape=(48, 48, 3),
classes=10)

Related

ValueError Input 0 of layer sequential_13 is incompatible with the layer: expected ndim=3, found ndim=4 Full shape received: (None, None, None, None)

I am trying to work with a Simple RNN to predict Parkinson's Gait using Physionet Database. I am feeding the RNN with Images of height 240 and width of 16 pixels. I am also using Model checkpoint and monitor validation accuracy to save the best weights. While trying the input shape to the RNN I am getting that error as
ValueError: Input 0 of layer sequential_13 is incompatible with the layer: expected ndim=3, found ndim=4. Full shape received: (None, None, None, None)
RNN model:
model = Sequential()
model.add(SimpleRNN(24, kernel_initializer='glorot_uniform', input_shape=(64,240), return_sequences = True))
model.add(Activation('relu'))
model.add(Dropout(0.5))
model.add(Flatten())
model.add(Dense(2))
model.add(Activation('softmax'))
opt = optimizers.RMSprop(learning_rate=0.001, decay=1e-6)
epoch=10
early_stopping = EarlyStopping(monitor='val_accuracy', patience=60, verbose=1, mode='auto')
checkpoint = ModelCheckpoint("model_parkinsons.h5",
monitor='val_accuracy', verbose=0, save_best_only=True,
save_weights_only=False, mode='auto', save_freq='epoch')
model.compile(loss='binary_crossentropy',
optimizer=opt,
metrics=['accuracy'])
Batch size:64
Height of the image: 240
a.shape
Output: (64, 16, 240, 1)
I tried to feed the input shape as a.shape[1:]
But I am getting the error as expected 3 dimension but got 4 dimension.
Please help me how to resolve this.
In your first layer, you specified the input shape of your network. This shape does not include your batch size. So, if you specify "input_shape=(64, 240)", this would mean that your final input would need to have the shape (batch_size, 64, 240). Since 64 is your batch size, it seems like there definitely went something wrong there. Additionally, your input has four dimensions: (64, 16, 240, 1), but your first layer takes three dimensional inputs. I do not quite understand what you want to achieve with your model, but it should work if you input a[:, :, :, 0] into your model instead of a. Additionally, you need to set "input_shape=(16, 240)" in your first layer. If you do these two things, then your model uses the RNN to process one column of the image at a time. This approach does not make any sense to me (since RNNs are not used for image processing, at least not in this form), but I do not see any other way to interpret what you already did.

Struggle with LSTM and RNN using Keras

I'm working on a speech recognition problem running on Colab using LSTM. The audio files were converted into spectrograms and then normalized. There are 6840 spectrograms in total and the shape of each one is (288, 864, 4).
I already tried a few examples with RNN and CNN and they worked, but when I try an example using a LSTM I get shape errors, every time either there is one more or one less dimension than expected. Here are some of these cases :
rnn = keras.Sequential()
rnn.add(keras.layers.SimpleRNN(500, input_shape = (864, 4)))
rnn.add(keras.layers.LSTM(500, return_sequences = True))
rnn.add(keras.layers.Dropout(0.2))
rnn.add(keras.layers.LSTM(500, return_sequences = True))
rnn.add(keras.layers.Dropout(0.2))
rnn.add(keras.layers.LSTM(500, return_sequences = True))
rnn.add(keras.layers.Dropout(0.2))
rnn.add(keras.layers.Dense(212, activation = 'softmax'))
rnn.compile(optimizer = 'adam', loss = 'sparse_categorical_crossentropy',metrics = ['accuracy'])
rnn.fit(X_train, y_train, epochs = 5, validation_data=(X_test, y_test))
scores = rnn.evaluate(X_test, y_test, verbose=1)
print('Test loss:', scores[0])
print('Test accuracy:', '%.2f' % (scores[1] * 100), '%')
The following error is raised on the first LSTM layer : ValueError: Input 0 of layer lstm_54 is incompatible with the layer: expected ndim=3, found ndim=2. Full shape received: [None, 500]
If I remove the SimpleRNN line and feed the input directly to the first LSTM like this
rnn.add(keras.layers.LSTM(500, return_sequences = True, input_shape = (288, 864, 4)))
I get : ValueError: Input 0 of layer lstm_56 is incompatible with the layer: expected ndim=3, found ndim=4. Full shape received: [None, 288, 864, 4]
I tried reshaping the images to (4, 288 * 864) and got the same error when trying to use the RNN layer, but with just the LSTM I got InvalidArgumentError: Incompatible shapes: [32] vs. [32,4].
No idea where the 32 came from, though.
One last thing, not really an issue but more of a request, is there any library that can resize images the simple way? 288x864 is too big for Colab, so I'll have to do it eventually to be able to load all 6840 images and feed it to the neural network. Right now I'm just using 100 samples to test.
Feel free to leave suggestions about other methods, cabalistic number of nodes/layers or anything like that.
LSTM input is 3 dimensions [n_samples, n_timesteps, n_features], so your first line also need to enable return sequences:
rnn.add(keras.layers.SimpleRNN(500, return_sequences = True, input_shape = (864, 4)))
Next, your Dense layer will complain from wrong input size, so you want to remove return_sequence on the last LSTM network:
rnn.add(keras.layers.LSTM(500))
If you still want to keep the return_sequences = True on the last LSTM layer, you might want to wrap the Dense layer in a TimeDistributed.
I tried it on the following input and they seems to work
X_train = np.random.rand(100, 864, 4)
y_train = np.random.rand(100, 1)
The PIL from pillow package has plenty of image manipulation methods.

LSTM - Incompatible layer, dimension mismatch?

I'm trying to set up an LSTM model with Keras. The training data has the dimension [7165, 27], and with my current setup it throws the following error:
File "C:\Users\Eier\Anaconda3\lib\site-packages\keras\models.py", line 441, in __init__
self.add(layer)
File "C:\Users\Eier\Anaconda3\lib\site-packages\keras\models.py", line 497, in add
layer(x)
File "C:\Users\Eier\Anaconda3\lib\site-packages\keras\layers\recurrent.py", line 500, in __call__
return super(RNN, self).__call__(inputs, **kwargs)
File "C:\Users\Eier\Anaconda3\lib\site-packages\keras\engine\topology.py", line 575, in __call__
self.assert_input_compatibility(inputs)
File "C:\Users\Eier\Anaconda3\lib\site-packages\keras\engine\topology.py", line 474, in assert_input_compatibility
str(K.ndim(x)))
ValueError: Input 0 is incompatible with layer lstm_64: expected ndim=3, found ndim=4
I know this error is fairly common, but none of the many different solutions found online have worked for me yet. I have already trying reshaping the training data to a 3D matrix, fooling around with different layer combinations, explictly stating batch size, using Flatten() and more to no avail. Would be very grateful if someone could push me in the right direction for fixing this.
Code snippet:
input_dim = 27
units = 5
timesteps = 1
samples = X_train.shape[0]
X_train = np.reshape(X_train, (X_train.shape[0], 1, X_train.shape[1]))
X_test = np.reshape(X_test, (X_test.shape[0], 1, X_test.shape[1]))
model = Sequential([
LSTM(units, return_sequences=True, stateful = True, input_shape=(samples,timesteps,input_dim)),
Dropout(0.2),
LSTM(units,return_sequences=False),
Dropout(0.2),
Dense(1),
Activation('softmax'),
])
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['acc'])
model.fit(X_train, y_train, batch_size = 32, epochs = 60)
As pointed out by #ShubhamPanchal in comments you don't need to specify samples dimension. LSTM layer expects input to have shape [batch_size, time_steps, channels), so when you pass input_shape argument you have to pass tuple specifying time_steps and channels dimension.
LSTM(32, return_sequences=True, stateful = True, input_shape=(time_steps, input_dim))
Since you are using stateful lstm you need to specify the batch_size argument also. So the full code for the model would be,
model = Sequential([
LSTM(units, return_sequences=True, stateful = True, input_shape=(timesteps,input_dim), batch_size=batch_size),
Dropout(0.2),
LSTM(units,return_sequences=False),
Dropout(0.2),
Dense(1),
Activation('softmax'),
])

ImageDataGenerator Shape Issue

I am new to Keras. I am having some issues with shape while using ImageDataGenerator . Below is my code:
train_batches = ImageDataGenerator().flow_from_directory(trainpath,target_size(227,227),classes=['class1','class2'])
x_train, y_train = next(train_batches)
When I print shape of x_train, it gives (32, 227, 227, 3). I am not sure where "32" is coming in the shape. Because of this, I am having issues with training the model.
Any suggestion?
There is parameter that goes inside the method flow_from directory called batch_size, You can learn more about it here
https://keras.io/preprocessing/image/
So if you want to change the shape of the trainig batches generated, you can give a value for batch_size inside flow_from_directory()
train_batches = ImageDataGenerator().flow_from_directory(trainpath,target_size(227,227),batch_size=64,classes=['class1','class2'])
The above code will generate batches of shape (64,227,227,3). Hope this helps

python 3.x Keras ValueError: Error when checking target: expected seq_input to have shape (None, 2) but got array with shape (16, 1)

I am relatively new to Keras/Tensorflow so apologies if the question is basic.
I am trying to train a model on top of the VGG16 model.
for VGG16 I am using:
input_tensor = Input(shape=(img_height, img_width, 3), name='Image_input')
vgg16 = VGG16(include_top=False, weights='imagenet', input_tensor=input_tensor)
then the model I want to train:
seq_model = Sequential(name='seq_input')
seq_model.add(Flatten(input_shape=vgg16.output_shape[1:], name='flatten'))
seq_model.add(Dense(256, activation='relu', name='dense1'))
seq_model.add(Dense(62, activation='relu', name='dense2'))
seq_model.add(Dropout(0.5))
seq_model.add(Dense(nb_classes, activation='sigmoid', name='Output'))
seq_model.compile(loss='binary_crossentropy',
optimizer='rmsprop',
metrics=['accuracy'])
combine the two:
model = Model(input=vgg16.input, output=seq_model(vgg16.output))
model.compile(loss='binary_crossentropy',
optimizer=optimizers.SGD(lr=1e-4, momentum=0.9),
metrics=['accuracy'])
Data augmentation:
train_datagen = ImageDataGenerator(
rescale=1. / 255,
shear_range=0.2,
zoom_range=0.2,
horizontal_flip=True)
test_datagen = ImageDataGenerator(rescale=1. / 255)
train_generator = train_datagen.flow_from_directory(
train_data_dir,
target_size=(img_width, img_height),
batch_size=batch_size,
classes=classes,
class_mode='binary')
validation_generator = test_datagen.flow_from_directory(
validation_data_dir,
target_size=(img_width, img_height),
batch_size=batch_size,
classes=classes,
class_mode='binary')
fit
model.fit_generator(train_generator,
steps_per_epoch=nb_train_samples//batch_size,
epochs=epochs,
validation_data=validation_generator,
validation_steps=nb_validation_samples // batch_size)
The code seems to break when I try to train the model; if i run them individually it seems to work, but when I combine them I get the error below (added full traceback in case it is useful)
Found 200 images belonging to 2 classes.
Found 80 images belonging to 2 classes.
Epoch 1/30
Traceback (most recent call last):
File "C:/Users/nikfotei/Documents/Content/content/inHousemodel/trainModel.py", line 76, in <module>
validation_steps=nb_validation_samples // batch_size)
File "C:\ProgramData\Anaconda3\envs\py353\lib\site-packages\keras\legacy\interfaces.py", line 87, in wrapper
return func(*args, **kwargs)
File "C:\ProgramData\Anaconda3\envs\py353\lib\site-packages\keras\engine\training.py", line 2077, in fit_generator
class_weight=class_weight)
File "C:\ProgramData\Anaconda3\envs\py353\lib\site-packages\keras\engine\training.py", line 1791, in train_on_batch
check_batch_axis=True)
File "C:\ProgramData\Anaconda3\envs\py353\lib\site-packages\keras\engine\training.py", line 1413, in _standardize_user_data
exception_prefix='target')
File "C:\ProgramData\Anaconda3\envs\py353\lib\site-packages\keras\engine\training.py", line 154, in _standardize_input_data
str(array.shape))
ValueError: Error when checking target: expected seq_input to have shape (None, 2) but got array with shape (16, 1)
Process finished with exit code 1
Any ideas?
Let me know in the comments if anything seems messy
The problem is that your labels shape do not match the last layer output..
According to the code you published and according to the error it gives you, the shape of the labels are scalar(!) (0 or 1 probably) while the last layer of your model outputs array with shape 2 (something like ([0.1,0.9],[0.5,0.5] etc).
You should add to flow_from_directory function this param: class_mode="categorical"
so your labels will be encoded to one-hot forma (0 will be [1,0] while 1 will be [0,1] for instance..)

Resources