Formation supplémentaire d'un réseau de neurones pour rechercher des visages dans les masques médicaux

La première chose dont nous avons besoin est un ensemble de données (échantillon de photos) de personnes avec et sans masques pour une formation supplémentaire du réseau neuronal MobileNetV2, qui est dans le domaine public. J'avais un ensemble de données de 981 photographies de personnes masquées et le même nombre sans, les mêmes personnes.





Je voudrais noter un point important que le réseau de neurones MobileNetV2 peut être utilisé pour presque toutes les classifications, par exemple, il était possible de le recycler pour déterminer le sexe, ou d'essayer de déterminer automatiquement une personne portant des lunettes ou non, c'est pourquoi nous geler toutes les couches de base du modèle, et dans la couche supérieure, nous servons ce qui doit être classé. Mais nous nous concentrerons sur la recherche d'un masque médical, comme le plus pertinent à l'heure actuelle.





Alors, plaçons notre jeu de données de 1962 photos dans deux répertoires dans le dossier du jeu de données avec des masques dans "WithMask" et sans masque dans "Withoutmask", respectivement. Chacun contient 981 photographies. Une autre note importante est que nous le recyclons sur les visages, et pas seulement que la personne sur l'image porte un masque ou non, même si cela aurait pu être le cas.





Ensuite, nous importons les bibliothèques requises:





from tensorflow.keras.preprocessing.image import ImageDataGenerator
from tensorflow.keras.applications import MobileNetV2
from tensorflow.keras.layers import AveragePooling2D
from tensorflow.keras.layers import Dropout
from tensorflow.keras.layers import Flatten
from tensorflow.keras.layers import Dense
from tensorflow.keras.layers import Input
from tensorflow.keras.models import Model
from tensorflow.keras.optimizers import Adam
from tensorflow.keras.applications.mobilenet_v2 import preprocess_input
from tensorflow.keras.preprocessing.image import img_to_array
from tensorflow.keras.preprocessing.image import load_img
from tensorflow.keras.utils import to_categorical
from sklearn.preprocessing import LabelBinarizer
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report
from imutils import paths
import matplotlib.pyplot as plt
import numpy as np
import argparse
import os
      
      



# Spécifier les hyperparamètres initiaux





— , ,





INIT_LR = 0,004





— ,  





EPOCHS = 20





— , .





BS = 32





, , , .





imagePaths = list(paths.list_images (r'C:\dataset'))  #          
data , labels = [] , []
for imagePath in imagePaths:
	#     (   )
	label = imagePath.split(os.path.sep)[-2]
	#    224224   
	image = load_img(imagePath, target_size = (224, 224))
	image = img_to_array(image)
	image = preprocess_input(image)
	#     
	data.append(image)
	labels.append(label)
#   NumPy 
data = np.array(data, dtype="float32")
labels = np.array(labels)
#     , .. 0   1  
lb = LabelBinarizer()
labels = lb.fit_transform(labels)
labels = to_categorical(labels)
#        80%  20%;
(trainX, testX, trainY, testY) = train_test_split(data, labels,  test_size = 0.20, stratify = labels, random_state = 42)
#     
aug = ImageDataGenerator(rotation_range = 20, zoom_range = 0.15,
	width_shift_range = 0.2, height_shift_range = 0.2, shear_range=0.15, horizontal_flip = True, fill_mode = "nearest")
#    c   
path_weights = ‘mobilenet_v2_weights_tf_dim_ordering_tf_kernels_1.0_224_no_top.h5'    
baseModel = MobileNetV2(weights=path_weights, 
include_top=False, input_tensor=Input(shape=(224, 224, 3))
        
headModel = baseModel.output
headModel = AveragePooling2D(pool_size = (7, 7))(headModel)
headModel = Flatten(name = "flatten")(headModel)
headModel = Dense(128, activation = "relu")(headModel)
headModel = Dropout(0.5)(headModel)
headModel = Dense(2, activation = "softmax")(headModel)
model = Model(inputs = baseModel.input, outputs = headModel)
#     
for layer in baseModel.layers:
	layer.trainable = False
#   
opt = Adam(lr = INIT_LR, decay = INIT_LR / EPOCHS)
model.compile(loss = "binary_crossentropy", optimizer = opt, metrics = ["accuracy"])
#   
H = model.fit( aug.flow(trainX, trainY, batch_size = BS), steps_per_epoch = len(trainX) // BS,
	validation_data = (testX, testY), validation_steps = len(testX) // BS, epochs = EPOCHS)
#     
predIdxs = model.predict(testX, batch_size = BS)
#       ,   
predIdxs = np.argmax(predIdxs, axis=1)
#    
print(classification_report(testY.argmax(axis = 1), predIdxs, target_names = lb.classes_))
      
      



#





model.save('model_mask_FACE', save_format = "h5")
model_mask = tf.keras.models.load_model('model_mask_FACE)
      
      



,  





# , MTCNN





frame = cv2.cvtColor(cv2.imread(‘house.png'), cv2.COLOR_BGR2RGB)
frame_image = Image.fromarray(frame)
boxes, probs, landmarks = mtcnn.detect(frame_image, landmarks = True)
x1, y1, x2, y2 = [int(bx) for bx in boxes[0]]
image = Image.fromarray(frame[y1:y2, x1:x2]).resize((224,224))
face = img_to_array(image)
      
      



#





face = preprocess_input(face)
face = np.expand_dims(face, axis=0)
      
      



#  





(mask, withoutMask) = model_mask.predict(face)[0]
image = cv2.imread(‘house.png’)
      
      



#





if mask > withoutMask and max(mask, withoutMask) > 0.8: # 
    label = "Mask" if mask > withoutMask else "No Mask"
    color = (0, 122, 0) if label == "Mask" else (0, 0, 122)
    label = "{}: {:.2f}%".format(label, max(mask, withoutMask) * 100)
    cv2.putText(image, label, (x1, y1 - 10),cv2.FONT_HERSHEY_SIMPLEX, 2, color, 5)
    cv2.rectangle(image, (x1, y1), (x2, y2), color, 5) 
    y = Image.fromarray(cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
      
      



Ainsi, dans cet article, nous avons montré comment recycler le réseau de neurones MobileNetV2 afin de classer les images de personnes avec et sans masques médicaux.








All Articles