Heim > Artikel > Backend-Entwicklung > Verwendung von VGG zur Gesichts- und Geschlechtserkennung
So erstellen Sie ein Python-Projekt zur Gesichts- und Geschlechtserkennung mithilfe von Deep Learning und VGG16.
Deep Learning ist eine Unterkategorie des maschinellen Lernens, ein neuronales Netzwerk mit drei oder mehr Schichten. Diese neuronalen Netze versuchen, das Verhalten des menschlichen Gehirns zu simulieren, indem sie aus großen Datenmengen lernen. Während ein neuronales Netzwerk mit einer einzelnen Schicht immer noch ungefähre Vorhersagen treffen kann, können zusätzliche verborgene Schichten zur Optimierung und Verfeinerung der Genauigkeit beitragen.
Deep Learning verbessert die Automatisierung, indem Aufgaben ohne menschliches Eingreifen ausgeführt werden. Deep Learning findet sich in digitalen Assistenten, sprachgesteuerten TV-Fernbedienungen, der Erkennung von Kreditkartenbetrug und selbstfahrenden Autos.
** Schauen Sie sich den vollständigen Code auf GitHub an: https://github.com/alexiacismaru/face-recognision
Laden Sie den VGG16-Gesichtsdatensatz und die Haar Cascade XML-Datei herunter, die für die Gesichtserkennung verwendet werden und für die Vorverarbeitung in der Gesichtserkennungsaufgabe verwendet werden.
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())
Laden und verarbeiten Sie selektiv eine bestimmte Anzahl von Bildern für eine Reihe vordefinierter Motive aus dem VGG-Gesichtsdatensatz.
# 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
Durchsuchen Sie die Datei jedes Betreffs, indem Sie eine mit dem Betreff verknüpfte Textdatei öffnen und den Inhalt lesen. Jede Zeile in diesen Dateien enthält eine URL zu einem Bild. Für jede URL (die auf ein Bild verweist) versucht der Code, das Bild mit urllib zu laden und in ein NumPy-Array zu konvertieren.
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)
Die Methode detectMultiScale erkennt Gesichter im Bild. Anschließend werden die Koordinaten der Rechtecke zurückgegeben, in denen sich seiner Meinung nach Flächen befinden. Um jedes Gesicht herum wird im Bild ein Rechteck gezeichnet, das die Position des Gesichts angibt. Die Größe jedes Bildes wird auf 224 x 224 Pixel geändert.
Teilen Sie den Datensatz in einen Trainings- und Validierungssatz auf:
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())
Die Genauigkeit von Deep-Learning-Modellen hängt von der Qualität, Quantität und kontextuellen Bedeutung der Trainingsdaten ab. Dies ist eine der häufigsten Herausforderungen beim Aufbau von Deep-Learning-Modellen und kann kostspielig und zeitaufwändig sein. Unternehmen nutzen Datenerweiterung, um die Abhängigkeit von Trainingsbeispielen zu verringern und schnell hochpräzise Modelle zu erstellen.
Datenerweiterung bedeutet, die Datenmenge künstlich zu vergrößern, indem aus vorhandenen Daten neue Datenpunkte generiert werden. Dazu gehört das Hinzufügen geringfügiger Änderungen an Daten oder die Verwendung von Modellen des maschinellen Lernens, um neue Datenpunkte im latenten Raum der Originaldaten zu generieren und den Datensatz zu erweitern.
Synthetics stellen künstlich generierte Daten ohne Verwendung realer Bilder dar und werden von Generative Adversarial Networks produziert.
Erweitert wird von Originalbildern mit geringfügigen geometrischen Transformationen (wie Spiegeln, Translation, Rotation oder Hinzufügen von Rauschen) abgeleitet, um die Vielfalt des Trainingssatzes zu erhöhen.
# 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
Datenerweiterung verbessert die Leistung von ML-Modellen durch vielfältigere Datensätze und senkt die Betriebskosten im Zusammenhang mit der Datenerfassung:
VGG16 ist ein Faltungs-Neuronales Netzwerk, das häufig zur Bilderkennung verwendet wird. Sie gilt als eine der besten Computer-Vision-Modellarchitekturen. Es besteht aus 16 Schichten künstlicher Neuronen, die das Bild schrittweise verarbeiten, um die Genauigkeit zu verbessern. In VGG16 bezieht sich „VGG“ auf die Visual Geometry Group der University of Oxford, während sich „16“ auf die 16 gewichteten Schichten des Netzwerks bezieht.
VGG16 wird zur Bilderkennung und Klassifizierung neuer Bilder verwendet. Die vorab trainierte Version des VGG16-Netzwerks wird anhand von über einer Million Bildern aus der visuellen ImageNet-Datenbank trainiert. VGG16 kann angewendet werden, um festzustellen, ob ein Bild bestimmte Gegenstände, Tiere, Pflanzen und mehr enthält.
Es gibt 13 Faltungsschichten, fünf Max-Pooling-Schichten und drei dichte Schichten. Daraus ergeben sich 21 Schichten mit 16 Gewichtungen, also 16 lernbare Parameterschichten. VGG16 nimmt die Größe des Eingabetensors als 224 x 244 an. Das Modell konzentriert sich auf Faltungsschichten eines 3x3-Filters mit Schritt 1. Es verwendet immer die gleiche Polsterung mit einer Maxpool-Schicht eines 2x2-Filters mit Schritt 2.
Conv-1 Layer hat 64 Filter, Conv-2 hat 128 Filter, Conv-3 hat 256 Filter, Conv 4 und Conv 5 haben 512 Filter und drei vollständig verbundene Layer, wobei die ersten beiden jeweils 4096 Kanäle haben, der dritte führt eine 1000-Wege-ILSVRC-Klassifizierung durch und enthält 1000 Kanäle (einen für jede Klasse). Die letzte Schicht ist die Soft-Max-Schicht.
Beginnen Sie mit der Vorbereitung des Basismodells.
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())
Um sicherzustellen, dass das Modell die Bilder korrekt klassifiziert, müssen wir das Modell um zusätzliche Ebenen erweitern.
# 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
Die Global Average Pooling 2D-Ebene verdichtet die aus VGG16 erhaltenen Feature-Maps zu einem einzigen 1D-Vektor pro Karte. Es vereinfacht die Ausgabe und reduziert die Gesamtzahl der Parameter, was dazu beiträgt, eine Überanpassung zu verhindern.
Die Dichte Schichten sind eine Folge vollständig verbundener (dichter) Schichten, die hinzugefügt werden. Jede Schicht enthält eine bestimmte Anzahl von Einheiten (1024, 512 und 256), die auf der Grundlage gängiger Praktiken und Experimente ausgewählt werden. Diese Ebenen verarbeiten die von VGG16 extrahierten Features weiter.
Die letzte dichte Ebene (die Ausgabeebene) verwendet eine Sigmoidaktivierung, die für die binäre Klassifizierung geeignet ist (unsere beiden Klassen sind „weiblich“ und „männlich“).
Der Adam-Optimierungsalgorithmus ist eine Erweiterung des stochastischen Gradientenabstiegsverfahrens, um Netzwerkgewichte iterativ auf der Grundlage von Trainingsdaten zu aktualisieren. Die Methode ist effizient, wenn große Probleme mit vielen Daten oder Parametern bearbeitet werden. Es benötigt weniger Speicher und ist effizient.
Dieser Algorithmus kombiniert zwei Gradientenabstiegsmethoden: Impuls und Root Mean Square Propagation (RMSP).
Momentum ist ein Algorithmus, der dazu dient, den Gradientenabstiegsalgorithmus mithilfe des exponentiell gewichteten Durchschnitts der Gradienten zu beschleunigen.
Root Mean Square Prop ist ein adaptiver Lernalgorithmus, der versucht, den AdaGrad zu verbessern, indem er den „exponentiellen gleitenden Durchschnitt“ verwendet.
Da mt und vt beide als 0 initialisiert wurden (basierend auf den oben genannten Methoden), ist zu beobachten, dass sie tendenziell „gegen 0 tendieren“, da sowohl β1 als auch β2 ≈ 1. Dieser Optimierer behebt dieses Problem durch Berechnung 'Bias-korrigierter' mt und vt. Dies geschieht auch, um die Gewichte beim Erreichen des globalen Minimums zu kontrollieren und starke Schwankungen in dessen Nähe zu verhindern. Die verwendeten Formeln sind:
Intuitiv passen wir uns nach jeder Iteration an den Gradientenabfall an, sodass er während des gesamten Prozesses kontrolliert und unvoreingenommen bleibt, daher der Name Adam.
Anstelle unserer normalen Gewichtsparameter mt und vt nehmen wir nun die voreingenommenen Gewichtsparameter (m_hat)t und (v_hat)t. Setzen wir sie in unsere allgemeine Gleichung ein, erhalten wir:
Quelle: 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())
Richten Sie die Vorverarbeitung, Erweiterung und das Modelltraining von Bilddaten in einem Deep-Learning-Kontext ein.
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())
Die Leistung des Modells wird bewertet, indem Vorhersagen zum Validierungssatz getroffen werden. Dies gibt einen Eindruck davon, wie gut das Modell unsichtbare Daten verarbeitet. Auf diese Vorhersagen wird ein Schwellenwert angewendet, um jedes Bild in eine von zwei Klassen („männlich“ oder „weiblich“) zu klassifizieren.
# 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
Erstellen Sie eine Verwirrungsmatrix, um die Genauigkeit zu visualisieren.
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
Für die binäre Klassifizierung sind die ROC-Kurve (Receiver Operating Characteristic) und die AUC (Area Under Curve) hilfreich, um die Kompromisse zwischen der Rate richtig positiver und der Rate falsch positiver Ergebnisse zu verstehen.
# 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)
Zusammenfassend lässt sich sagen, dass Sie durch die Verwendung von Deep-Learning- und Bildverarbeitungsalgorithmen ein Python-Projekt erstellen können, das menschliche Gesichter erkennt und sie entweder als männlich oder weiblich kategorisieren kann.
Das obige ist der detaillierte Inhalt vonVerwendung von VGG zur Gesichts- und Geschlechtserkennung. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!