How should i increase accuracy of face recognition using cnn? - python

from tensorflow.python.keras.applications.inception_v3 import preprocess_input
from tensorflow.python.keras.preprocessing.image import ImageDataGenerator
from tensorflow.python.keras.models import Sequential
from tensorflow.python.keras.layers import Dense, Flatten, Conv2D, MaxPool2D, Dropout
from keras.layers.normalization import BatchNormalization
from keras import regularizers
import os
os.environ["CUDA_DEVICE_ORDER"] = "PCI_BUS_ID"
os.environ['CUDA_VISIBLE_DEVICES'] = '-1'
data_gen = ImageDataGenerator(preprocessing_function=preprocess_input, shear_range=0.2, zoom_range=0.2, horizontal_flip=True)
train_gen = data_gen.flow_from_directory('/home/bg22/PycharmProjects/KUNAL/dataset/training_set', target_size=(64,64), batch_size=16, class_mode='categorical')
test_gen = data_gen.flow_from_directory('/home/bg22/PycharmProjects/KUNAL/dataset/test_set', target_size=(64,64), batch_size=16, class_mode='categorical')
model = Sequential()
model.add(Conv2D(32, kernel_size=(3, 3), activation='relu', input_shape=(64, 64, 3)))
#model.add(BatchNormalization())
#model.add(Dropout(0.5))
model.add(MaxPool2D(pool_size=(2, 2)))
model.add(Conv2D(32, kernel_size=(3, 3), activation='relu'))
#model.add(BatchNormalization())
#model.add(Dropout(0.5))
model.add(MaxPool2D(pool_size=(2, 2)))
model.add(Conv2D(16, kernel_size=(3, 3), activation='relu'))
#model.add(BatchNormalization())
#model.add(Dropout(0.5))
model.add(MaxPool2D(pool_size=(2, 2)))
model.add(Conv2D(16, kernel_size=(3, 3), activation='relu'))
#model.add(BatchNormalization())
#model.add(Dropout(0.5))
model.add(MaxPool2D(pool_size=(2, 2)))
model.add(Flatten())
#model.add(Dense(16, activation='relu', kernel_regularizer=regularizers.l2(0.01)))
model.add(Dense(2, activation='softmax'))
model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])
model.fit_generator(train_gen, epochs= 10, validation_data=test_gen)
With this architecture i'm getting 80% accuracy.
I tried these methods to increase accuracy:
Batch normalization
Weight Decay(L2 regularizer)
Dropout
But all of them failed to give expected result.
Batch normalization gives error:
/usr/bin/python3.5 "/home/bg22/PycharmProjects/KUNAL/Face Recognition.py"
Using TensorFlow backend.
Found 8000 images belonging to 2 classes.
Found 2000 images belonging to 2 classes.
Traceback (most recent call last):
File "/home/bg22/PycharmProjects/KUNAL/Face Recognition.py", line 20, in <module>
model.add(BatchNormalization())
File "/usr/local/lib/python3.5/dist-packages/tensorflow/python/training/checkpointable/base.py", line 364, in _method_wrapper
method(self, *args, **kwargs)
File "/usr/local/lib/python3.5/dist-packages/tensorflow/python/keras/engine/sequential.py", line 130, in add
'Found: ' + str(layer))
TypeError: The added layer must be an instance of class Layer. Found: keras.layers.normalization.BatchNormalization object at 0x7fddf526e9e8>
On the other hand Dropout and regularizer reduces the accuracy instead!!

First you have import the BatchNormalization layer from keras.layers.BatchNormalization. You can take the following measures to increase the accuracy.
Decrease the batch size.
Decrease the learning rate to a smaller number like 0.001 or 0.0001.
Slightly increase the dropout rates to 0.5 or 0.6.
Use the LeakyReLU activation with alpha ( negative slope ) 0.2 or 0.01.
Try using AdaGrad or Nadam optimizers.
Add two Conv2d layers and then add the pooling layer.

Related

ValueError: Shapes (None, 1) and (None, 64) are incompatible Keras

