Cara membina projek Python pengecaman wajah dan jantina menggunakan pembelajaran mendalam dan VGG16.
Pembelajaran mendalam ialah subkategori pembelajaran mesin, rangkaian saraf dengan tiga atau lebih lapisan. Rangkaian saraf ini cuba mensimulasikan tingkah laku otak manusia dengan belajar daripada sejumlah besar data. Walaupun rangkaian saraf dengan satu lapisan masih boleh membuat ramalan anggaran, lapisan tersembunyi tambahan boleh membantu mengoptimumkan dan memperhalusi untuk ketepatan.
Pembelajaran mendalam meningkatkan automasi dengan melaksanakan tugas tanpa campur tangan manusia. Pembelajaran mendalam boleh didapati dalam pembantu digital, alat kawalan jauh TV berdaya suara, pengesanan penipuan kad kredit dan kereta pandu sendiri.
** Lihat kod penuh di GitHub: https://github.com/alexiacismaru/face-recognition
Muat turun Set Data Wajah VGG16 dan fail XML Haar Cascade yang digunakan untuk pengesanan muka yang akan digunakan untuk prapemprosesan dalam tugas pengecaman muka.
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())
Muat dan proses secara terpilih beberapa imej untuk set subjek yang dipratentukan daripada Set Data Wajah 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
Lelar melalui fail setiap subjek dengan membuka fail teks yang dikaitkan dengan subjek dan membaca kandungannya. Setiap baris dalam fail ini mengandungi URL ke imej. Untuk setiap URL (yang menghala ke imej), kod cuba memuatkan imej menggunakan urllib dan menukarnya menjadi tatasusunan 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)
Kaedah detectMultiScale mengecam muka dalam imej. Ia kemudian mengembalikan koordinat segi empat tepat di mana ia percaya wajah terletak. Untuk setiap muka, segi empat tepat dilukis di sekelilingnya dalam imej, menunjukkan lokasi wajah itu. Setiap imej diubah saiz kepada 224x224 piksel.
Pisah set data kepada set latihan dan pengesahan:
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())
Ketepatan model pembelajaran mendalam bergantung pada kualiti, kuantiti dan makna kontekstual data latihan. Ini adalah salah satu cabaran yang paling biasa dalam membina model pembelajaran mendalam dan ia boleh menelan kos dan memakan masa. Syarikat menggunakan penambahan data untuk mengurangkan pergantungan pada contoh latihan untuk membina model berketepatan tinggi dengan cepat.
Penambahan data bermaksud meningkatkan jumlah data secara buatan dengan menjana titik data baharu daripada data sedia ada. Ini termasuk menambahkan perubahan kecil pada data atau menggunakan model pembelajaran mesin untuk menjana titik data baharu dalam ruang terpendam data asal untuk menguatkan set data.
Sintetik mewakili data yang dijana secara buatan tanpa menggunakan imej dunia sebenar dan ia dihasilkan oleh Generative Adversarial Networks.
Ditambah terbit daripada imej asal dengan beberapa jenis transformasi geometri kecil (seperti terbalik, terjemahan, putaran atau penambahan bunyi) untuk meningkatkan kepelbagaian set latihan.
# 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
Pembesaran data meningkatkan prestasi model ML melalui set data yang lebih pelbagai dan mengurangkan kos operasi yang berkaitan dengan pengumpulan data:
VGG16 ialah rangkaian saraf konvolusi yang digunakan secara meluas untuk pengecaman imej. Ia dianggap sebagai salah satu seni bina model penglihatan komputer terbaik. Ia terdiri daripada 16 lapisan neuron buatan yang memproses imej secara berperingkat untuk meningkatkan ketepatan. Dalam VGG16, "VGG" merujuk kepada Kumpulan Geometri Visual Universiti Oxford, manakala "16" merujuk kepada 16 lapisan berwajaran rangkaian.
VGG16 digunakan untuk pengecaman imej dan pengelasan imej baharu. Versi rangkaian VGG16 pra-latihan dilatih pada lebih satu juta imej daripada pangkalan data visual ImageNet. VGG16 boleh digunakan untuk menentukan sama ada imej mengandungi item tertentu, haiwan, tumbuhan dan banyak lagi.
Terdapat 13 lapisan konvolusi, lima lapisan Max Pooling dan tiga lapisan Padat. Ini menghasilkan 21 lapisan dengan 16 pemberat, bermakna ia mempunyai 16 lapisan parameter yang boleh dipelajari. VGG16 mengambil saiz tensor input sebagai 224x244. Model ini memfokuskan pada mempunyai lapisan lilitan penapis 3x3 dengan langkah 1. Ia sentiasa menggunakan padding yang sama dengan lapisan maxpool penapis 2x2 langkah 2.
Lapisan Penukaran-1 mempunyai 64 penapis, Penukaran-2 mempunyai 128 penapis, Penukaran-3 mempunyai 256 penapis, Penukaran 4 dan Penukaran 5 mempunyai 512 penapis dan tiga lapisan bersambung sepenuhnya di mana dua lapisan pertama mempunyai 4096 saluran setiap satu, yang ketiga melaksanakan klasifikasi ILSVRC 1000 hala dan mengandungi 1000 saluran (satu untuk setiap kelas). Lapisan terakhir ialah lapisan maksimum lembut.
Mula menyediakan model asas.
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())
Untuk memastikan model akan mengklasifikasikan imej dengan betul, kita perlu memanjangkan model dengan lapisan tambahan.
# 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
Lapisan 2D Penggabungan Purata Global memekatkan peta ciri yang diperoleh daripada VGG16 menjadi satu vektor 1D bagi setiap peta. Ia memudahkan output dan mengurangkan jumlah parameter, membantu dalam pencegahan overfitting.
Lapisan padat ialah jujukan lapisan bersambung sepenuhnya (Padat) yang ditambahkan. Setiap lapisan mengandungi bilangan unit tertentu (1024, 512, dan 256), dipilih berdasarkan amalan biasa dan percubaan. Lapisan ini memproses lagi ciri yang diekstrak oleh VGG16.
Lapisan Padat terakhir (Lapisan Output) menggunakan pengaktifan sigmoid yang sesuai untuk klasifikasi binari (dua kelas kami ialah 'perempuan' dan 'lelaki').
Algoritma Pengoptimuman Adam ialah lanjutan daripada prosedur penurunan kecerunan stokastik untuk mengemas kini berat rangkaian berulang berdasarkan data latihan. Kaedah ini cekap apabila menangani masalah besar yang melibatkan banyak data atau parameter. Ia memerlukan kurang ingatan dan cekap.
Algoritma ini menggabungkan dua metodologi penurunan kecerunan: momentum dan Pembiakan Purata Purata Akar (RMSP).
Momentum ialah algoritma yang digunakan untuk membantu mempercepatkan algoritma penurunan kecerunan menggunakan purata wajaran eksponen bagi kecerunan.
Root mean square prop ialah algoritma pembelajaran adaptif yang cuba menambah baik AdaGrad dengan mengambil "purata bergerak eksponen".
Memandangkan mt dan vt mempunyai kedua-duanya dimulakan sebagai 0 (berdasarkan kaedah di atas), diperhatikan bahawa mereka mendapat kecenderungan untuk 'berat sebelah ke arah 0' kerana kedua-dua β1 & β2 ≈ 1. Pengoptimum ini membetulkan masalah ini dengan mengira 'bias-diperbetulkan' mt dan vt. Ini juga dilakukan untuk mengawal berat semasa mencapai minimum global untuk mengelakkan ayunan tinggi apabila berhampirannya. Formula yang digunakan ialah:
Secara intuitif, kami menyesuaikan diri dengan penurunan kecerunan selepas setiap lelaran supaya ia kekal terkawal dan tidak berat sebelah sepanjang proses, maka dinamakan Adam.
Sekarang, bukannya parameter berat biasa kami mt dan vt, kami mengambil parameter berat pembetulan berat sebelah (m_hat)t dan (v_hat)t. Meletakkannya ke dalam persamaan am kita, kita dapat:
Sumber: 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())
Sediakan prapemprosesan data imej, pembesaran dan latihan model dalam konteks pembelajaran yang mendalam.
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())
Prestasi model dinilai dengan membuat ramalan pada set pengesahan. Ini memberi gambaran tentang sejauh mana model itu melaksanakan data yang tidak kelihatan. Ambang digunakan pada ramalan ini untuk mengklasifikasikan setiap imej kepada satu daripada dua kelas (“lelaki” atau “perempuan”).
# 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
Buat matriks kekeliruan untuk menggambarkan ketepatan.
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
Untuk klasifikasi binari, keluk Ciri Operasi Penerima (ROC) dan Kawasan Di Bawah Keluk (AUC) berguna untuk memahami pertukaran antara kadar positif benar dan kadar positif palsu.
# 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)
Kesimpulannya, dengan menggunakan pembelajaran mendalam dan algoritma pemprosesan imej anda boleh membina projek Python yang mengenali wajah manusia dan boleh mengkategorikannya sama ada lelaki atau perempuan.
Atas ialah kandungan terperinci Menggunakan VGG untuk pengecaman muka dan jantina. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!