keras face recognition accuracy not going above 50% - python

I'm pretty new to deep learning and i'm trying to make a face recognizer for anime faces. This is my current code
CNN
model = Sequential()
model.add(Convolution2D(32, 3, 3, padding='same', input_shape=input_shape))
model.add(Activation('relu'))
model.add(Convolution2D(32, 3, 3, padding='same'))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2), padding='same'))
model.add(Dropout(0.25))
model.add(Convolution2D(64, 3, 3, padding='same'))
model.add(Activation('relu'))
model.add(Convolution2D(64, 3, 3, padding='same'))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2), padding='same'))
model.add(Dropout(0.25))
model.add(Flatten())
model.add(Dense(512))
model.add(Activation('relu'))
model.add(Dropout(0.5))
model.add(Dense(nb_classes, activation='sigmoid'))
return model
Training CNN
def run():
(X_train, y_train), (X_test, y_test) = datasets.load_data(img_rows=32, img_cols=32)
Y_train = np_utils.to_categorical(y_train, nb_classes)
Y_test = np_utils.to_categorical(y_test, nb_classes)
model = CNN(input_shape=X_train.shape[1:], nb_classes=nb_classes)
csv_logger = CSVLogger('../log/cnn.log')
model.compile(loss='categorical_crossentropy', optimizer = 'rmsprop', metrics=['accuracy'])
X_test = preprocess_input(X_test)
checkpointer = ModelCheckpoint(filepath="../resources/weights.hdf5", monitor="val_accuracy", verbose=1, save_best_only=True)
datagen = ImageDataGenerator(
featurewise_center=False,
samplewise_center=False,
featurewise_std_normalization=False,
samplewise_std_normalization=False,
zca_whitening=False,
rotation_range=0,
width_shift_range=0.1,
height_shift_range=0.1,
horizontal_flip=True,
vertical_flip=False ,
preprocessing_function=preprocess_input
)
datagen.fit(X_train)
history = model.fit(
datagen.flow(X_train, Y_train, batch_size=batch_size),
steps_per_epoch= round(X_train.shape[0] / batch_size),
epochs=nb_epoch,
validation_data=(X_test, Y_test),
callbacks=[csv_logger, checkpointer], batch_size=batch_size
)
With this I don't go above 50% accuracy sometimes not even 10%
When i change the CNN to this, the accuracy goes to 65% and doesn't increase further
model = Sequential()
model.add(Convolution2D(32, 3, 3, padding='same', input_shape=input_shape))
model.add(MaxPooling2D(pool_size=(2, 2), padding='same'))
model.add(Dropout(0.25))
model.add(Flatten())
model.add(Dense(512))
model.add(Activation('relu'))
model.add(Dropout(0.5))
model.add(Dense(nb_classes, activation='sigmoid')
return model
How would i improve this to get atleast 90% accuracy
More Info over the Model
nb_epoch = 200
batch size = 10
nb_classes = 83
The dataset in total has around 3000 files.

Related

My trained model return the same predict for all input images

I'm very new to this. I just trained a model following instruction from kaggle and another website. The trained model works fine with train images but whenever i try to input a new image to predict, the result is always the same.
The accuracy is 0.9975000023841858
`
X_train = np.array(X_train)
X_test = np.array(X_test)
X_train = np.expand_dims(X_train, axis=3)
X_test = np.expand_dims(X_test, axis=3)
Here is the model
weight_decay = 1e-4
num_classes = 12
model = Sequential()
model.add(Conv2D(64, (4,4), padding='same', kernel_regularizer=regularizers.l2(weight_decay), input_shape=(128,128,1)))
model.add(Activation('elu'))
model.add(BatchNormalization())
model.add(Conv2D(64, (4,4), padding='same', kernel_regularizer=regularizers.l2(weight_decay)))
model.add(Activation('elu'))
model.add(BatchNormalization())
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(Dropout(0.2))
model.add(Conv2D(128, (4,4), padding='same', kernel_regularizer=regularizers.l2(weight_decay)))
model.add(Activation('elu'))
model.add(BatchNormalization())
model.add(Conv2D(128, (4,4), padding='same', kernel_regularizer=regularizers.l2(weight_decay)))
model.add(Activation('elu'))
model.add(BatchNormalization())
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(Dropout(0.3))
model.add(Conv2D(128, (4,4), padding='same', kernel_regularizer=regularizers.l2(weight_decay)))
model.add(Activation('elu'))
model.add(BatchNormalization())
model.add(Conv2D(128, (4,4), padding='same', kernel_regularizer=regularizers.l2(weight_decay)))
model.add(Activation('elu'))
model.add(BatchNormalization())
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(Dropout(0.4))
model.add(Flatten())
model.add(Dense(128, activation="linear"))
model.add(Activation('elu'))
model.add(Dense(num_classes, activation='softmax'))
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
model.fit(X_train, y_train,
epochs=5,
validation_data=(X_test,y_test),
verbose = 1,
initial_epoch=0)
`
When i tried to test the train image
`
predicted_classes = model.predict(X_train[:,:,:,:])
predicted_classes = np.argmax(np.round(predicted_classes), axis=1)
k = X_train.shape[0] #18000
r = np.random.randint(k) #random in 18000
print("Prediction:", predicted_classes[4])
Prediction: 8`
My input image
`
imgTest = tf.keras.utils.load_img('/content/drive/My Drive/Colab Notebooks/finger.jpg')
imgTest = np.array(imgTest)
imgTest = cv2.cvtColor(imgTest, cv2.COLOR_BGR2GRAY)
imgTest = cv2.resize(imgTest, (128, 128))
imgTest = np.expand_dims(imgTest, axis=0)
# imgTest = imgTest.reshape((1, 128, 128, 1, 1, 1))
# imgTest = imgTest/255
print(imgTest.shape)
predicted_classes_test = model.predict(imgTest)
predicted_classes_test = np.argmax(np.round(predicted_classes_test), axis=1)
print("Prediction:", predicted_classes_test)
Prediction: [7]`
I tried changing the shape of the input image so that it's the same as the train images but doesn't work
I looked for people having the same mistake to see if i can find any solutions but nothing works
Can somebody tell me what's wrong with the model? Why is it return the same value for all the images that i input?

My Input shape is correct but I stil l get the following err.: Input 0 of layer sequential is incompatible with the layer: : expected min_ndim=4,

This is my model:
def make_model():
model = Sequential()
model.add(Conv2D(kernel_size=(3, 3), filters=16, input_shape=(32, 32,1), padding='same'))
model.add(LeakyReLU(0.1))
model.add(Conv2D(kernel_size=(3, 3), filters=32, padding='same'))
model.add(LeakyReLU(0.1))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))
model.add(Conv2D(kernel_size=(3, 3), filters=32, padding='same'))
model.add(LeakyReLU(0.1))
model.add(Conv2D(kernel_size=(3, 3), filters=64, padding='same'))
model.add(LeakyReLU(0.1))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))
model.add(Flatten())
model.add(Dense(256))
model.add(LeakyReLU(0.1))
model.add(Dropout(0.5))
model.add(Dense(10))
model.add(Activation('softmax'))
return model
Compile part:
INIT_LR = 5e-3 # initial learning rate
BATCH_SIZE = 32
EPOCHS = 10
from tensorflow.keras import backend as K
K.clear_session()
model = make_model()
model.compile(
loss='categorical_crossentropy', # we train 10-way classification
optimizer=tf.keras.optimizers.Adamax(lr=INIT_LR), # for SGD
metrics=['accuracy'] # report accuracy during training
)
def lr_scheduler(epoch):
return INIT_LR * 0.9 ** epoch
# callback for printing of actual learning rate used by optimizer
class LrHistory(keras.callbacks.Callback):
def on_epoch_begin(self, epoch, logs={}):
print("Learning rate:", K.get_value(model.optimizer.lr))
Fitting:
model.fit(
X_train.reshape(-1, 32, 32, 1), y_train, # prepared data
batch_size=BATCH_SIZE,
epochs=EPOCHS,
callbacks=[keras.callbacks.LearningRateScheduler(lr_scheduler),
LrHistory(),
tfa.callbacks.TQDMProgressBar() ],
validation_data=(X_test, y_test),
shuffle=True,
verbose=0,
initial_epoch=None or 0
)
My Data_trainX shape:
My Data_trainy shape
My input shape is compatible with models Conv2D layer's input shape.
I've looked at other questions about this applied those solutions, but it didn't work.
It seems everything correct to me. Where am I doing wrong?
While you are reshaping the training data X_train to fit the model specifications, you are not doing this with the validation data X_test.
Reshape X_test as well and it should work fine:
model.fit(
X_train.reshape(-1, 32, 32, 1), y_train,
...
validation_data=(X_test.reshape(-1, 32, 32, 1), y_test), # <-- apply changes here
...
)