I'm trying to build a sequential model . I have 32 features as the input dimension and it's a classification problem.
this is the result of the summary :
and this is my model:
#Create an ANN using Keras and Tensorflow backend
from keras.wrappers.scikit_learn import KerasClassifier
from keras.models import Sequential
from keras.layers import Dense, Dropout,Activation
from keras.optimizers import Adam,SGD
nb_epoch = 200
batch_size = 64
input_d = X_train.shape[1]
model = Sequential()
model.add(Dense(512, activation='relu', input_dim=input_d))
model.add(Dropout(0.5))
model.add(Dense(128, activation='relu', input_dim=input_d))
model.add(Dropout(0.5))
model.add(Dense(64, activation='relu'))
model.add(Dropout(0.3))
model.add(Activation('softmax'))
sgd = SGD(lr=0.01, decay=1e-6, momentum=0.9, nesterov=True)
rms = 'rmsprop'
model.compile(loss='categorical_crossentropy',
optimizer=sgd,
metrics=['accuracy'])
the test and train shape are both 32. I get the ValueError: Shapes (None, 1) and (None, 64) are incompatible error whnever I want to fit the model but I have no idea why.
Much thanks.
The loss function is expecting a tensor of shape (None, 1) but you give it (None, 64). You need to add a Dense layer at the end with a single neuron which will get the final results of the calculation:
model = Sequential()
model.add(Dense(512, activation='relu', input_dim=input_d))
model.add(Dropout(0.5))
model.add(Dense(128, activation='relu', input_dim=input_d))
model.add(Dropout(0.5))
model.add(Dense(64, activation='relu'))
model.add(Dropout(0.3))
model.add(Dense(1, activation='softmax'))

CNN model not learning

