Python- Mask Detection Nerual Network using Keras [closed] - python

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 2 years ago.
Improve this question
So this is my first real try on neural networks with keras. I've been trying to make a classifier which decides wether someone is wearing a mask. Below i provided my model. I achived a training accuracy of about 87 percent and a validation accuracy of 85 percent. With own images it performs mostly well too. I created my own dataset with about 600 images for each of the two classes. However I have some questions.
Is it correct? Any suggested improvements? As I said this is my first neural network project i dont really know if i made anything wrong(which I most likely did)
How would i implemet this to predict on camera feed and not only images. Would I just get the frames from for example opencv and predict those? Any review and/or help is highly appreciated
This is my model:
from keras.layers import Dense, Input, Dropout, GlobalAveragePooling2D, Flatten, Conv2D, BatchNormalization, Activation, MaxPooling2D
from keras.models import Model, Sequential
from tensorflow.keras.callbacks import TensorBoard
from tensorflow.keras.preprocessing.image import ImageDataGenerator
from tensorflow.keras.optimizers import RMSprop
from sklearn.model_selection import train_test_split
NAME = "mask-detection"
tensorboard = TensorBoard(log_dir="logs/{}".format(NAME))
train_datagen = ImageDataGenerator(rescale=1 / 255)
test_datagen = ImageDataGenerator(rescale=1. / 255)
train_generator = train_datagen.flow_from_directory(
'data/train',
target_size=(100, 100),
batch_size=32,
class_mode='categorical',
color_mode = "grayscale"
)
label_map = (train_generator.class_indices)
validation_generator = test_datagen.flow_from_directory(
'data/test',
target_size=(100, 100),
batch_size=32,
class_mode='categorical',
color_mode = "grayscale"
)
model=Sequential()
model.add(Conv2D(100,(3,3),padding='same', input_shape=(100,100,1)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(Conv2D(100,(3,3), padding='same',))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(Flatten())
model.add(Dropout(0.5))
model.add(Dense(50,activation='relu'))
model.add(Dense(2, activation='softmax'))
model.compile(
optimizer=RMSprop(lr=0.0001),
loss="binary_crossentropy",
metrics=["accuracy"])
model.fit(train_generator, epochs=20, callbacks=[tensorboard])
model.evaluate(validation_generator)
model.save('saved_model/model')
model.summary()
print(label_map)
And with this i predict the imgs:
import numpy as np
from keras.preprocessing import image
model = tf.keras.models.load_model('saved_model/model')
predictions = ["Mask", "No Mask"]
def predict_mask(img):
x = image.load_img(img, color_mode="grayscale", target_size=(100, 100))
x = image.img_to_array(x)
x = np.expand_dims(x, axis= 0)
x = np.array(x).astype("float32")/255
x = x.reshape([1, 100, 100, 1])
classes = model.predict(x)
return predictions[np.argmax(classes)]
img = "test.png"
print(predict_mask(img))

There are a number of things you can do. If you want to use your existing model then I recommend you use the keras callbacks ReduceLROnPlateau and ModelCheckpoint. The first enables you to use an adjustable learning rate. Set it up to monitor validation loss. A typical use is shown in the code below where if the validation loss fails to reduce on an epoch the learning rate is reduced by 50% .This allows you to use a larger learning rate initially and have it reduce automatically in later epochs. The second enables you to save the model with the lowest validation loss. Typical application is shown in the code below. Documentation for these callbacks is here. After training load this model to do predictions. If you want to get better results I recommend you try transfer learning. Many models are available with documentation here. I prefer to use the MobileNet model because it has only 4 million trainable parameters versus say 140 million for VGG16 and is about as accurate in most cases. Code below shows typical use.
rlrp=tf.keras.callbacks.ReduceLROnPlateau(
monitor='val_loss', factor=0.5, patience=1, verbose=0, mode='auto',
min_delta=0.0001, cooldown=0, min_lr=0)
checkpoint_filepath = '/tmp/checkpoint'
mcp=tf.keras.callbacks.ModelCheckpoint(filepath=checkpoint_filepath,
monitor='val_loss', verbose=0, save_best_only=True,
save_weights_only=False, mode='auto', save_freq='epoch', options=None)
callbacks=[rlrp,mcp]
mobile = tf.keras.applications.mobilenet.MobileNet( include_top=False,
input_shape=(image_size,image_size,3),
pooling='max', weights='imagenet',
alpha=1, depth_multiplier=1,dropout=.5)
x=mobile.layers[-1].output
x=keras.layers.BatchNormalization(axis=-1, momentum=0.99, epsilon=0.001 )(x)
predictions=Dense (2, activation='softmax')(x)
model = Model(inputs=mobile.input, outputs=predictions)
for layer in model.layers:
layer.trainable=True
model.compile(Adamax(lr=.05), loss='categorical_crossentropy', metrics=['accuracy'])
data=model.fit(x=train_generator, epochs=20, verbose=1,
callbacks=callbacks, validation_data=validation_generator, shuffle=True)

Related

What Can I do to improve the 96% (f-score) in my CNN Keras?

I'm running a project with roughly 22000 images (11000 each class) with ResNet50 fine tuning. This is my code:
base_model = ResNet50(weights='imagenet', include_top=True, input_shape=(224,224,3))
head_model = base_model.get_layer("conv5_block1_1_conv").output
head_model = Dropout(0.75)(head_model)
head_model = Flatten()(head_model)
head_model = Dense(1, activation="sigmoid")(head_model)
model = Model(inputs=base_model.input, outputs=head_model)
model.summary()
for layer in base_model.layers:
layer.trainable = False
adam = Adam(lr=0.001)
model.compile(optimizer= adam, loss='binary_crossentropy', metrics=['accuracy'])
train_datagen = ImageDataGenerator()
train_generator = train_datagen.flow_from_directory(TRAIN_DIR,
target_size=(224, 224),
batch_size=50,
class_mode='binary')
model.fit_generator(train_generator, steps_per_epoch=100)
model.save("asd.h5")
With this model I reached 96 % of f-score. What method I can apply to improve its accuracy? I already tried include colormap as preprocessing and Include Dense layers.
There're a lot of techniques:
You can change the structure of model. Add or remove some layers (and not only Dense layers). Or use other pretrained model.
Change the optimizer. For example, despite the Adam another popular optimizer is RMSprop. You can also try to tune optimizer's hyperparameters.
Preprocess data. You can do zoom, shear and etc.

Bad training results when I am trying to find out defected and non-defected solar cells

I am trying to classify which are defected solar cells. I have a huge dataset of both defected plates and non-defected solar cells. As per a few suggestions from research papers I have been using the VGG 16 model for the training purpose. But even after 3 epochs, it is showing 100 % accuracy. I don't why it is coming like this. Is there any other way to solve this problem, any other Algorithm.
I am uploading some of the defected cells which I have in my dataset
]2]2]3
from keras.layers import Input, Lambda, Dense, Flatten
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 = 'Datasets/Train'
valid_path = 'Datasets/Test'
# 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('Datasets/Train/*')
# our layers - you can add more if you want
x = Flatten()(vgg.output)
# x = Dense(1000, activation='relu')(x)
prediction = Dense(len(folders), activation='softmax')(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='categorical_crossentropy',
optimizer='adam',
metrics=['accuracy']
)
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('Datasets/Train',
target_size = (224, 224),
batch_size = 32,
class_mode = 'categorical')
test_set = test_datagen.flow_from_directory('Datasets/Test',
target_size = (224, 224),
batch_size = 32,
class_mode = 'categorical')
# fit the model
r = model.fit_generator(
training_set,
validation_data=test_set,
epochs=10,
steps_per_epoch=len(training_set),
validation_steps=len(test_set)
)
# loss
plt.plot(r.history['loss'], label='train loss')
plt.plot(r.history['val_loss'], label='val loss')
plt.legend()
plt.show()
plt.savefig('LossVal_loss')
# accuracies
plt.plot(r.history['acc'], label='train acc')
plt.plot(r.history['val_acc'], label='val acc')
plt.legend()
plt.show()
plt.savefig('AccVal_acc')
import tensorflow as tf
from keras.models import load_model
model.save('defect_features_new_model.h5')
It feels like the images are too simple and do not contain any complicated data. Hence they tend to overfit the VGG16 model. VGG16 models are generally trained on much more complicated data. You can try defining your own convolutional neural network. Since you are already using keras you can create sequential model to define your own model with minimum as 2 or 3 convolutional layersPlease refer the link for keras sequential model
Your data for the network looks very simple so it is not unexpected that you achieve high accuracy. Remember the network trains in batches so for every 32 images it goes through a back propagation cycle and updates the weights accordingly. So if you have a lot of images which you say you do then you are executing a lot of iterations on the weights.
I do not see a problem here. You are not over training in the sense that your validation accuracy is 100%. Certainly you could get good results with a simpler model but why bother your results are what you would want.

