increase validation accuracy in CNN - python

Below is my code to classify 2 kind of classes.
The accuracy increase gradually till reach about 87%.
The problem is validation accuracy stuck between 0.5 and 0.6.
I know it is over fitting problem.
I tried to manipulate the number of parameters, but still got same problem.
Any idea about how the model can be improved?
Thanks so much
from keras.models import Sequential
from keras.layers import Conv2D, Dropout, Activation
from keras.layers import MaxPooling2D
from keras.layers import Flatten
from keras.layers import Dense
import matplotlib.pyplot as plt
from keras.preprocessing.image import ImageDataGenerator
classifier = Sequential()
classifier.add(Conv2D(16, (3, 3), input_shape = (110, 110, 3)))
classifier.add(Activation('relu'))
classifier.add(MaxPooling2D(pool_size = (2, 2)))
classifier.add(Conv2D(32,(3,3)))
classifier.add(Activation('relu'))
classifier.add(MaxPooling2D(pool_size =(2,2)))
classifier.add(Conv2D(64,(3,3)))
classifier.add(Activation('relu'))
classifier.add(MaxPooling2D(pool_size =(2,2)))
classifier.add(Flatten())
classifier.add(Dense(64))
classifier.add(Activation('relu'))
classifier.add(Dropout(0.5))
classifier.add(Dense(1))
classifier.add(Activation('sigmoid'))
classifier.compile(optimizer = 'rmsprop', loss = 'binary_crossentropy', metrics = ['accuracy'])
train_datagen = ImageDataGenerator(rescale = 1./255,
shear_range = 0.2,
zoom_range = 0.2,
horizontal_flip = True)
test_datagen = ImageDataGenerator(rescale = 1./255)
training_set =
train_datagen.flow_from_directory('/home/ccc/Downloads/Compressed/CNN/AD/train',
target_size = (110, 110),
batch_size = 10, #10
class_mode = 'binary')
test_set = test_datagen.flow_from_directory('/home/ccc/Downloads/Compressed/CNN/AD/test',
target_size = (110, 110),
batch_size =6, # 6
class_mode = 'binary')
hist = classifier.fit_generator(training_set,
steps_per_epoch = 1160,
epochs = 50,
validation_data = test_set,
validation_steps = 300)
plt.plot(hist.history['accuracy'])
plt.plot(hist.history['val_accuracy'])
plt.title('Model accuracy')
plt.ylabel('Accuracy')
plt.xlabel('Epoch')
plt.legend(['Train', 'Val'], loc='upper left')
plt.show()

Add few more layers.Start with high learning rate and slowly decrease your learning rate. Try different optimizers. I recommend to use transfer learning technique for more validation accuracy.

Related

CNN model predicting the same output for any inputs

