Ara 182018
 
4.844 kez okundu

OpenCV ile Yüz Tanıma Bölüm 3-2

Önceki yazımda veri setimizi nasıl oluşturacağımızı anlatmıştım.

Bu kez veri setimizi Keras kullanarak eğiteceğiz. Sonra da yeni resimleri bu eğitilmiş veri setini kullanarak sınıflandıracağız.

3. ADIM – EĞİTİM

Projemize örnek olarak aldığımız çalışmada Adrian, Keras modellemesi için SmallerVGGNet sınıfını kullanıyor. Ben onun yerine daha basit bir model kullandım (vgg_like). Eğer isterseniz yazının sonundaki Referanslar bölümünde yer alan linkleri kullanarak SmallerVGGNet kodlarına ulaşabilirsiniz.

Lafı uzatmadan eğitim betiğimize geçelim. Betiğimizin adı: train.py

İşin içine eğitim girince bir sürü kütüphane ve modüle ihtiyaç duyuyoruz. Kullanacağımız kütüphaneler hakkında kabaca da olsa, bilgi sahibi olduğunuzu umuyorum. Yoksa bu yazıyı 1000-1500 kelimelik bir hacme sığdırmak olanaksız hale gelirdi.

İlk 27 satırımızda matplotlib, keras, sklearn, imutils, numpy, random, pickle, cv2 ve os kütüphanelerimizi içe aktarıyoruz. smallervggnet kütüphanesini de belki kullanırsınız diye listeden çıkarmadım.

Modeli daha basit tutmak amacıyla vgg_like() fonksiyonunu tanımladım. (VGGNet, 2014 yılındaki Imagenet Büyük Ölçekli Görsel Tanıma Yarışmasında çok iyi performans gösteren bir yapay sinir ağıdır. VGG (Visual Geometry Group) Oxford Üniversitesi Mühendislik Bilimleri Bölümünün bir alt birimidir.)

Eğitim için Doğrusal(Sequential) bir model kullanıyoruz – satır 30
Görsellerimiz 96×96 boyutlu ve 3 renk kanalına sahip.
Modelimize ilk önce bir Conv2D katmanı uyguluyoruz – satır 31
İkinci katmanımız yine Conv2D – satır 32
Üçüncü katmanda MaxPooling2D var – satır 33
34. satırdaki Dropout ile %25’lik giriş bilgisini devre dışı bırakıyoruz (overfitting engelleme).

Benzer işlemleri bir kez daha tekrarlıyoruz. Ama boyutlamalar biraz farklı. satır 36-39

Son aşamada modelimize önce Flatten(), sonra Dense() uyguluyoruz. satır 41-42
Dropout oranımız %50 satır 43
Son işlemimiz her zamanki gibi ‘softmax’ satır 44
45.satırda modelimizi geri döndürüyoruz.

47. satırda işlem başlangıç zamanını t0 olarak not ediyoruz. Bu değişkeni belirli aşamalarda geçen süreyi belirtmek için kullanacağız.

Satır 48-51’de sabitlerimizi tanımlıyoruz.

data ve labels boş birer listedir. satır 53-54

58. satırda görsel dosya yollarımızı bir listede topluyoruz (imagePaths).

imagePaths listesinin satırlarını karıştırırken, sonraki denemelerde de aynı rasgele değerleri elde edebilmek için seed değerini 42 olarak belirliyoruz. satır 60 (Bu değer herhangi bir başka sayı da olabilir. Önemli olan hep aynı başlatma değerini kullanmak.)

63. satırda görsel dosyalarını işlemeye başlıyoruz.
Dosyayı okuyoruz – satır 64
İmajı 96×96 olarak yeniden boyutlandırıyoruz – satır 65
İmajı bir dizi (array) haline dönüştürüyoruz – satır 66
Ve imaj dizisini data listesine ekliyoruz – satır 67

Dosya yolundan etiket bilgisini (sanatçı_kodu) ayrıştırıyoruz – satır 70
Etiket bilgisini labels listesine ekliyoruz – satır 71

data listesini elemanları 0 veya 1 olacak şekilde bir numpy dizisine çeviriyoruz – satır 75
Aynı şekilde labels listesini de bir numpy dizisi haline getiriyoruz – satır 76

Satır 81-82’de etiketleri sayısallaştırıyoruz.

Satır 85-86: data ve labels dizi elemanlarının %20’sini test, geri kalanını eğitim için ayırıyoruz.

Veri sayımız kısıtlı olduğu için data çoğullama (augmentation) işlemi yaptırıyoruz – satır 89-91 (Çoğullama sırasında döndürme, kaydırma, yükseklik değiştirme, kesme, büyütme ve yatay aynalama (flip) işlemleri yapılacak.)

Modelimizi vgg_like() fonksiyonu ile oluşturuyoruz – satır 99

model.summary(), model katmanlarımızın değişimini ayrıntılı bir şekilde açıklıyor. Bu özeti hem ekrana, hem de dosyaya kaydediyoruz. – satır 102-105