Keras: Overfitting Model?

I am trying to create a binary image classification model using the malaria dataset from NIH (National Library of Medicine) which contains approximately 27,000 images of each class (infected/uninfected).
There seems to be overfitting and I have tried to play around with different batch sizes, steps per epoch/validation steps, using different hidden layers and adding callbacks etc. The graph always shows a straight line that is either dramatically increasing or decreasing, rather than increasing steadily with some decreases as it learns (which from my understanding, is how it should be). Below is an example, most turn out somewhat similar to this.
I'm new to deep learning, I have read a lot about overfitting and trying to find a solution. But I think there must be something I'm doing wrong and/or misunderstanding. If someone is able to spot something that doesn't look right and is able to point me in the right direction, it would be greatly appreciated!
from keras.layers import MaxPooling2D, Conv2D, Flatten, Dense, Dropout
from keras_preprocessing.image import ImageDataGenerator
from sklearn.model_selection import train_test_split
from keras.models import Sequential
import matplotlib.pyplot as plt
import constants as c
import numpy as np
import keras
# Clear session and instantiate model
keras.backend.clear_session()
model = Sequential()
# Load images & labels
cells = np.load(c.cells_path)
labels = np.load(c.labels_path)
# Shuffle the entire dataset
n = np.arange(cells.shape[0])
np.random.shuffle(n)
# Update numpy files with shuffled data
cells = cells[n]
labels = labels[n]
# Split the dataset into train/validation/test
train_x, test_x, train_y, test_y = train_test_split(cells, labels, test_size=1 - c.train_ratio, shuffle=False)
val_x, test_x, val_y, test_y = train_test_split(test_x, test_y, test_size=c.test_ratio / (c.test_ratio + c.val_ratio),
shuffle=False)
# The amount of images in each set
print('Training data shape: ', train_x.shape)
print('Validation data shape: ', val_x.shape)
print('Testing data shape: ', test_x.shape)
# Neural network
model.add(Conv2D(32, (3, 3), input_shape=c.input_shape, activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Conv2D(32, (3, 3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Conv2D(32, (3, 3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Flatten())
model.add(Dense(units=64, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(units=1, activation='sigmoid'))
# Compile the model
model.compile(optimizer='rmsprop',
loss='binary_crossentropy',
metrics=['accuracy'])
# Data augmentation
train_datagen = ImageDataGenerator(rescale=1. / 255,
rotation_range=20,
width_shift_range=0.05,
height_shift_range=0.05,
shear_range=0.05,
zoom_range=0.05,
horizontal_flip=True,
fill_mode='nearest')
validation_datagen = ImageDataGenerator(rescale=1. / 255)
testing_datagen = ImageDataGenerator(rescale=1. / 255)
training_dataset = train_datagen.flow(train_x, train_y, batch_size=32)
validation_dataset = validation_datagen.flow(val_x, val_y, batch_size=32)
testing_dataset = validation_datagen.flow(val_x, val_y, batch_size=32)
# Add callbacks to prevent overfitting
es = EarlyStopping(monitor='accuracy',
min_delta=0,
patience=2,
verbose=0,
mode='max')
rlrop = ReduceLROnPlateau(monitor='val_loss',
factor=0.2,
patience=0.5,
min_lr=0.001)
checkpoint = ModelCheckpoint("Model.h5")
# Perform backpropagation and update weights in model
history = model.fit_generator(training_dataset,
epochs=50,
validation_data=validation_dataset,
callbacks=[es, checkpoint, rlrop])
# Save model & weights
model.save_weights("Model_weights.h5")
model.save("Model.h5")
# Plot accuracy graph
plt.plot(history.history['accuracy'])
plt.plot(history.history['val_accuracy'])
plt.title('model accuracy')
plt.ylabel('accuracy')
plt.xlabel('epoch')
plt.legend(['train', 'val'], loc='upper left')
plt.show()
Doesn't seem to be a case of overfitting. Without looking much at it, would do the following:
leave the filters at 32 in the fist layer and gradually double on every following convolutional layer.
Since the variations in the images aren't that significant lower the Dropout rate.
Oddly enough, this is something I built when I was first trying Tensorflow 2.0, you can check it here.

Face recognition with keras

Below is my face recognition model. I get several issues while training my training data on it. My dataset contains images of me. When I train it, validation accuracy is 100%. And also its prediction is bad. What can I do to solve this problem?
from keras import layers
from keras import models
model = models.Sequential()
model.add(layers.Conv2D(32,(3,3),activation='relu',
input_shape = (150,150,3)))
model.add(layers.MaxPooling2D((2,2)))
model.add(layers.Dropout(0.5))
model.add(layers.Conv2D(64,(3,3),activation='relu'))
model.add(layers.MaxPooling2D((2,2)))
model.add(layers.Conv2D(128,(3,3),activation='relu'))
model.add(layers.MaxPooling2D((2,2)))
model.add(layers.Dropout(0.5))
model.add(layers.Conv2D(128,(3,3),activation='relu'))
model.add(layers.MaxPooling2D((2,2)))
model.add(layers.Flatten())
model.add(layers.Dense(512,activation='relu'))
model.add(layers.Dense(1,activation='sigmoid'))
print(model.summary())
from keras import optimizers
model.compile(loss='binary_crossentropy',
optimizer=optimizers.RMSprop(lr=1e-4),
metrics=['acc'])
from keras.preprocessing.image import ImageDataGenerator
train_datagen = ImageDataGenerator(rescale=1./255)
val_datagen = ImageDataGenerator(rescale=1./255)
train_generator = train_datagen.flow_from_directory(
train_dir,
target_size = (150,150),
batch_size=20)
validation_generator = val_datagen.flow_from_directory(
validation_dir,
target_size = (150,150),
batch_size=20)
history = model.fit_generator(
train_generator,
steps_per_epoch = 100,
epochs = 3,
validation_data = validation_generator,
validation_steps = 50)
model.save('/home/monojit/Desktop/me3.h5')
How large is the dataset that is being used? A small dataset might be the problem, or your model architecture if the model is not generalizing well. Also, you might look at image augmentation using the ImageDataGenerator, see the blog post that i'll link to in a bit.
If the purpose of this project is to get as high accuracy as possible, without explicitly learning how CNN and their different layers work, then i would suggest the following. As you are working with images, you might not want to re-invent the wheel. Go on and take a pre-trained convolutional neural network, then train that on your imaged. This will yield you way higher accuracy with less epochs, than an untrained network. A great blog post can be found here Keras Cats vs dogs.
Now this tutorial is cats vs dogs. But you can use (almost, depending on your input images) the exact same code for your problem.

Criteria for nb_epoch, samples_per_epoch, and nb_val_samples in keras fit_generator?

I have created a simple cat and dog image classification (convolution neural network). Having training data of 7,000 each class and validation data of 5,500 each class.
My problem is my system is not completing all epoch. I would really appreciate if someone could explain the proportion or criteria of selecting nb_epoch, samples_per_epoch and nb_val_samples values to get maximum out of given amount of training and validation data.
Following is my code:
from keras.preprocessing.image import ImageDataGenerator
from keras.models import Sequential
from keras.layers import Convolution2D, MaxPooling2D
from keras.layers import Activation, Dropout, Flatten, Dense
from keras.callbacks import EarlyStopping
import numpy as np
from keras.preprocessing import image
from keras.utils.np_utils import probas_to_classes
model=Sequential()
model.add(Convolution2D(32, 5,5, input_shape=(28,28,3)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(Convolution2D(32,3,3))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(Flatten())
model.add(Dense(128))
model.add(Activation('relu'))
model.add(Dropout(0.5))
model.add(Dense(2))
model.add(Activation('softmax'))
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(
r'F:\data\train',
target_size=(28,28),
classes=['dog','cat'],
batch_size=10,
class_mode='categorical',
shuffle=True)
validation_generator=test_datagen.flow_from_directory(
r'F:\data\validation',
target_size=(28, 28),
classes=['dog','cat'],
batch_size=10,
class_mode='categorical',
shuffle=True)
model.compile(loss='categorical_crossentropy', optimizer='rmsprop', metrics=['accuracy'])
early_stopping=EarlyStopping(monitor='val_loss', patience=2)
model.fit_generator(train_generator,verbose=2, samples_per_epoch=650, nb_epoch=100, validation_data=validation_generator, callbacks=[early_stopping],nb_val_samples=550)
json_string=model.to_json()
open(r'F:\data\mnistcnn_arc.json','w').write(json_string)
model.save_weights(r'F:\data\mnistcnn_weights.h5')
score=model.evaluate_generator(validation_generator, 1000)
print('Test score:', score[0])
print('Test accuracy:', score[1])
img_path = 'F:/abc.jpg'
img = image.load_img(img_path, target_size=(28, 28))
x = image.img_to_array(img)
x = np.expand_dims(x, axis=0)
y_proba = model.predict(x)
y_classes = probas_to_classes(y_proba)
print(train_generator.class_indices)
print(y_classes)
samples_per_epoch is usually setted as:
samples_per_epoch=train_generator.nb_samples
This way you are ensuring that every epoch you are seeing a number of samples equal to the size of your training set. This means that you are seeing all of your training samples at every epoch.
nb_epoch is pretty much up to you. It determines how many times you iterate over a number defined by samples_per_epoch.
To give you an example, in your code right now your model is 'seeing' (nb_epoch * samples_per_epoch) images, wich in this case are 65000 images.
nb_val_samples determines over how many validation samples your model is evaluated after finishing every epoch. It is up to you aswell. The usual thing is to set:
nb_val_samples=validation_generator.nb_samples
In order to evaluate your model on the full validation set.
batch_size determines how many images are feeded at the same time to your gpu (or cpu). Rule of dumb is to set the largest batch_size that your gpu's memmory allows. Ideal batch_size is active area of research nowdays, but usually a bigger batch_size will work better.

Categories

Resources