ValueError: logits and labels must have the same shape ((None, 6, 8, 1) vs (None, 1))

I am trying to get my hands dirty with neural networks in practice, for such task i am trying to classify some images, where i'll have two classes basically. So, i took a CNN as an example using keras and tensorflow from tutorial on youtube.
I tried changing my output layer activation to sigmoid and when did it, i started getting the error:
ValueError: logits and labels must have the same shape ((None, 6, 8, 1) vs (None, 1))
Given specifically at the following line:
validation_steps = nb_validation_Samples // batch_size)
My neural network code:
Libraries
from keras.preprocessing.image import ImageDataGenerator
from keras.models import Sequential
from keras.layers import Conv2D, MaxPooling2D
from keras.layers import Activation, Dropout, Flatten, Dense
from keras import backend as K
import numpy as np
from keras.preprocessing import image
Setup
img_width, img_height = 128, 160
train_data_dir = '/content/drive/My Drive/First-Group/Eyes/'
validation_data_dir = '/content/drive/My Drive/First-Validation-Group/'
nb_train_samples = 1300
nb_validation_Samples = 1300
epochs = 100
batch_size = 16
if K.image_data_format() == 'channels_first':
input_shape = (3, img_width, img_height)
else:
input_shape = (img_width, img_height, 3)
train_datagen = ImageDataGenerator(
zoom_range=0.2,
)
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,
class_mode='binary')
validation_generator = test_datagen.flow_from_directory(
validation_data_dir,
target_size=(img_width, img_height),
batch_size=batch_size,
class_mode="binary")
model = Sequential()
model.add(Conv2D(32, (3, 3), input_shape=input_shape))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Conv2D(32, (3, 3)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Conv2D(32, (3, 3)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Conv2D(64, (3, 3)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))
model.add(Dense(64))
model.add(Dropout(0.5))
model.add(Dense(1))
model.add(Activation('sigmoid'))
model.summary()
model.compile(loss='binary_crossentropy',
optimizer='rmsprop',
metrics=['accuracy'])
model.fit_generator(
train_generator,
steps_per_epoch=nb_train_samples // batch_size,
epochs=epochs,
validation_data = validation_generator,
error line -> **validation_steps = nb_validation_Samples // batch_size)**
model.save_weights('weights.npy')
the input of your network is 4d (batch_dim, height, width, channel), while your target is 2d (batch_dim, 1). you need something in your network to pass from 4d to 2d like flatten or global pooling. for example, you can add one of them after your last max-pooling layer.
model = Sequential()
model.add(Conv2D(32, (3, 3), input_shape=input_shape))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Conv2D(32, (3, 3)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Conv2D(32, (3, 3)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Conv2D(64, (3, 3)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Flatten()) #<========================
model.add(Dense(64))
model.add(Dropout(0.5))
model.add(Dense(1))
model.add(Activation('sigmoid'))
the usage of binary_crossentropy as a loss with sigmoid and class_mode='binary' in generator seems ok if u are dealing with a binary classification problem

Dimension mismatch in keras

I was trying to run a 10 fold cross validation on my dataset.I had reshaped my data before training as follows
data = data.reshape(500,1,1028,1)
data_y = np_utils.to_categorical(data_y, 3)
After this i described my model
for train,test in kf.split(data):
fold+=1
print("Fold #{}".format(fold))
x_train = data[train]
y_train = data_y[train]
x_test = data[test]
y_test = data_y[test]
print(x_train.shape)
model.add(Conv2D(32, (1, 3),input_shape=(1,1028,1)))
model.add(BatchNormalization(axis=-1))
model.add(Activation('relu'))
#model.add(MaxPooling2D(pool_size=(1,2)))
model.add(Conv2D(34, (1, 4)))
model.add(BatchNormalization(axis=-1))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(1,2)))
model.add(Conv2D(64,(1, 3)))
model.add(BatchNormalization(axis=-1))
model.add(Activation('relu'))
#model.add(MaxPooling2D(pool_size=(1,2)))
model.add(Conv2D(64, (1, 4)))
model.add(BatchNormalization(axis=-1))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(1,2)))
model.add(Flatten())
#fully connected for new model
model.add(Dense(550))
model.add(BatchNormalization())
model.add(Activation('relu'))
model.add(Dropout(0.25))
model.add(Dense(250))
model.add(BatchNormalization())
model.add(Activation('relu'))
model.add(Dropout(0.25))
model.add(Dense(100))
model.add(BatchNormalization())
model.add(Activation('relu'))
model.add(Dropout(0.25))
model.add(Dense(25))
model.add(BatchNormalization())
model.add(Activation('relu'))
model.add(Dropout(0.25))
model.add(Dense(3))
model.add(Activation('softmax'))
model.compile(loss='categorical_crossentropy', optimizer=Adam(), metrics=['accuracy'])
model.fit(x_train.reshape(450,1,1028,1), y_train,
batch_size=5,
epochs=1,
verbose=1,
validation_data=(x_test, y_test))
pred = model.predict(x_test)
oos_y.append(y_test)
pred = np.argmax(pred, axis=1) # raw probabilities to chosen class (highest probability)
oos_pred.append(pred)
# Measure this fold's accuracy
y_compare = np.argmax(y_test, axis=1) # For accuracy calculation
score = metrics.accuracy_score(y_compare, pred)
print("Fold score (accuracy): {}".format(score))
The problem is that when I run my code the code runs properly for fold 1 but for fold 2 it gives me the following error
ValueError: Input 0 is incompatible with layer conv2d_5: expected ndim=4, found ndim=2
When I checked the dimensions of x_train it was (450, 1, 1028, 1)
I am not sure what the error is.
You are adding model layers inside loop over and over. The error was produced when you try to add convolutional layer(for second iteration of loop) after softmax activation layer(the last layer for first iteration of the loop). After careful inspection I've come to the following solution to your question.
First split the dataset into train and test
for train_index, test_index in kf.split(data):
X_train, X_test = data[train_index], data[test_index]
y_train, y_test = data_y[train_index], data_y[test_index]
then add layers to model outside of the loop.
model.add(Conv2D(32, (1, 3),input_shape=(1,1028,1)))
model.add(BatchNormalization(axis=-1))
model.add(Activation('relu'))
#model.add(MaxPooling2D(pool_size=(1,2)))
model.add(Conv2D(34, (1, 4)))
model.add(BatchNormalization(axis=-1))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(1,2)))
# ... The reset of the code