enter code here
from keras.models import Sequential
from keras.layers import Convolution2D
from keras.layers import Flatten
from keras.layers import Dense
from keras.layers import MaxPooling2D
classifier = Sequential()
classifier.add(Convolution2D(32,(3,3),input_shape = (64,64,3), activation = 'relu'))
classifier.add(MaxPooling2D(pool_size = (2, 2)))
classifier.add(Convolution2D(32,(3,3), activation = 'relu'))
classifier.add(MaxPooling2D(pool_size = (2, 2)))
classifier.add(Flatten())
classifier.add(Dense(units=32,activation = 'relu'))
classifier.add(Dense(units=64,activation = 'relu'))
classifier.add(Dense(units=128,activation = 'relu'))
classifier.add(Dense(units=256,activation = 'relu'))
classifier.add(Dense(units=256,activation = 'relu'))
classifier.add(Dense(units=6,activation = 'softmax'))
classifier.compile(optimizer = 'adam', loss = 'categorical_crossentropy', metrics = ['accuracy'])
from keras.preprocessing.image import ImageDataGenerator
train_datagen = ImageDataGenerator(rescale = 1./255, # To rescaling the image in range of [0,1]
shear_range = 0.2, # To randomly shear the images
zoom_range = 0.2, # To randomly zoom the images
horizontal_flip = True) # for randomly flipping half of the images
horizontally
test_datagen = ImageDataGenerator(rescale = 1./255)
print("\nTraining the data...\n")
training_set = train_datagen.flow_from_directory('train',
target_size=(64,64),
batch_size=12, #Total no. of batches
class_mode='categorical')
test_set = test_datagen.flow_from_directory('test',
target_size=(64,64),
batch_size=12,
class_mode='categorical')
classifier.fit_generator(training_set,
steps_per_epoch=len(training_set), # Total training images
epochs = 20, # Total no. of epochs
validation_data = test_set,
validation_steps = len(test_set)) # Total testing images
classifier.save("model.h5")
#Prediction
classes = ['Fresh Apple','Fresh Banana','Fresh Orange','Rotten Apple','Rotten Banana','Rotten
Orange']
from keras.preprocessing import image
from keras.models import load_model
import numpy as np
new_model = load_model('model.h5')
filename = 'a1.jpeg'
new_model.summary()
test_image = image.load_img('images\\a1.jpg',target_size=(64,64))
test_image = image.img_to_array(test_image)
test_image = np.expand_dims(test_image, axis = 0)
result = new_model(test_image)
result1 = result[0]
for i in range(6):
if result1[i] == 1.:
break;
prediction = classes[i]
print(prediction)
My model is giving the same output for any input. The errors and warnings have been removed but the output still remains the same. Earlier the model was giving same value 'A'(example) before removing Warnings and after removing Warnings, the model is giving same value 'B'. I don't know where is the problem in my code whether it is in model or whether it is in #Prediction.
A couple of things. In your generators you set a batch size of 12. then in model.fit you have steps_per_epoch=len(training_set). This means you will go through your training set 12 times per epoch. I usually leave steps per epoch and validation steps as None. model.fit will determine the value internally but if you want to then set
steps_per_epoch = int(len(train_set/batch_size) + 1
validation_steps= int(len(test_set/batch_size) +1
Now in predictions. You scaled your train and test images by 1/255. You need to do the same for images you wish to predict. So right after the code to expand dimension add code
test_image=test_image/255

CNNLSTM2D Implementation

There is 2550 images as train set and 1530 images as test set. to classify these images into two classes, a hybrid deep learning model including is used but there is an error is occurred during running the code as is shown below. i was wonder if someone help me to know the ERROR reason. thank you
ERROR:
when checking input: expected conv_lst_m2d_39_input to have 5 dimensions, but got array with shape (32, 64, 64, 3)
# importing libraries
from keras.models import Sequential
from keras.layers import Convolution2D
from keras.layers import MaxPooling2D
from keras.layers import Flatten
from keras.layers import Dense
import tensorflow as tf
from keras.layers.convolutional_recurrent import ConvLSTM2D
from keras.layers.normalization import BatchNormalization
#Data_Prprocessing
from keras.preprocessing.image import ImageDataGenerator
train_datagen = ImageDataGenerator(
rescale=1./255,
shear_range=0.2,
zoom_range=0.2,
horizontal_flip=True)
test_datagen = ImageDataGenerator(rescale=1./255)
training_set = train_datagen.flow_from_directory(
'D:\\thesis\\Paper 3\\Feature Extraction\\two_dimension_Feature_extraction\\stft_feature\\Training_set',
target_size=(64, 64),
batch_size=32,
class_mode='binary')
test_set = test_datagen.flow_from_directory(
'D:\\thesis\\Paper 3\\Feature Extraction\\two_dimension_Feature_extraction\\stft_feature\\Test_set',
target_size=(64, 64),
batch_size=32,
class_mode='binary')
#initializing the CNN
classifier = Sequential()
classifier.add(ConvLSTM2D(filters=40, kernel_size=(3, 3),input_shape=(None, 64, 64, 3), padding='same', return_sequences=True))
classifier.add(BatchNormalization())
classifier.add(ConvLSTM2D(filters=40, kernel_size=(3, 3),
padding='same', return_sequences=True))
classifier.add(BatchNormalization())
classifier.add(ConvLSTM2D(filters=40, kernel_size=(3, 3),
padding='same'))
#Full Connection
classifier.add(Dense(output_dim = 128, activation = 'relu'))
classifier.add(Dense(output_dim = 1, activation = 'sigmoid'))
#compiling the CNN
classifier.compile(optimizer = 'adam', loss = 'binary_crossentropy', metrics = ['accuracy'])
#Fitting the CNN to the images
history = classifier.fit_generator(training_set,
steps_per_epoch=2550,
epochs=25,
validation_data= test_set,
validation_steps=510)
import matplotlib.pyplot as plt
acc = history.history['acc']
val_acc = history.history['val_acc']
loss = history.history['loss']
val_loss = history.history['val_loss']
epochs = range(1, len(acc) + 1)
plt.plot(epochs, acc, 'r', label='Training acc')
plt.plot(epochs, val_acc, 'b', label='Validation acc')
plt.title('Training and validation accuracy')
plt.legend()
plt.figure()
plt.plot(epochs, loss, 'r', label='Training loss')
plt.plot(epochs, val_loss, 'b', label='Validation loss')
plt.title('Training and validation loss')
plt.plot()
plt.legend()
plt.show()
test_loss, test_acc = classifier.evaluate(test_set)
print('test_acc:', test_acc)
ERROR:
ValueError: Input 0 is incompatible with layer conv_lst_m2d_23: expected ndim=5, found ndim=6
New ERROR:
import numpy as np
import glob
from PIL import Image
import tensorflow as tf
images_png = glob.glob("*.png")
images = []
for pic in images_png:
image = tf.read_file(pic)
image = tf.image.decode_png(image, channels=3, dtype=tf.uint16)
image = tf.cast(image, tf.float32)
image = image / 256.0
images.append(image)
img_seq_list = []
for i in range(0, len(images) - 5, 5):
j = i+5
img_seq = np.stack(images[i:j], axis=0)
img_seq_list.append(img_seq)
labels = np.zeros((2,len(img_seq_list) + 1), dtype=int)
labels = np.transpose(labels)
length = len(img_seq_list)/2
length = int(length)
for i in range(0, 255):
if i <= 127:
labels[i][0] = 1
elif i > 127 :
labels[i][1] = 1
import tensorflow as tf
from keras.models import Sequential
from keras.layers import Convolution2D
from keras.layers import MaxPooling2D
from keras.layers import Flatten
from keras.layers import Dense
from keras.layers.convolutional_recurrent import ConvLSTM2D
from keras.layers.normalization import BatchNormalization
classifier = Sequential()
classifier.add(ConvLSTM2D(filters=40, kernel_size=(3, 3),input_shape=(5, 64, 64, 3), padding='same', return_sequences=True))
classifier.add(BatchNormalization())
classifier.add(ConvLSTM2D(filters=40, kernel_size=(3, 3),
padding='same', return_sequences=True))
classifier.add(BatchNormalization())
classifier.add(ConvLSTM2D(filters=40, kernel_size=(3, 3),
padding='same'))
#Full Connection
classifier.add(Dense(output_dim = 128, activation = 'relu'))
classifier.add(Dense(output_dim = 1, activation = 'sigmoid'))
#compiling the CNN
classifier.compile(optimizer = 'adam', loss = 'binary_crossentropy', metrics = ['accuracy'])
train_data = tf.data.Dataset.from_tensor_slices((img_seq_list[0:127], labels[0:127]))
train_data = train_data.shuffle(100).batch(10)
test_data = tf.data.Dataset.from_tensor_slices((img_seq_list[128:254], labels[128:254]))
test_data = train_data.shuffle(100).batch(10)
history = classifier.fit(train_data, validation_data=test_data)
import matplotlib.pyplot as plt
acc = history.history['acc']
val_acc = history.history['val_acc']
loss = history.history['loss']
val_loss = history.history['val_loss']
epochs = range(1, len(acc) + 1)
plt.plot(epochs, acc, 'r', label='Training acc')
plt.plot(epochs, val_acc, 'b', label='Validation acc')
plt.title('Training and validation accuracy')
plt.legend()
plt.figure()
plt.plot(epochs, loss, 'r', label='Training loss')
plt.plot(epochs, val_loss, 'b', label='Validation loss')
plt.title('Training and validation loss')
plt.plot()
plt.legend()
plt.show()
test_loss, test_acc = classifier.evaluate(test_data)
print('test_acc:', test_acc)
I believe the problem is that the convolutional LSTM layer is expecting a temporal sequence of images, so it has to have 5 dimensions including the batch dimension, so something of shape (B, T, H, W, C). You've defined the input shape (ignoring batch dimension) to be (None, 64, 64, 3), so you'll need to input a batch tensor of shape (batch, timesteps, 64, 64, 3).
Also, I believe fit_generator() is deprecated in favor of passing a generator to fit().
EDIT: If you have a sequence of frames from a video stream, you can stack them into an array with one more dimension. You'll have to get the images manually in the correct order from the directories, and then make a data iterator:
images = <ordered list of 3-D numpy arrays>
img_seq = np.stack(images, axis=0)
# Do the above for each sequence of images in the training data to get N sequences
sequences = <list of sequences of images of length N>
labels = <array of labels of length N>
train_data = tf.data.Dataset.from_tensor_slices((sequence, labels))
train_data = train_data.shuffle(1000).batch(batch_size)
# Do similar for test data
You can then use the tf.data.Dataset in fit():
model.fit(train_data, validation_data=test_data)

How to Implement CNN2D+ LSTM Model For Image Classification in Keras?

There is 2550 images as train set and 1530 images as test set. to classify these images into two classes, a hybrid deep learning model including CNN2D+LSTM is used but there is an error is occurred during running the code as is shown below. i was wonder if someone help me to solve it. thanks in advance
ERROR:
RuntimeError: You must compile your model before using it
# importing libraries
from keras.models import Sequential
from keras.layers import Convolution2D
from keras.layers import MaxPooling2D
from keras.layers import Flatten
from keras.layers import Dense
from keras.layers import LSTM
from keras.layers import TimeDistributed
from keras.preprocessing.image import ImageDataGenerator
train_datagen = ImageDataGenerator(
rescale=1./255,
shear_range=0.2,
zoom_range=0.2,
horizontal_flip=True)
test_datagen = ImageDataGenerator(rescale=1./255)
training_set = train_datagen.flow_from_directory(
'D:\\thesis\\Paper 3\\Feature Extraction\\two_dimension_Feature_extraction\\stft_feature\\Training_set',
target_size=(64, 64),
batch_size=32,
class_mode='binary')
test_set = test_datagen.flow_from_directory(
'D:\\thesis\\Paper 3\\Feature Extraction\\two_dimension_Feature_extraction\\stft_feature\\Test_set',
target_size=(64, 64),
batch_size=32,
class_mode='binary')
#initializing the CNN
classifier = Sequential()
#convolution2D
classifier.add(TimeDistributed(Convolution2D(32,3,3, input_shape = (64,64,3), activation = 'relu'))) #32 feature detector with 3*3 dimensions, 64*64 is the used format with 3 channel because the image is colored
#adding maxpooling
classifier.add(TimeDistributed(MaxPooling2D(2, 2)))
#Flattening
classifier.add(TimeDistributed(Flatten()))
classifier.add(TimeDistributed(classifier))
classifier.add(LSTM(units= 20, input_shape = (1,5), return_sequences = True ))
classifier.add(LSTM(units = 20))
#Full Connection
classifier.add(Dense(output_dim = 128, activation = 'relu'))
classifier.add(Dense(output_dim = 1, activation = 'sigmoid'))
#compiling the CNN
classifier.compile(optimizer = 'adam', loss = 'binary_crossentropy', metrics = ['accuracy'])
#Fitting the CNN to the images
history = classifier.fit_generator(training_set,
steps_per_epoch=2550,
epochs=25,
validation_data= test_set,
validation_steps=510)
import matplotlib.pyplot as plt
acc = history.history['acc']
val_acc = history.history['val_acc']
loss = history.history['loss']
val_loss = history.history['val_loss']
epochs = range(1, len(acc) + 1)
plt.plot(epochs, acc, 'r', label='Training acc')
plt.plot(epochs, val_acc, 'b', label='Validation acc')
plt.title('Training and validation accuracy')
plt.legend()
plt.figure()
plt.plot(epochs, loss, 'r', label='Training loss')
plt.plot(epochs, val_loss, 'b', label='Validation loss')
plt.title('Training and validation loss')
plt.plot()
plt.legend()
plt.show()
test_loss, test_acc = classifier.evaluate(test_set)
print('test_acc:', test_acc)

Training and Validation curves have spikes for loss and accuracy when training vgg16

Training and Validation curves have spikes for loss and accuracy when training vgg16. I am using transfer learning technique and have changed the classifier for binary class problem of classifying genders. Can someone suggest me why am i getting such spikes and how can i reduce it.
The code is as follows :
from keras.layers import Input, Lambda, Dense, Flatten, Dropout
from keras.models import Model
from keras.applications.vgg16 import VGG16
from keras.applications.vgg16 import preprocess_input
from keras.preprocessing import image
from keras.preprocessing.image import ImageDataGenerator
from keras.models import Sequential
import numpy as np
from glob import glob
import matplotlib.pyplot as plt
# re-size all the images to this
IMAGE_SIZE = [224, 224]
train_path = 'E:/decompressed_images/data_set/train'
valid_path = 'E:/decompressed_images/data_set/validation'
# add preprocessing layer to the front of VGG
vgg = VGG16(input_shape=IMAGE_SIZE + [3], weights='imagenet', include_top=False)
# don't train existing weights
for layer in vgg.layers:
layer.trainable = False
# useful for getting number of classes
folders = glob('E:/decompressed_images/data_set/train*')
x = Flatten()(vgg.output)
# x = Dense(1000, activation='relu')(x)
prediction = Dense(len(folders), activation='sigmoid')(x)
# create a model object
model = Model(inputs=vgg.input, outputs=prediction)
# view the structure of the model
model.summary()
# tell the model what cost and optimization method to use
model.compile(
loss='binary_crossentropy',
optimizer='adam',
metrics=['accuracy']
)
from keras.preprocessing.image import ImageDataGenerator
train_datagen = ImageDataGenerator(rescale = 1./255,
horizontal_flip = True,
vertical_flip = True,
width_shift_range = 0.1,
height_shift_range = 0.1,
zoom_range = 0.1,
rotation_range = 10)
test_datagen = ImageDataGenerator(rescale = 1./255)
training_set = train_datagen.flow_from_directory('E:/Ullu/new_trial__/balanced_dataset/train',
target_size = (224, 224),
batch_size = 64,
class_mode = 'binary')
test_set = test_datagen.flow_from_directory('E:/Ullu/new_trial__/balanced_dataset/test',
target_size = (224, 224),
batch_size = 64,
class_mode = 'binary')
r = model.fit_generator(
training_set,
validation_data=test_set,
epochs=100,
steps_per_epoch=len(training_set),
validation_steps=len(test_set)
)
plt.plot(r.history['loss'], label='train loss')
plt.plot(r.history['val_loss'], label='val loss')
plt.legend()
plt.show()
plt.savefig('E:/Model_128_30/LossVal_loss.png')
# accuracies
plt.plot(r.history['accuracy'], label='train acc')
plt.plot(r.history['val_accuracy'], label='val acc')
plt.legend()
plt.show()
plt.savefig('E:/Model_128_30/AccVal_acc.png')
import tensorflow as tf
from keras.models import load_model
model.save('E:/Model_128_30/128_30_wt.h5')
High and fluctuating training and validation accuracy image
High and fluctuating training and validation loss image
I tried using dropout layer(0.5) for the final layers but my accuracy and loss for training and validation are the same. Could anyone please suggest me where i am going wrong. Thanks.

How to use a trained model on new inputs?

I have created a CNN model that can be used to differentiate DOGS and CATS. During the training process my model was showing an training accuracy of 99% and testing accuracy of 81% by the end of 4/25 epoch.
Is this normal? or is there any problem that might occur after completion of all the epoch's?
So I need to use this CNN model to my new inputs that do not belong to my training of test set. How do I use my model to predict some new photos?
I have not used classifier.save( ), so after the training can I just use that command so that model gets saved? or do I have to recompile everything with clssifier.save() at the end?
# Part 1 - Building the CNN
# Importing the Keras libraries and packages
from keras.models import Sequential
from keras.layers import Conv2D
from keras.layers import MaxPooling2D
from keras.layers import Flatten
from keras.layers import Dense
# Initialising the CNN
classifier = Sequential()
# Step 1 - Convolution
classifier.add(Conv2D(32, (3, 3), input_shape = (64, 64, 3), activation = 'relu'))
# Step 2 - Pooling
classifier.add(MaxPooling2D(pool_size = (2, 2)))
# Adding a second convolutional layer
classifier.add(Conv2D(32, (3, 3), activation = 'relu'))
classifier.add(MaxPooling2D(pool_size = (2, 2)))
# Step 3 - Flattening
classifier.add(Flatten())
# Step 4 - Full connection
classifier.add(Dense(units = 128, activation = 'relu'))
classifier.add(Dense(units = 1, activation = 'sigmoid'))
# Compiling the CNN
classifier.compile(optimizer = 'adam', loss = 'binary_crossentropy', metrics = ['accuracy'])
# Part 2 - Fitting the CNN to the images
from keras.preprocessing.image import ImageDataGenerator
train_datagen = ImageDataGenerator(rescale = 1./255,
shear_range = 0.2,
zoom_range = 0.2,
horizontal_flip = True)
test_datagen = ImageDataGenerator(rescale = 1./255)
training_set = train_datagen.flow_from_directory('dataset/training_set',
target_size = (64, 64),
batch_size = 32,
class_mode = 'binary')
test_set = test_datagen.flow_from_directory('dataset/test_set',
target_size = (64, 64),
batch_size = 32,
class_mode = 'binary')
classifier.fit_generator(training_set,
steps_per_epoch = 8000,
epochs = 25,
validation_data = test_set,
validation_steps = 2000)
The model has a save method that exports the architecture and training configuration of the model to a file which can be later extracted and used. The documentation for the same can be found here.
After importing the model, you can use the model on any data sets that you want to. About the accuracy of the model, it is possible to achieve the same. There is still a huge difference between the train and test accuracy so at the moment it is over-fitting the data. Also, try to randomize the data and train using them to make sure it is not an exceptional case.

Categories

Resources