vgg16 model not converging - keras

I tried to train keras's VGG16 on my dataset of orca calls with 8 classes. Data contains 7 classes for orca calls and 1 class for negative. Data contains spectrogram of orca calls and their corresponding labels.
Even after 50 epocs of training, loss and accuracy is not changing at all. I have tried feature scaling and various learning rate but model is not learning anything at all. I have checked the data manually, it is fine.
code:
model = keras.applications.vgg16.VGG16(include_top=True, weights=None, input_tensor=None, input_shape=(320, 480, 3), pooling='max', classes=8)
opt = keras.optimizers.Adam(lr=0.001, beta_1=0.9, beta_2=0.999, epsilon=1e-8, decay=1e-6, amsgrad=False)
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
model.fit(x=X_train, y= Y_train, batch_size=16, epochs=2000, shuffle=True,validation_split=0.2)
I have read some research papers and I have done some contrasting and other type of preprocessing on images according to those papers. Upper half of images is turned to white as the frequencies I am interested in lies in second half. I chose cmap ='gray', as the frequencies popped out more in it. Should I go for some another cmap?
Some Images from my dataset:
Kaggle kernal: https://www.kaggle.com/sainimohit23/myorcanb.

Related

Transfer Learning on Resnet50 doesn't go beyond 40%

I'm using Kaggle - Animal-10 dataset for experimenting transfer learning with FastAI and Keras.
Base model is Resnet-50.
With FastAI I'm able to get accuracy of 95% in 3 epochs.
learn.fine_tune(3, base_lr=1e-2, cbs=[ShowGraphCallback()])
I believe it only trains the top layers.
With Keras
If I train the complete Resnet then only I'm able to achieve accuracy of 96%
If I use the below code for transfer learning, then at max I'm able to reach 40%
num_classes = 10
#number of layers to retrain from previous model
fine_tune = 33 #conv5 block
model = Sequential()
base_layer = ResNet50(include_top=False, pooling='avg', weights="imagenet")
# base_layer.trainable = False
#make only last few layers trainable, except them make all false
for layer in base_layer.layers[:-fine_tune]:
layer.trainable = False
model.add(base_layer)
model.add(layers.Flatten())
# model.add(layers.BatchNormalization())
# model.add(layers.Dense(2048, activation='relu'))
# model.add(layers.Dropout(rate=0.2))
model.add(layers.Dense(1024, activation='relu'))
model.add(layers.BatchNormalization())
model.add(layers.Dense(num_classes, activation='softmax'))
I assume the cause Transfer learning with Keras, validation accuracy does not improve from outset (beyond naive baseline) while train accuracy improves
and thats the reason that now I'm re-training complete block5 of Resnet and still it doesn't add any value.

CNN model gives accuracy 0f 90% on Validation Images but when predicted on the same validation set, accuracy is hardly 5%

I am new to CNN. I was implementing CNN to classify a dataset with 18000 training images and 10,000 test images into 102 output classes.
I am using Transfer learning and i can see that training accuracy is around 98% and Validation accuracy is around 97%. But when i predict on the same validation dataset, i hardly get 5% accuracy.
I tried L1/L2 regularizarion in Dense layers as looks like overfitting case.
I tried dropouts But didn't able to get more accuracy than 5-6% on Validation dataset itself. Needed some suggestions and input here.
Validation Dataset i had created out of train dataset by randomly selecting 50 images of each of the 102 classes , so validation dataset contains around 5000 images. Below is the code
from keras.applications.mobilenet import preprocess_input
base_model=MobileNet(weights='imagenet',include_top=False)
x=base_model.output
x=GlobalAveragePooling2D()(x)
x=Dense(1024,kernel_regularizer=regularizers.l2(0.3),activation='relu')(x)
x=Dense(1024,kernel_regularizer=regularizers.l2(0.3), activation='relu')(x)
preds=Dense(102,activation='softmax')(x)
model=Model(inputs=base_model.input,outputs=preds)
for layer in model.layers[:44]:
layer.trainable=False
for layer in model.layers[44:]:
layer.trainable=True
train_datagen=ImageDataGenerator(preprocessing_function=preprocess_input)
train_generator=train_datagen.flow_from_directory('./train',
target_size=(224,224),
color_mode='rgb',
batch_size=32,
class_mode='categorical',
shuffle=True)
validation_datagen=ImageDataGenerator(preprocessing_function=preprocess_input)
validation_generator=validation_datagen.flow_from_directory('./Validation',
target_size=(224,224),
color_mode='rgb',
batch_size=32,
class_mode='categorical',
shuffle=True)
model.compile(optimizer='adam',loss='categorical_crossentropy',metrics=['accuracy'])
step_size_train=train_generator.n//train_generator.batch_size
MobileNet=model.fit_generator(generator=train_generator,
steps_per_epoch=step_size_train,
validation_data=validation_generator,
validation_steps=validation_generator.n // validation_generator.batch_size,
epochs=30)

