Comment créer un projet Python de reconnaissance des visages et des genres en utilisant le deep learning et VGG16.
Le deep learning est une sous-catégorie du machine learning, un réseau neuronal à trois couches ou plus. Ces réseaux de neurones tentent de simuler le comportement du cerveau humain en apprenant à partir de grandes quantités de données. Même si un réseau neuronal avec une seule couche peut toujours faire des prédictions approximatives, des couches cachées supplémentaires peuvent aider à optimiser et à affiner la précision.
Le deep learning améliore l'automatisation en effectuant des tâches sans intervention humaine. L'apprentissage profond peut être trouvé dans les assistants numériques, les télécommandes de télévision à commande vocale, la détection des fraudes par carte de crédit et les voitures autonomes.
** Consultez le code complet sur GitHub : https://github.com/alexiacismaru/face-recognision
Téléchargez l'ensemble de données faciales VGG16 et le fichier XML Haar Cascade utilisé pour la détection des visages qui seront utilisés pour le prétraitement dans la tâche de reconnaissance faciale.
faceCascade = cv2.CascadeClassifier(os.path.join(base_path, "haarcascade_frontal_face_default.xml")) # haar cascade detects faces in images vgg_face_dataset_url = "http://www.robots.ox.ac.uk/~vgg/data/vgg_face/vgg_face_dataset.tar.gz" with request.urlopen(vgg_face_dataset_url) as r, open(os.path.join(base_path, "vgg_face_dataset.tar.gz"), 'wb') as f: f.write(r.read()) # extract VGG dataset with tarfile.open(os.path.join(base_path, "vgg_face_dataset.tar.gz")) as f: f.extractall(os.path.join(base_path)) # download Haar Cascade for face detection trained_haarcascade_url = "https://raw.githubusercontent.com/opencv/opencv/master/data/haarcascades/haarcascade_frontalface_default.xml" with request.urlopen(trained_haarcascade_url) as r, open(os.path.join(base_path, "haarcascade_frontalface_default.xml"), 'wb') as f: f.write(r.read())
Chargez et traitez sélectivement un nombre spécifique d'images pour un ensemble de sujets prédéfinis à partir de l'ensemble de données de visage VGG.
# populate the list with the files of the celebrities that will be used for face recognition all_subjects = [subject for subject in sorted(os.listdir(os.path.join(base_path, "vgg_face_dataset", "files"))) if subject.startswith("Jesse_Eisenberg") or subject.startswith("Sarah_Hyland") or subject.startswith("Michael_Cera") or subject.startswith("Mila_Kunis") and subject.endswith(".txt")] # define number of subjects and how many pictures to extract nb_subjects = 4 nb_images_per_subject = 40
Parcourez le fichier de chaque sujet en ouvrant un fichier texte associé au sujet et en lisant le contenu. Chaque ligne de ces fichiers contient une URL vers une image. Pour chaque URL (qui pointe vers une image), le code tente de charger l'image à l'aide de urllib et de la convertir en tableau NumPy.
images = [] for subject in all_subjects[:nb_subjects]: with open(os.path.join(base_path, "vgg_face_dataset", "files", subject), 'r') as f: lines = f.readlines() images_ = [] for line in lines: url = line[line.find("http://"): line.find(".jpg") + 4] try: res = request.urlopen(url) img = np.asarray(bytearray(res.read()), dtype="uint8") # convert the image data into a format suitable for OpenCV # images are colored img = cv2.imdecode(img, cv2.IMREAD_COLOR) h, w = img.shape[:2] images_.append(img) cv2_imshow(cv2.resize(img, (w // 5, h // 5))) except: pass # check if the required number of images has been reached if len(images_) == nb_images_per_subject: # add the list of images to the main images list and move to the next subject images.append(images_) break
# create arrays for all 4 celebrities jesse_images = [] michael_images = [] mila_images = [] sarah_images = [] faceCascade = cv2.CascadeClassifier(os.path.join(base_path, "haarcascade_frontalface_default.xml")) # iterate over the subjects for subject, images_ in zip(all_subjects, images): # create a grayscale copy to simplify the image and reduce computation for img in images_: img_ = img.copy() img_gray = cv2.cvtColor(img_, cv2.COLOR_BGR2GRAY) faces = faceCascade.detectMultiScale( img_gray, scaleFactor=1.2, minNeighbors=5, minSize=(30, 30), flags=cv2.CASCADE_SCALE_IMAGE ) print("Found {} face(s)!".format(len(faces))) for (x, y, w, h) in faces: cv2.rectangle(img_, (x, y), (x+w, y+h), (0, 255, 0), 10) h, w = img_.shape[:2] resized_img = cv2.resize(img_, (224, 224)) cv2_imshow(resized_img) if "Jesse_Eisenberg" in subject: jesse_images.append(resized_img) elif "Michael_Cera" in subject: michael_images.append(resized_img) elif "Mila_Kunis" in subject: mila_images.append(resized_img) elif "Sarah_Hyland" in subject: sarah_images.append(resized_img)
La méthode detectMultiScale reconnaît les visages dans l'image. Il renvoie ensuite les coordonnées des rectangles où il pense que les faces se trouvent. Pour chaque visage, un rectangle est dessiné autour de lui dans l’image, indiquant l’emplacement du visage. Chaque image est redimensionnée à 224x224 pixels.
Divisez l'ensemble de données en un ensemble de formation et de validation :
faceCascade = cv2.CascadeClassifier(os.path.join(base_path, "haarcascade_frontal_face_default.xml")) # haar cascade detects faces in images vgg_face_dataset_url = "http://www.robots.ox.ac.uk/~vgg/data/vgg_face/vgg_face_dataset.tar.gz" with request.urlopen(vgg_face_dataset_url) as r, open(os.path.join(base_path, "vgg_face_dataset.tar.gz"), 'wb') as f: f.write(r.read()) # extract VGG dataset with tarfile.open(os.path.join(base_path, "vgg_face_dataset.tar.gz")) as f: f.extractall(os.path.join(base_path)) # download Haar Cascade for face detection trained_haarcascade_url = "https://raw.githubusercontent.com/opencv/opencv/master/data/haarcascades/haarcascade_frontalface_default.xml" with request.urlopen(trained_haarcascade_url) as r, open(os.path.join(base_path, "haarcascade_frontalface_default.xml"), 'wb') as f: f.write(r.read())
La précision des modèles d'apprentissage profond dépend de la qualité, de la quantité et de la signification contextuelle des données d'entraînement. Il s’agit de l’un des défis les plus courants liés à la création de modèles d’apprentissage profond et cela peut s’avérer coûteux et long. Les entreprises utilisent l'augmentation des données pour réduire la dépendance aux exemples de formation afin de créer rapidement des modèles de haute précision.
L'augmentation des données signifie augmenter artificiellement la quantité de données en générant de nouveaux points de données à partir des données existantes. Cela inclut l'ajout de modifications mineures aux données ou l'utilisation de modèles d'apprentissage automatique pour générer de nouveaux points de données dans l'espace latent des données d'origine afin d'amplifier l'ensemble de données.
LesSynthétiques représentent des données générées artificiellement sans utiliser d'images du monde réel et sont produites par Generative Adversarial Networks.
Augmenté dérive d'images originales avec une sorte de transformations géométriques mineures (telles que le retournement, la translation, la rotation ou l'ajout de bruit) pour augmenter la diversité de l'ensemble d'entraînement.
# populate the list with the files of the celebrities that will be used for face recognition all_subjects = [subject for subject in sorted(os.listdir(os.path.join(base_path, "vgg_face_dataset", "files"))) if subject.startswith("Jesse_Eisenberg") or subject.startswith("Sarah_Hyland") or subject.startswith("Michael_Cera") or subject.startswith("Mila_Kunis") and subject.endswith(".txt")] # define number of subjects and how many pictures to extract nb_subjects = 4 nb_images_per_subject = 40
L'augmentation des données améliore les performances des modèles ML grâce à des ensembles de données plus diversifiés et réduit les coûts d'exploitation liés à la collecte de données :
VGG16 est un réseau neuronal convolutif largement utilisé pour la reconnaissance d'images. Elle est considérée comme l’une des meilleures architectures de modèles de vision par ordinateur. Il se compose de 16 couches de neurones artificiels qui traitent l’image progressivement pour améliorer la précision. Dans VGG16, « VGG » fait référence au Visual Geometry Group de l'Université d'Oxford, tandis que « 16 » fait référence aux 16 couches pondérées du réseau.
VGG16 est utilisé pour la reconnaissance d'images et la classification de nouvelles images. La version pré-entraînée du réseau VGG16 est formée sur plus d'un million d'images de la base de données visuelle ImageNet. VGG16 peut être appliqué pour déterminer si une image contient certains éléments, animaux, plantes et plus encore.
Il y a 13 couches convolutives, cinq couches Max Pooling et trois couches Dense. Cela donne 21 couches avec 16 poids, ce qui signifie qu'il comporte 16 couches de paramètres apprenables. VGG16 prend la taille du tenseur d'entrée à 224x244. Le modèle se concentre sur les couches de convolution d'un filtre 3x3 avec la foulée 1. Il utilise toujours le même rembourrage avec une couche maxpool de filtre 2x2 de la foulée 2.
Conv-1 Layer a 64 filtres, Conv-2 a 128 filtres, Conv-3 a 256 filtres, Conv 4 et Conv 5 ont 512 filtres et trois couches entièrement connectées où les deux premières ont chacune 4096 canaux, la troisième effectue une classification ILSVRC à 1 000 voies et contient 1 000 canaux (un pour chaque classe). La couche finale est la couche soft-max.
Commencez à préparer le modèle de base.
faceCascade = cv2.CascadeClassifier(os.path.join(base_path, "haarcascade_frontal_face_default.xml")) # haar cascade detects faces in images vgg_face_dataset_url = "http://www.robots.ox.ac.uk/~vgg/data/vgg_face/vgg_face_dataset.tar.gz" with request.urlopen(vgg_face_dataset_url) as r, open(os.path.join(base_path, "vgg_face_dataset.tar.gz"), 'wb') as f: f.write(r.read()) # extract VGG dataset with tarfile.open(os.path.join(base_path, "vgg_face_dataset.tar.gz")) as f: f.extractall(os.path.join(base_path)) # download Haar Cascade for face detection trained_haarcascade_url = "https://raw.githubusercontent.com/opencv/opencv/master/data/haarcascades/haarcascade_frontalface_default.xml" with request.urlopen(trained_haarcascade_url) as r, open(os.path.join(base_path, "haarcascade_frontalface_default.xml"), 'wb') as f: f.write(r.read())
Pour nous assurer que le modèle classera correctement les images, nous devons étendre le modèle avec des couches supplémentaires.
# populate the list with the files of the celebrities that will be used for face recognition all_subjects = [subject for subject in sorted(os.listdir(os.path.join(base_path, "vgg_face_dataset", "files"))) if subject.startswith("Jesse_Eisenberg") or subject.startswith("Sarah_Hyland") or subject.startswith("Michael_Cera") or subject.startswith("Mila_Kunis") and subject.endswith(".txt")] # define number of subjects and how many pictures to extract nb_subjects = 4 nb_images_per_subject = 40
La Couche 2D Global Average Pooling condense les cartes de caractéristiques obtenues à partir de VGG16 en un seul vecteur 1D par carte. Il simplifie la sortie et réduit le nombre total de paramètres, contribuant ainsi à prévenir le surajustement.
Les Couches denses sont une séquence de couches (Denses) entièrement connectées qui sont ajoutées. Chaque couche contient un nombre spécifié d'unités (1 024, 512 et 256), choisies sur la base de pratiques et d'expérimentations courantes. Ces couches traitent davantage les caractéristiques extraites par VGG16.
La couche Dense finale (la Couche de sortie) utilise une activation sigmoïde adaptée à la classification binaire (nos deux classes étant « femelle » et « masculin »).
L'algorithme d'optimisation Adam est une extension de la procédure de descente de gradient stochastique pour mettre à jour les pondérations du réseau de manière itérative en fonction des données d'entraînement. La méthode est efficace lorsque l’on travaille sur des problèmes volumineux impliquant beaucoup de données ou de paramètres. Il nécessite moins de mémoire et est efficace.
Cet algorithme combine deux méthodologies de descente de gradient : l'impulsion et la propagation quadratique moyenne (RMSP).
Momentum est un algorithme utilisé pour aider à accélérer l'algorithme de descente de gradient en utilisant la moyenne pondérée exponentielle des gradients.
Root Mean Square Prop est un algorithme d'apprentissage adaptatif qui tente d'améliorer l'AdaGrad en prenant la « moyenne mobile exponentielle ».
Puisque mt et vt ont tous deux été initialisés à 0 (sur la base des méthodes ci-dessus), on observe qu'ils ont tendance à être « biaisés vers 0 » lorsque β1 et β2 ≈ 1. Cet optimiseur résout ce problème en calculant mt et vt « corrigés en biais ». Ceci est également fait pour contrôler les poids tout en atteignant le minimum global afin d'éviter de fortes oscillations à proximité. Les formules utilisées sont :
Intuitivement, nous nous adaptons à la descente de gradient après chaque itération afin qu'elle reste contrôlée et impartiale tout au long du processus, d'où le nom Adam.
Maintenant, au lieu de nos paramètres de poids normaux mt et vt, nous prenons les paramètres de poids corrigés du biais (m_hat)t et (v_hat)t. En les mettant dans notre équation générale, nous obtenons :
Source : Geeksforgeeks, https://www.geeksforgeeks.org/adam-optimizer/
faceCascade = cv2.CascadeClassifier(os.path.join(base_path, "haarcascade_frontal_face_default.xml")) # haar cascade detects faces in images vgg_face_dataset_url = "http://www.robots.ox.ac.uk/~vgg/data/vgg_face/vgg_face_dataset.tar.gz" with request.urlopen(vgg_face_dataset_url) as r, open(os.path.join(base_path, "vgg_face_dataset.tar.gz"), 'wb') as f: f.write(r.read()) # extract VGG dataset with tarfile.open(os.path.join(base_path, "vgg_face_dataset.tar.gz")) as f: f.extractall(os.path.join(base_path)) # download Haar Cascade for face detection trained_haarcascade_url = "https://raw.githubusercontent.com/opencv/opencv/master/data/haarcascades/haarcascade_frontalface_default.xml" with request.urlopen(trained_haarcascade_url) as r, open(os.path.join(base_path, "haarcascade_frontalface_default.xml"), 'wb') as f: f.write(r.read())
Configurer le prétraitement, l'augmentation et la formation des modèles de données d'image dans un contexte d'apprentissage en profondeur.
faceCascade = cv2.CascadeClassifier(os.path.join(base_path, "haarcascade_frontal_face_default.xml")) # haar cascade detects faces in images vgg_face_dataset_url = "http://www.robots.ox.ac.uk/~vgg/data/vgg_face/vgg_face_dataset.tar.gz" with request.urlopen(vgg_face_dataset_url) as r, open(os.path.join(base_path, "vgg_face_dataset.tar.gz"), 'wb') as f: f.write(r.read()) # extract VGG dataset with tarfile.open(os.path.join(base_path, "vgg_face_dataset.tar.gz")) as f: f.extractall(os.path.join(base_path)) # download Haar Cascade for face detection trained_haarcascade_url = "https://raw.githubusercontent.com/opencv/opencv/master/data/haarcascades/haarcascade_frontalface_default.xml" with request.urlopen(trained_haarcascade_url) as r, open(os.path.join(base_path, "haarcascade_frontalface_default.xml"), 'wb') as f: f.write(r.read())
Les performances du modèle sont évaluées en faisant des prédictions sur l'ensemble de validation. Cela donne une idée de la façon dont le modèle traite les données invisibles. Un seuil est appliqué à ces prédictions pour classer chaque image dans l'une des deux classes (« masculin » ou « femelle »).
# populate the list with the files of the celebrities that will be used for face recognition all_subjects = [subject for subject in sorted(os.listdir(os.path.join(base_path, "vgg_face_dataset", "files"))) if subject.startswith("Jesse_Eisenberg") or subject.startswith("Sarah_Hyland") or subject.startswith("Michael_Cera") or subject.startswith("Mila_Kunis") and subject.endswith(".txt")] # define number of subjects and how many pictures to extract nb_subjects = 4 nb_images_per_subject = 40
Créez une matrice de confusion pour visualiser l'exactitude.
images = [] for subject in all_subjects[:nb_subjects]: with open(os.path.join(base_path, "vgg_face_dataset", "files", subject), 'r') as f: lines = f.readlines() images_ = [] for line in lines: url = line[line.find("http://"): line.find(".jpg") + 4] try: res = request.urlopen(url) img = np.asarray(bytearray(res.read()), dtype="uint8") # convert the image data into a format suitable for OpenCV # images are colored img = cv2.imdecode(img, cv2.IMREAD_COLOR) h, w = img.shape[:2] images_.append(img) cv2_imshow(cv2.resize(img, (w // 5, h // 5))) except: pass # check if the required number of images has been reached if len(images_) == nb_images_per_subject: # add the list of images to the main images list and move to the next subject images.append(images_) break
Pour la classification binaire, la courbe des caractéristiques de fonctionnement du récepteur (ROC) et la zone sous la courbe (AUC) sont utiles pour comprendre les compromis entre le taux de vrais positifs et le taux de faux positifs.
# create arrays for all 4 celebrities jesse_images = [] michael_images = [] mila_images = [] sarah_images = [] faceCascade = cv2.CascadeClassifier(os.path.join(base_path, "haarcascade_frontalface_default.xml")) # iterate over the subjects for subject, images_ in zip(all_subjects, images): # create a grayscale copy to simplify the image and reduce computation for img in images_: img_ = img.copy() img_gray = cv2.cvtColor(img_, cv2.COLOR_BGR2GRAY) faces = faceCascade.detectMultiScale( img_gray, scaleFactor=1.2, minNeighbors=5, minSize=(30, 30), flags=cv2.CASCADE_SCALE_IMAGE ) print("Found {} face(s)!".format(len(faces))) for (x, y, w, h) in faces: cv2.rectangle(img_, (x, y), (x+w, y+h), (0, 255, 0), 10) h, w = img_.shape[:2] resized_img = cv2.resize(img_, (224, 224)) cv2_imshow(resized_img) if "Jesse_Eisenberg" in subject: jesse_images.append(resized_img) elif "Michael_Cera" in subject: michael_images.append(resized_img) elif "Mila_Kunis" in subject: mila_images.append(resized_img) elif "Sarah_Hyland" in subject: sarah_images.append(resized_img)
En conclusion, en utilisant des algorithmes d'apprentissage profond et de traitement d'images, vous pouvez créer un projet Python qui reconnaît les visages humains et peut les classer comme masculins ou féminins.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!