I'm building a CNN model to classify images, however, I guess that my model is not learning because of the constant values of accuracy and loss function. See my code below:
Building the images train, test and validation datasets
import pandas as pd
from keras_preprocessing.image import ImageDataGenerator
import numpy as np
#Creating three datasets from the the 3 .txt files.
trainingfile = pd.read_table('data/training.txt', delim_whitespace=True, names=('class', 'image'))
testingfile = pd.read_table('data/testing.txt', delim_whitespace=True, names=('class', 'image'))
validationfile = pd.read_table('data/validation.txt', delim_whitespace=True, names=('class', 'image'))
#Changing target variable type
trainingfile = trainingfile.replace([0, 1, 2], ['class0', 'class1', 'class2'])
testingfile = testingfile.replace([0, 1, 2], ['class0', 'class1', 'class2'])
validationfile = validationfile.replace([0, 1, 2], ['class0', 'class1', 'class2'])
#Data augmentation
datagen=ImageDataGenerator()
train_datagen = ImageDataGenerator(
#Apliquem una mica de rotació no gaire ja que generalment les fotografies estaran centrades
rotation_range=5,
zoom_range=0.1)
#Final datasets containing the images
train=train_datagen.flow_from_dataframe(dataframe=trainingfile, directory="data/", x_col="image", y_col="class", class_mode="categorical", target_size=(256,256),color_mode='rgb',batch_size=32)
test=datagen.flow_from_dataframe(dataframe=testingfile, directory="data/", x_col="image", y_col="class", class_mode="categorical", target_size=(256,256),color_mode='rgb',batch_size=32)
#No data augmentation to the validation dataset.
validation=datagen.flow_from_dataframe(dataframe=validationfile, directory="data/", x_col="image", y_col="class", class_mode="categorical", target_size=(256,256),color_mode='rgb', batch_size=32)
CNN model
from keras.models import Sequential
from keras.layers import Dense, Conv2D, Flatten, Activation, Dropout, MaxPooling2D, BatchNormalization
from keras.constraints import maxnorm
#Creació del model
model = Sequential()
#1r bloc convolució
model.add(Conv2D(32, kernel_size = (3, 3), activation='relu', input_shape=(256, 256,3)))
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(BatchNormalization())
#2n bloc convolució
model.add(Conv2D(64, kernel_size=(3,3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(BatchNormalization())
#3r bloc convolució
model.add(Conv2D(64, kernel_size=(3,3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(BatchNormalization())
#4t bloc convolució
model.add(Conv2D(96, kernel_size=(3,3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(BatchNormalization())
#5e bloc convolució
model.add(Conv2D(32, kernel_size=(3,3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(BatchNormalization())
#Dropout
model.add(Dropout(0.2))
model.add(Flatten())
model.add(Dense(128, activation='relu'))
#model.add(Dropout(0.3))
model.add(Dense(3, activation = 'softmax'))
from keras import regularizers, optimizers
from keras.optimizers import RMSprop
from keras.callbacks import EarlyStopping
# Compile model
model.compile(optimizer='adam',loss="categorical_crossentropy",metrics=["accuracy"])
# Early stopping
es = EarlyStopping(monitor='val_loss', mode='min', verbose=1,patience=10)
Training the model
h=model.fit_generator(generator=train,
validation_data=validation,
epochs=50,
callbacks=[es])
Results
It is the first time that I use fit_generator and perhaps I'm not using it properly?
As I can see from the results images, you are training just for 1 epoch. This could be because the EarlyStopping is too strict. Try adding patience=3to the EarlyStopping callback.
es = EarlyStopping(monitor='val_loss', mode='min', verbose=1, patience=3)
EDIT
Overfitting example:
Check this post to know more about how to deal with overfitting.

AttributeError: 'ImageDataGenerator' object has no attribute 'shape'

I am new in coding. I am trying to get the score but unfortunately i am getting errors. I was using first import.keras until it gave me when i wanted to evaluate the score and predict.The training model happened well, i have gotten no problem there.It is after that, when i was aboout to get the score of my model that i got as error ImageDataGnerator: Object has no 'ndim'.
Then i looked for help and someone told me to use import.tensorflow.keras instead and i did it....
After training the model again,reaching that part in order to get the score and predict after i've gotten another error saying : ImageDataGenerator object has no attribute shapes and a warning saying :
WARNING : tensorflow : Falling back from v2 loop because of error : Failed to find data* **adapter that can handle input : < class 'tensorflow.python.keras.preprocessing.image.ImageDataGenerator'> , < class 'NoneType'
This is some of the code below.
import numpy as np
import tensorflow as tf
import cv2
import sys
import os
import matplotlib.pyplot as plt
from tensorflow import keras
from tensorflow.keras.preprocessing.image import ImageDataGenerator
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Dropout, Activation, Flatten
from tensorflow.keras.layers import Conv2D, MaxPooling2D
from tensorflow.keras.optimizers import Adam
image_width, image_height = 150,150
Epochs =10
batch_size=45
Steps_per_epoch=190
Validation_data=20
num_classes = len(map_characters)
model = Sequential()
model.add(Conv2D(32, (3, 3), padding='same', input_shape= (image_height,image_width ,3)))
model.add(Activation('relu'))
model.add(Conv2D(32, (3, 3)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.2))
model.add(Conv2D(64, (3, 3), padding='same'))
model.add(Activation('relu'))
model.add(Conv2D(64, (3, 3)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.2))
model.add(Conv2D(256, (3, 3), padding='same'))
model.add(Activation('relu'))
model.add(Conv2D(256, (3, 3)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.2))
model.add(Flatten())
model.add(Dense(1024))
model.add(Activation('relu'))
model.add(Dropout(0.5))
model.add(Dense(num_classes, activation='softmax'))
opt = Adam(lr=0.01, decay=1e-6, )
model.summary()
model.compile(loss='categorical_crossentropy',
optimizer='Adam',
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_generator = train_datagen.flow_from_directory(
train_data_dir,
target_size = (image_height, image_width),
batch_size = batch_size,
class_mode = 'categorical')
validation_generator = test_datagen.flow_from_directory(
validation_data_dir,
target_size = (image_height, image_width),
batch_size = batch_size,
class_mode = 'categorical')
result=model.fit_generator(training_generator,
steps_per_epoch=Steps_per_epoch,
epochs = Epochs,
validation_data = validation_generator,
validation_steps=Validation_data)
score = model.evaluate(test_datagen,
validation_generator,
batch_size=batch_size)
To evaluate on a generator, you need to use evaluate_generator, not evaluate.

Accuracy Equals 0 CNN Python Keras

I'm working on a binary classification problem. I was getting 69% accuracy at first, but kept running out of memory so I shrunk certain parameters, now it's coming up 0. Any idea whats going on?
model = Sequential()
from keras.layers import Dropout
model.add(Conv2D(96, kernel_size=11, padding="same", input_shape=(300, 300, 1), activation = 'relu'))
model.add(MaxPooling2D(pool_size=(3, 3), strides=(2, 2)))
model.add(Conv2D(128, kernel_size=3, padding="same", activation = 'relu'))
model.add(MaxPooling2D(pool_size=(2, 2), strides=(2, 2)))
model.add(Conv2D(128, kernel_size=3, padding="same", activation = 'relu'))
model.add(MaxPooling2D(pool_size=(2, 2), strides=(2, 2)))
from keras.layers.core import Activation
model.add(Flatten())
# model.add(Dense(units=1000, activation='relu' ))
model.add(Dense(units= 300, activation='relu'))
model.add(Dropout(0.2))
model.add(Dense(1))
model.add(Activation("softmax"))
model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])
from keras.preprocessing.image import ImageDataGenerator
datagen = ImageDataGenerator(
featurewise_center=True,
rotation_range=90,
fill_mode='nearest',
validation_split = 0.2
)
datagen.fit(train)
train_generator = datagen.flow(train, train_labels, batch_size=8)
# # fits the model on batches with real-time data augmentation:
history = model.fit_generator(generator=train_generator,
use_multiprocessing=True,
steps_per_epoch = len(train_generator) / 8,
epochs = 5,
workers=20)
Softmax should only be used if you have a multiclass classification problem. You have a single output from your Dense layer, so you should use sigmoid.

Getting 'only size-1 arrays can be converted to python scalars' error in keras model

I'm using this code:
import keras
from keras.models import Sequential
from keras.layers import Dense, Activation, Dropout, Flatten,\
Conv2D, MaxPooling2D
from keras.layers.normalization import BatchNormalization
import numpy as np
np.random.seed(1000)
# (3) Create a sequential model
model = Sequential()
# 1st Convolutional Layer
model.add(Conv2D(kernel_size=96, filters=(11, 11), input_shape=(64,64,3), activation='relu', strides=(4,4), padding='valid'))
# Pooling
model.add(MaxPooling2D(pool_size=(2,2), strides=(2,2), padding='valid'))
# Batch Normalisation before passing it to the next layer
model.add(BatchNormalization())
# 2nd Convolutional Layer
model.add(Conv2D(256, 11, 11, activation='relu', strides=(1,1), padding='valid'))
# Pooling
model.add(MaxPooling2D(pool_size=(2,2), strides=(2,2), padding='valid'))
# Batch Normalisation
model.add(BatchNormalization())
# 3rd Convolutional Layer
model.add(Conv2D(384, 3, 3, activation='relu', strides=(1,1), padding='valid'))
# Batch Normalisation
model.add(BatchNormalization())
# 4th Convolutional Layer
model.add(Conv2D(384, 3, 3, activation='relu', strides=(1,1), padding='valid'))
# Batch Normalisation
model.add(BatchNormalization())
# 5th Convolutional Layer
model.add(Conv2D(256, 3, 3, activation='relu', strides=(1,1), padding='valid'))
# Pooling
model.add(MaxPooling2D(pool_size=(2,2), strides=(2,2), padding='valid'))
# Batch Normalisation
model.add(BatchNormalization())
# Passing it to a dense layer
model.add(Flatten())
# 1st Dense Layer
model.add(Dense(4096, input_shape=(224*224*3,)))
model.add(Activation('relu'))
# Add Dropout to prevent overfitting
model.add(Dropout(0.4))
# Batch Normalisation
model.add(BatchNormalization())
# 2nd Dense Layer
model.add(Dense(4096))
model.add(Activation('relu'))
# Add Dropout
model.add(Dropout(0.4))
# Batch Normalisation
model.add(BatchNormalization())
# 3rd Dense Layer
model.add(Dense(1000))
model.add(Activation('relu'))
# Add Dropout
model.add(Dropout(0.4))
# Batch Normalisation
model.add(BatchNormalization())
output_node=109
# Output Layer
model.add(Dense(output_node.shape, activation='softmax'))
model.summary()
# (4) Compile
model.compile(loss='categorical_crossentropy', optimizer='adam',\
metrics=['accuracy'])
#Fitting dataset
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 = 'categorical')
test_set = test_datagen.flow_from_directory('dataset/test_set',
target_size = (64, 64),
batch_size = 32,
class_mode = 'categorical')
#steps_per_epoch = number of images in training set / batch size (which is 55839/32)
#validation_steps = number of images in test set / batch size (which is 18739/32)
classifier.fit_generator(
training_set,
steps_per_epoch=55839/32,
epochs=5,
validation_data=test_set,
validation_steps=18739/32)
And I'm getting this error:
TypeError: only size-1 arrays can be converted to Python scalars
I've tried looking up this solution: Keras Model giving TypeError: only size-1 arrays can be converted to Python scalars
But, as you can see I have used the .shape method in my output layer and still it doesn't work. I don't see where an array is being created which needs to be a size 1 array in the line
model.add(Conv2D(kernel_size=96, filters=(11, 11), input_shape=(64,64,3), activation='relu', strides=(4,4), padding='valid'))
because that's where the error is being triggered.
EDIT: I tried to set an integral value for 'filters' as suggested by #TavoGLC as:
model.add(Conv2D(filters=11, kernel_size=96, input_shape=(224,224,3), activation='relu', strides=(4,4), padding='valid', data_format='channels_last'))
and I added a data_format='channels_last' to overcome a negative values problem. That made this line of code run properly, but then the 2nd Convolutional layer started giving me problems.
# 2nd Convolutional Layer
model.add(Conv2D(filters=11, kernel_size=256, strides=(1,1), padding='valid', activation='relu'))
Error:
ValueError: Negative dimension size caused by subtracting 256 from 16 for 'conv2d_77/convolution' (op: 'Conv2D') with input shapes: [?,33,16,5], [256,256,33,11].
Again, I've tried the solutions given here: Negative dimension size caused by subtracting 3 from 1 for 'conv2d_2/convolution'
Nothing just seems to work.
Change these:
filter - use a single integer (number of output filters for the convolution).
kernel_size - use the smaller size as the kernel has to move in the input shape(The shape could decrease for deeper layer so you have to understand the shape of the layer input to get the size)
other convolution layers - you have to use tuple (like Conv2D(256, (11, 11))) else it will be considered as another variable, follow the previous procedure on filter and kernel_size for all Conv2D layers.
for output shape use
output_node=109
# Output Layer
model.add(Dense(output_node, activation='softmax'))

Categories

Resources