Predicting New ImageNet Pictures

I'm having problems predicting new images based on the ImageNet database where objects are placed on different backgrounds. Predicting the classes work well on various models (ResNets and VGG) but it doesn't work at all for Densenets and Inception. I'm thinking this is related to the labels but I can't figure out what's wrong exactly.
The labels are ordered from 0 to 999 (divided in maps) and are in the same order as the original dataset.
I've changed to labels to the other format (e.g. n02676566). This didn't work for DenseNet (ResNets still worked fine).
Code:
model = keras.applications.densenet.DenseNet201(weights='imagenet', classes=1000)
labels = [str(i) for i in range(0,1000)]
generator_imagenet = ImageDataGenerator().flow_from_directory(path, target_size(224,224), batch_size=64, class_mode='categorical', shuffle=True, classes=labels)
resnet18_model.compile(optimizer='SGD', loss='categorical_crossentropy', metrics=['acc'])
resnet18_model.evaluate_generator(generator_imagenet)
Output ResNet 152:
Found 243 images belonging to 1000 classes. [1.6771895689238245,
0.5679012397189199]
Output DenseNet 201:
Found 243 images belonging to 1000 classes. [15.938421453468102, 0.0]
You will need to preprocess the images using the preprocess_input function provided with each keras_applications model.
Add the following changes.
keras.applications.densenet import preprocess_input
generator_imagenet = ImageDataGenerator(preprocessing_function=preprocess_input).flow_from_directory(path,
target_size(224,224),
batch_size=64,
class_mode='categorical',
shuffle=True,
classes=labels)

Why is the validation accuracy constant at 20%?