Optimizasyon işlemi için Adam da yaygın bir şekilde kullanılıyor. Benim yaptığım denemelerde SGD daha iyi sonuçlar almamı sağladı. Her ikisini de deneyebilirsiniz. Satır 108

110. satırda modelimizi derliyoruz.

Eğitim işlemleri (satır 116-120) için bir kaç dakika bekliyoruz.

Eğitim tamamlandığında, önce modelimizi (satır 124), sonra da etiketlerimizi (satır 128-130) kaydediyoruz.

Son aşama olarak, eğitim işlemlerimiz sırasında hesaplanan kayıp ve doğruluk değerlerini grafiğe döküyor ve plot.png adıyla kaydediyoruz. – satır 135-146

OpenCV ile Yüz Tanıma Bölüm 3-2

Artık sınıflandırma işlemlerimize geçebiliriz. Ama daha önce model özetimize kısaca bir göz atsak iyi olacak:

Conv2D katman çıkış boyutlarında 2 piksellik küçülme yaratıyor.
MaxPooling2D ise (2,2) oranları ile her iki yönde boyutları yarıya indiriyor.
Flatten işlemi katmanı tek boyutlu bir diziye dönüştürür.
Dropout input değerlerinden bir bölümünü işlem dışı bırakır. Böylece overfitting olasılığı azalır.

4. ADIM – SINIFLANDIRMA

Sınıflandırma işlemlerinde eğitim aşamasında kullanmadığımız görsellerden yararlanacağız. Her sanatçı için birer görsel seçtik ve bunları kontrol klasörünün altına kopyaladık.

İlk 7 satırda gerekli kütüphaneleri içeri aktarıyoruz.

imajlar listesi sınıflandıracağımız fotoğrafları tutuyor. satır 10

Sınıflandırma işlemlerini check_image() fonksiyonu ile yapacağız (satır 12). Her görsel ayrı ayrı işleme sokulacak.

Satır 13-16’da imajımızı 96×96 piksel boyutlarına küçültüyor ve modelimize uygun bir numpy dizisine dönüştürüyoruz.

Satır 19 ve 20’de eğitim sonunda kaydettiğimiz model ve etiket bilgilerini belleğe alıyoruz.

Modele göre bulunan tahmin ve olası doğruluk derecesini saptıyor; etiket değerini alıyoruz. satır 23-25

Sınıflandırma sonucunu genişliğini 400 pikselle sınırlandırdığımız imajımızın üzerine işliyoruz. satır 28-33

İşlenmiş imajı ekranda gösterip diske kaydettikten sonra bir tuşa basılmasını bekliyoruz. satır 35-38

Tuşa basıldığında belleği temizliyoruz: satır 39

check_image() fonksiyonumuzu her resim için ayrı ayrı çağıran döngümüz satır 42-45 arasında.

Elde ettiğim görüntüler aşağıda:

OpenCV ile Yüz Tanıma Bölüm 3-2

OpenCV ile Yüz Tanıma Bölüm 3-2

OpenCV ile Yüz Tanıma Bölüm 3-2

SmallerVGGNet kullanarak yaptığım denemelerde daha yüksek sayısal doğruluk oranlarına ulaştım ama, yapılan tahminlerin pek çoğu aslında hatalıydı. Bu, veri kümemizin çok dar olmasından kaynaklanmış olabilir.

Aynı eğitim setini yüz saptama fonksiyonlarıyla birlikte kullanarak grup fotoğraflarından çoklu yüz tanıma işlemleri gerçekleştirmek mümkün olabilir.

Açıklamalara böyle bir blog yazısında daha kapsamlı bir şekilde girmek mümkün olmuyor. Sorularınız varsa, yorum alanından iletebilirsiniz.

Bu tür çalışmalar çok geniş bir kapsama alanına sahip. Yapılan işlemler ve elde edilen sonuçlar deneysel nitelikte. Bu yüzden, bu tür konulara ilgi duyuyorsanız, siz de kendi modellerinizi geliştirin. Mümkünse veri kümeleri oluşturun. Deneyin. Yorumlayın.

Elbette hala öğrenecek çok şey var. Ama yapabileceğimiz şeyler de pek çok…

Önemli olan, hangi düzeyde olursak olalım, deneysel bakış açımızı yitirmemek ve hevesimizi kaybetmemek… Hata yapmak bizi korkutmasın. Hatalar, kullanmasını bilenler için en etkin yol göstericilerdir.

Yeni yazılarda buluşmak üzere…

Beni izlemeye devam edin.

Ahmet Aksoy

Referanslar:
https://github.com/kjaisingh/pokemon-classifier/blob/master/pyimagesearch/smallervggnet.py
https://www.pyimagesearch.com/2018/04/16/keras-and-convolutional-neural-networks-cnns/
https://hackernoon.com/learning-keras-by-implementing-vgg16-from-scratch-d036733f2d5
http://www.robots.ox.ac.uk/~vgg/research/very_deep/