Keras ValueError when checking target

I'm trying to build a model in keras. I followed a tutorial almost to the letter, but I'm getting an error that says:
ValueError: Error when checking target: expected activation_5 to have shape (None, 1) but got array with shape (16, 13)
The code I have is the following:
model = Sequential()
model.add(Conv2D(32, (3, 3), input_shape=input_shape))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Conv2D(32, (3, 3)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Conv2D(64, (3, 3)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Flatten())
model.add(Dense(64))
model.add(Activation('relu'))
model.add(Dropout(0.5))
model.add(Dense(1))
model.add(Activation('sigmoid'))
model.compile(loss='binary_crossentropy',
optimizer='rmsprop',
metrics=['accuracy'])
batch_size = 16
epochs = 50
number_training_data = 999
number_validation_data = 100
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(
'data/train', # this is the target directory
target_size=(200, 200),
batch_size=batch_size,
class_mode='categorical')
validation_generator = test_datagen.flow_from_directory(
'data/validation',
target_size=(200, 200),
batch_size=batch_size,
class_mode='categorical')
model.fit_generator(
train_generator,
steps_per_epoch=number_training_data // batch_size,
epochs=epochs,
validation_data=validation_generator,
validation_steps=number_validation_data // batch_size)
The dataset I have has 13 classes, so the shape of the array in the error message corresponds to the batch size and the number of classes. Any idea why I'm getting this error?
Your model is configured to perform binary classification, not multi-class classification with 13 classes. To do that you should change:
The number of units in the last dense to 13, the number of classes.
The activation at the output to softmax.
The loss to categorical cross-entropy (categorical_crossentropy).

Categories