I am trying to implement a 5 class animal classifier using Keras. I am building the CNN from scratch and the weird thing is, the validation accuracy stays constant at 0.20 for all epochs. Any idea why this is happening? The dataset folder contains train, test and validation folders. And each of the folders contains 5 folders corresponding to the 5 classes. What am I doing wrong?
I have tried multiple optimizer but the problem persists. I have included the code sample below.
import warnings
warnings.filterwarnings("ignore")
#First convolution layer
model = Sequential()
model.add(Conv2D(filters=32, kernel_size=(3, 3), activation='relu',kernel_initializer='he_normal',input_shape=input_shape))
model.add(MaxPooling2D(pool_size=(2, 2)))
#Second convolution layer
model.add(Conv2D(filters=64, kernel_size=(3, 3), activation='relu',kernel_initializer='he_normal',input_shape=input_shape))
model.add(MaxPooling2D(pool_size=(2, 2)))
#Flatten the outputs of the convolution layer into a 1D contigious array
model.add(Flatten())
#Add a fully connected layer containing 256 neurons
model.add(Dense(256, activation='relu',kernel_initializer='he_normal'))
model.add(BatchNormalization())
#Add another fully connected layer containing 256 neurons
model.add(Dense(256, activation='relu',kernel_initializer='he_normal'))
model.add(BatchNormalization())
#Add the ouput layer containing 5 neurons, because we have 5 categories
model.add(Dense(5, activation='softmax',kernel_initializer='glorot_uniform'))
optim=RMSprop(lr=1e-6)
model.compile(loss='categorical_crossentropy',optimizer=optim,metrics=['accuracy'])
model.summary()
#We will use the below code snippet for rescaling the images to 0-1 for all the train and test images
train_datagen = ImageDataGenerator(rescale=1./255)
#We won't augment the test data. We will just use ImageDataGenerator to rescale the images.
test_datagen = ImageDataGenerator(rescale=1./255)
train_generator = train_datagen.flow_from_directory(train_data_dir,
classes=['frog', 'giraffe', 'horse', 'tiger','dog'],
target_size=(img_width, img_height),
batch_size=batch_size,
class_mode='categorical',
shuffle=False)
validation_generator = test_datagen.flow_from_directory(validation_data_dir,
classes=['frog', 'giraffe', 'horse', 'tiger','dog'],
target_size=(img_width, img_height),
batch_size=batch_size,
class_mode='categorical',
shuffle=False)
hist=History()
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,
callbacks=[hist])
model.save('models/basic_cnn_from_scratch_model.h5') #Save the model weights #Load using: model = load_model('cnn_from_scratch_weights.h5') from keras.models import load_model
print("Time taken to train the baseline model from scratch: ",datetime.now()-global_start)
Check the following for your data:
Shuffle the training data well (I see shuffle=False everywhere)
Properly normalize all data (I see you are doing rescale=1./255, maybe okay)
Proper train/val split (you seem to be doing that too)
Suggestions for your model:
Use multiple Conv2D layers followed by a final Dense. That's what works best for image classification problems. You can also look at popular architectures that are tried and tested; e.g. AlexNet
Can change the optimizer to Adam and try with different learning rates
Have a look at your training and validation loss graphs and see if they look as expected
Also, I guess you corrected the shape of the 2nd Conv2D layer as mentioned in the comments.
It looks as if your output is always the same animal, thus you have a 20% accuracy. I highly recommend you to check your testing outputs to see if they are all the same.
Also you said that you were building a CNN but in the code snipet you posted I see only dense layers, it is going to be hard for a dense architecture to do this task, and it is very small. What is the size of your pictures?
Hope it helps!
The models seems to be working now. I have removed shuffle=False attribute. Corrected the input shape for the 2nd convolution layer. Changed the optimizer to adam. I have reached a validation accuracy of almost 94%. However, I have not yet tested the model on unseen data. There is a bit of overfitting in the model. I will have to use some aggressive dropouts to reduce them. Thanks!

Emotion detection on text

I am a newbie in ML and was experimenting with emotion detection on the text.
So I have an ISEAR dataset which contains tweets with their emotion labeled.
So my current accuracy is 63% and I want to increase to at least 70% or even more maybe.
Heres the code :
inputs = Input(shape=(MAX_LENGTH, ))
embedding_layer = Embedding(vocab_size,
64,
input_length=MAX_LENGTH)(inputs)
# x = Flatten()(embedding_layer)
x = LSTM(32, input_shape=(32, 32))(embedding_layer)
x = Dense(10, activation='relu')(x)
predictions = Dense(num_class, activation='softmax')(x)
model = Model(inputs=[inputs], outputs=predictions)
model.compile(optimizer='adam',
loss='categorical_crossentropy',
metrics=['acc'])
model.summary()
filepath="weights-simple.hdf5"
checkpointer = ModelCheckpoint(filepath, monitor='val_acc', verbose=1, save_best_only=True, mode='max')
history = model.fit([X_train], batch_size=64, y=to_categorical(y_train), verbose=1, validation_split=0.1,
shuffle=True, epochs=10, callbacks=[checkpointer])
That's a pretty general question, optimizing the performance of a neural network may require tuning many factors.
For instance:
The optimizer chosen: in NLP tasks rmsprop is also a popular
optimizer
Tweaking the learning rate
Regularization - e.g dropout, recurrent_dropout, batch norm. This may help the model to generalize better
More units in the LSTM
More dimensions in the embedding
You can try grid search, e.g. using different optimizers and evaluate on a validation set.
The data may also need some tweaking, such as:
Text normalization - better representation of the tweets - remove unnecessary tokens (#, #)
Shuffle the data before the fit - keras validation_split creates a validation set using the last data records
There is no simple answer to your question.

Resources