Ara 062018
 
11.104 kez okundu

OpenCV ile Yüz Tanıma Bölüm 1

OpenCV ile Yüz Tanıma Bölüm 1

Yüz tanıma biraz geniş kapsamlı bir konu. Öncelikle incelediğimiz görselde bulunan olası “yüz”leri, daha sonra da gerekiyorsa bu yüzlerin “kim”e ait olduğunu saptamak sözkonusu. Ya da yüzlerin üzerindeki yüz, göz, kaş, burun, kulak gibi elemanların (facial features) belirlenmesi… O yüzden bu konuyu tek bir yazıyla değil, ardışık birkaç yazıyla ele alacağım.

İlk bölümde bir fotoğraf karesinde kaç adet “yüz” bulunduğunu saptayacağız.

Çeşitli beden parçalarını filtre etmek amacıyla kullanılan en yaygın araçlardan biri “haar cascade” sınıflandırıcılarıdır. Yazının sonunda bu “.xml” uzantılı dosyalara ulaşabileceğiniz çeşitli linkler bulacaksınız. Hatta isterseniz, kendi sınıflandırıcılarınızı bile eğitebilirsiniz. (Ben şimdilik bu maceraya kalkışmıyorum. Elde yeterince hazır kaynak var.)

Ele alacağımız “face_count.py” betiğindeki temel filtremiz “haarcascade_frontalface_default.xml”. Bu filtre genellikle çok verimli çalışıyor. Ancak imaj boyutları yeterince büyük değilse bazı hatalı (false positive) sonuçlar döndürebiliyor. Bu sorunu kısmen de olsa aşabilmek için “it_contains_eyes()” isimli bir fonksiyon tanımladım. Bu fonksiyon saptanan yüz alanının içinde göz, burun veya dudak olup olmadığını araştırıyor. Bulamazsa, yüz bulgusunun hatalı olduğunu geriye “False” döndürerek bildiriyor.

Ben 3 ayrı fotoğrafı döngü içinde test ettirdim. Siz de kendi istediğiniz fotoğrafları kullanabilirsiniz.

Orijinal koda ilave ettiğim bir değişiklik de UTF-8 fontlarını destekleyen Pillow kütüphanesini kullanarak hazırladığım print_utf8_text() fonksiyonudur. Böylece Türkçe karakterleri bastırmak da mümkün. OpenCV’nin putText() fonksiyonu sadece ASCII fontları destekliyor. Bu nedenle Türkçe karakterler basılamıyor.

Kodların içinde İngilizce açıklamalar kullandım. Çünkü bu seri tamamlandığında github üzerinden ve İngilizce olarak paylaşmayı düşünüyorum. İngilizce bilmeyen arkadaşlar zaten buradaki yazılardan aynı açıklamaları fazlasıyla edinebilecekler.

Gelelim kodlarımızın açıklamalarına:

Betiğimizde numpy ve cv2 yanında PIL kütüphanesini de kullanacağız. Böylece UTF-8 destekli FreeType fontları üzerinden Türkçe karakterli mesajları da basabileceğiz.

“haarcascade” dosyalarını “Cascades” isimli klasörün altında topladım. Bu betikte 4 farklı sınıflandırıcı kullanacağız. Sırasıyla yüz (cepheden), göz, gülümseme (dudak) ve burun.

“nocheck” değişkeni True olursa, fazladan göz, dudak ve burun kontrolü yapılmaması için it_contains_eyes() fonksiyonu işlem yapmadan True döndürerek devre dışı kalacaktır. Bu değer False olursa, ek kontrollerin yapılmasına izin veriliyor demektir.

OpenCV string basımı için putText() metodunu kullanıyor. Bu metodun kullanabildiği HERSHEY fontları sadece ASCII karakterleri destekliyor. Eğer sadece İngilizce veya ASCII karakterler içeren mesajlar kullanacaksanız print_text() fonksiyonu size yetecektir.

OpenCV doğrudan UTF-8 desteklemediği için Pillow kütüphanesini devreye sokarak FreeType fontlarını kullanabiliyoruz.
Örnekte ‘FreeSerif.ttf’ fontunu kullandım. Siz bir başka fontu tercih edebilirsiniz.
ImageFont.truetype() metodu ile font adını ve boyutunu belirliyoruz.
OpenCV ve Pillow farklı imaj sistemleri kullanıyor. Image.fromarray() metodunu kullanarak OpenCV formatlı imajı Pillow sistemine uygun biçime dönüştürüyoruz. Sonra da bu imajı bir Draw() nesnesi haline çevirip, text mesajımızı da bu nesnenin draw.text() metoduyla görüntünün üzerine işliyoruz.
Son aşamada işlenmiş görüntüyü yine bir numpy.array() biçimine dönüştürerek OpenCV’nin kullandığı formata aktarıyoruz. Fonksiyonumuz, üzerine text mesajı işlenmiş görüntüyü geri döndürüyor.

Eğer no_check değişkenimiz True değerine sahipse, it_contains_eys() fonksiyonumuz başka bir işlem yapmadan True değeri döndürür. Böylece ek kontrol yapılmaz.
Aksi halde önce roi_gray tanımlanır. Bu, “yüz” olarak tesbit edilen dikdörtgen yüzeydir.
İlk kontrol olarak bu alanın içindeki olası “göz”ler araştırılır. Parametreler deneyseldir. Çalışmanız için en uygun değerleri deneyerek bulmanız gerekebilir.
41-45 satırları arasında göz sayısını buluyor, bu sayı sıfırdan büyükse True değeri döndürerek geri dönüyoruz. Aynı satırları if len(eyes)>0: return True olarak kısaltmak da mümkün.
Diğer smiles (gülümseme-dudak) ve noses (burun) kontrolleri de aynı mantıkla çalışıyor.
Bu fonksiyonun temel amacı şudur: Bir yüzün içinde en azından 2 göz, bir dudak veya bir burun olmalıdır. Eğer hiçbiri yoksa, yüz hatalı saptanmıştır.

Ben bu betikte 3 ayrı imaj kullandım. İlk başta scaleFactor=1.5, minNeighbors=5, minSize(20,20) kullandım. Daha sonra deneme-yanılma yöntemiyle yukarıdaki değerlere ulaştım. Siz de deneyin.
Döngü içinde isimlerini verdiğim imaj dosyaları sırayla okunup image değişkenine atanıyor. Buradan da görüntünün gri bir kopyası oluşturuluyor. Gri görüntüler üzerinde sayısal işlem yapmak çok daha hızlı sonuçlar veriyor.
faceCascade.detectMultiScale(grayImage) metodu bize imaj içinde bulduğu yüz koordinatlarını veriyor (sol üst köşe x, sol üst köşe y, genişlik ve yükseklik). Konsol ekranına type(faces) değerini bastırıyoruz.

Eğer faces içinde hiç bilgi yoksa, görüntü üzerinde hiç yüz bulunamadı demektir. Bunu “Yüz bulunamadı” mesajıyla raporluyoruz.
Eğer faces içinde yüz koordinatları mevcutsa, -bilgi için- bulunan koordinatlar ile eleman boyutunu ve bu bilgiyi kullanarak ek filtre uygulanmamış yüz sayısını konsol ekranına bastırıyoruz.
Bulunan dikdörtgenlere it_contains_eyes() fonksiyonu ile ek denetimleri uyguluyoruz. Denetim atlanıyorsa veya aranan ek bilgiler bulunduysa o dikdörtgenin kenarlarını görüntünün üzerine çiziyor ve bulunan yüz sayısını tutan count değişkeninin değerini bir arttırıyoruz.
Tüm yüzler tarandıktan sonra “Belirlenen yüz sayısı: ” mesajımızın kolay görünebilir olması için altına beyaz bir zemin bastırıyoruz. (satır 88)
90-92 satırlarında bulunan yüz sayısını ifade eden mesajımız görüntünün üzerine işleniyor ve 94 numaralı satırda sonucu görüntülüyoruz.
Eğer UTF-8 yerine sadece ASCII fontlar kullanacaksanız 89 nolu satırı aktif hale getirip 90-92 satırlarını devre dışı bırakmanız yeterlidir.
Döngünün devam etmesi için herhangi bir tuşa basmamız gerek.
Tuşa bastığımızda ortalığı temizliyor ve varsa bir sonraki imaja geçiyoruz. Yeni imaj yoksa döngüyü ve betiği sonlandırıyoruz.

Tüm kodlar bir bütün olarak aşağıda:

Betiğin çalışmasını aşağıdaki videodan izleyebilirsiniz:

Bir sonraki yazımda kişi yüzlerini ismen tanıyan bir sistemi nasıl eğiteceğimizi ele alacağım.

Ahmet Aksoy

https://techtutorialsx.com/2017/05/02/python-opencv-face-detection-and-counting/
https://github.com/voidstellar/haar-cascade-files
https://github.com/opencv/opencv/tree/master/data/haarcascades
http://alereimondo.no-ip.org/OpenCV/34
https://www.instructables.com/id/Create-OpenCV-Image-Classifiers-Using-Python/
https://medium.com/@a5730051/train-dataset-to-xml-file-for-cascade-classifier-opencv-43a692b74bfe

Ara 032018
 
5.620 kez okundu

OpenCV ile Portakalın Peşinde

OpenCV ile Portakalın Peşinde

Bu yazımda bir önceki yazımda ele aldığım kodlardan yararlanacak, sadece bir kaç küçük değişiklik yapacağım.
Bu kez çember içine alarak işaretlediğimiz nesnenin (portakalın) merkez noktasını izlenebilir hale getireceğiz. İzlemeyi, en son ardışık 50 merkez noktasını çizgilerle birbirine birleştirerek yapacağız.

Bu betikte 2 kütüphaneye daha gereksinim var: collections ve numpy.

collections kütüphanesinin deque sınıfı her iki ucundan eleman eklenebilen ve önceden belirtilmişse maksimum eleman saısı sabit kalan nesneler üretir. Numpy kütüphanesini ise izleme çizgilerinin kalınlığını hesaplarken karekök almada kullanacağız. Onun yerine math kütüphanesini de kullanabilirdik ama, bu tür çalışmalarda numpy‘yi el altında tutmamızda büyük yarar var.

Bu kez kaynak kodları bir bütün halinde vereceğim. Sadece önceki örnekle karşılaştırdığımızda değişen satırları açıklamam yeterli olacak.

Kodlar aşağıda. Açıklamaları da onun altına ekledim.

3 ve 4 numaralı satırlarımızda yeni kütüphaneleri içe aktarıyoruz.

7. satırdaki WIDTH değerini 800 yaptım. Çünkü bu kez sadece bir pencereyi görselleştireceğiz.

8. satırda NO_OF_POINTS = 50 satırını ekledim. Bu sabit, merkez noktalarından kaç tanesini izleyeceğimizi belirliyor. Sayıyı azaltırsak izleme çizgilerimiz daha kısa, çoğaltırsak daha uzun olacaktır.

9. satırdaki ONLY_MAX artık kullanılmayacak. Çünkü sadece tek bir nesneyi (en büyük olanı) izleyeceğiz.

36. satıra kadar bir değişiklik yok. Burada frame isimli çerçevenin görüntüsünü cv2.GaussianBlur() metoduyla yumuşatıyoruz. Bu sayede görüntülerdeki renk dağılımları çok keskin hatlar oluşturmuyor. Aslında bizim örneğimizde bu metodu kullanmasak da olur.

46. satırda center değişkenini tanımlıyoruz. Bu değişken her görüntü karesinde yakalanan en büyük çemberin merkez noktasını tutacak.

49. satırdaki cmax değişeni en büyük alana sahip kontur değerlerini tutuyor.

51. satırda cmax’ı içine alan en küçük çembere ait merkez ve yarıçap bilgilerini buluyoruz.

52 ve 53. satırlarda şeklimizin ağırlık merkezini hesaplatıyoruz. Aslında bunun yerine center = (int(x),int(y)) kullansak da pek bir şey değişmeyecektir. Deneyebilirsiniz.

57-63 arası satırlarda yeni merkez noktamızı pts’ye ilk eleman olarak ekliyoruz. Böylece tüm elemanlar birer sıra sağ kayıyor ve en sondaki eleman siliniyor.

62. satırdaki thickness hesabı, çizgi kalınlığının, konumuna bağlı olarak değişmesini sağlıyor. Olayı basitleştirmek istersek onun yerine thickness=3 gibi bir satır kullanabiliriz. Elbette bu durumda çizgilerimizin kalınlığı sabit olur.

Son değişikliğimiz, 67.satırı devre dışı bırakmak. Böylece mask çerçevesini görünmez yapıyoruz.

Videoda kodların çalışır halini görebilirsiniz.

Bu yazıyı daha fazla uzatmayacağım. Çünkü ana fikirde bir önceki örneğimize göre önemli bir değişiklik yok. Ama istersek eğlenmek için bazı değişklikler yapabiliriz.

Örneğin ben cizgi kalınlıklarını biraz abartıp, rengini de kırmızı yaptım. Aşağıdaki videoda bu değişikliği görebilirsiniz. Siz de pts (deque) eleman sayısını azaltabilir veya çoğaltabilir, çizgi renkleriyle oynayabilirsiniz. Ya da renk aralıklarını değiştirerek farklı nesneleri izleyebilir veya web kamera yerine bir video dosyası kullanabilirsiniz (elinizde uygun bir video varsa).

Bir sonraki yazımda yüz tanıma konusunu yeniden ele alacağım.

Beni izlemeye devam edin.

Ahmet Aksoy

Ara 022018
 
5.350 kez okundu

OpenCV ile Portakallar ve Elmalar

OpenCV ile Portakallar ve Elmalar
Bu yazıda işleyeceğim kodların orijinal halini yine PyImageSearch sitesinde bulabilirsiniz. “ball tracking pyimagesearch” sözcüklerini Google’da aratırsanız, konuyla ilgili sayfalara kolayca ulaşırsınız.

Orijinal kodlarda izlediğimiz yuvarlağın (renkli topun) merkez noktasına ait koordinatlardaki değişimler görsel olarak izlenebiliyor. Benim aşağıda vereceğim kodlarda ise merkez noktası yerine, belirlediğimiz renk aralığının grileştirilerek maskelenmiş izdüşümünü ikinci çerçeveden izleyeceğiz.

(Not: Bir sonraki yazımda merkez noktalarının izlenmesi konusunu da ele alacağım. Ama dilerseniz bu kodları geliştirmeyi şimdiden bir ödev olarak üstlenebilirsiniz.)

OpenCV ile nesneleri izlemede kullanılan en basit yöntem, HSV renk sistemine uygun bir renk aralığını kullanmaktır. Çünkü HSV renk sistemi bu tür bir çalışmaya RGB veya BGR renk sistemlerine kıyasla çok daha yatkındır. Eğer renk sistemleriyle ilgili daha çok ayrıntıya ulaşmak isterseniz, internetteki pek çok kaynak size yardımcı olacaktır.

HSV terimi (Hue Saturation Value) sözcüklerinin ilk harflerini birleştirerek oluşturulmuştur. Hue renk tonlarını, saturation doygunluk oranını ve value parlaklık düzeyini ifade eder. OpenCV kütüphanesinde hue değerleri 0-179, diğerleri 0-255 arası değerler alır.

Şimdi kodlarımızı incelemeye başlayalım:

Örnek kodumuz için sadece cv2 ve imutils kütüphanelerini kullanacağız.

Web kamera görüntülerini kullanmak istiyorsak video_file string değeri boş olmalıdır. Eğer buraya bir video dosyasının erişim adresini yazarsak, web kamera yerine o videonun görüntüleri kullanılır.

WIDTH sabiti, pencerelerimizin genişliğini belirler. İstediğimiz gibi değiştirebiliriz.

ONLY_MAX sabiti False olarak tanımlanırsa, bulunan tüm sınır çizgileri (kontur) dikkate alınır. Bu değer True olarak verilirse, sadece alanı en büyük olan nesnenin çevre çizgisi çizilir.

Renk aralıkları için farklı opsiyonlar tanımladım. Kodu çalıştırmadan önce istediğiniz aralığı seçebilirsiniz. Örneğin YELLOW_RANGE aralığını kullanırsanız alt HSV değerler (10,100,100), üst değerler ise (40,255,255) olur.

video_file değişkenimizin uzunluğu sıfıra eşitse, içinde bir dosya adı yok demektir. Bu durumda web kamerayı etkinleştiriyoruz. İlk web kameranın karşılığı “0”dır. İkinci bir kamera tanımlarsanız, değeri “1” olur.

Örneğimizde yanyana 2 farklı pencere açacağız: frame ve mask. “mask” penceresi, “frame” penceresinin tam sağında yer alacak. Eğer bu yerleştirmeyi yapmazsak, pencereler üst üste açılacak; ikisini birden izleyebilmek için fare ile yerleşimi düzenlemek zorunda kalacaktık. (Not: cv2.moveWindow() parametreleri için kendi bilgisayarınızda biraz farklı değerler vermeniz gerekebilir.)

Ön tanımlarımızı yaptıktan ve pencere yerleşimlerini belirledikten sonra asıl işlemlerin içinde yer aldığı sonsuz döngüyü başlatıyoruz.

kamera.read() komutu, web kamera veya video dosyasından hangisini belirlediysek oradan bir çerçeveyi okuyor. Eğer ok değeri False ise ve dosya adı tanımlanmış ise okunacak çerçeve kalmadı demektir. Bu yüzden break komutuyla döngüyü sonlandırırız. Aksi halde işlenmesi gereken bir çerçeve okundu demektir.

Çerçeve boyutlarımızı WIDTH sabitine göre yeniden düzenledikten sonra frame isimli çerçevemizi HSV renk sistemine göre dönüştürüp, hsv isimli değişkene atarız. “frame” isimli çerçevemizin renk sistemi BGR’dir.

hsv isimli çerçeveden colorLower ve colorUpper renk değerlerine göre filtrelenen yeni çerçeveyi bu kez mask değişkenine atarız. Bu çerçeveye önce erode(), sonra da dilate() metodlarını uyguladıktan sonra bir de kopyasını alıp, çerçeve içinde yer alan nesne kenar çizgilerini (konturları) belirlemede kullanmak üzere mask_copy değişkenine atarız. (Not: erode() ve dilate() metodlarını kullanmadan önce mask çerçevemize GaussianBlur() metodu uygulayarak görüntüyü yumuşatmak daha güzel bir görsel etki yaratabilir. Bir sonraki yazımda bu metodu da örnekleyeceğim.)

contours listesi çerçevemizde yer alan tüm konturları içerir.

Eğer kontur listesi boş değilse, hepsini tek tek işleme sokarız.

ONLY_MAX sabitimiz True olarak tanımlandıysa her çerçevede sadece bir tek (en büyük) kontur belirlenir. Aksi halde yarıçapı 40 pikselden büyük olan tüm çemberleri kullanacağız demektir.

Konturlarımızı circle() metoduyla frame isimli çerçevemize işledikten sonra hem orijinal frame isimli çerçevemizi, hem de mask çerçevemizi görüntüleriz.

waitKey() metodumuz 4 milisaniyelik bir süre içinde basılacak tuşları dinler. Eğer ‘q’ veya ‘Esc’ tuşlarından birine basılmışsa, döngünün kırılmasını sağlar.

Döngü kırıldığında kamera nesnesini serbest bırakır ve açılmış tüm pencereleri kapatarak belleği temizleriz.

Örnek kodumuzun tamamı aşağıda:

Videoda kodların nasıl çalıştığı örnekleniyor. Tenis topu yerine elma ve portakal kullandım. Siz de isterseniz sarı renkler içeren başka nesneler kullanabilirsiniz.

mask çerçevesini görselleştirmek yerine sadece asıl çerçevedeki alanın veya alanların çember ile işaretlenmesini kullanabilir; ya da yakaladığımız nesnenin merkez koordinatlarındaki değişimi izlenebilir hale getirebiliriz.

Bu işlem için kendiniz doğrudan uğraşabilir ya da PyImageSearch sitesindeki örnekten veya benzer başka örneklerden yararlanabilirsiniz. (Bir sonraki yazımda bu konuyu ele alacağım.)

Yeni yazılarımdan anında haberdar olmak isterseniz sitemize abone olun.

Ahmet Aksoy

Eyl 212018
 
alice ekler
6.655 kez okundu



Python ile Türkçe Kelime Eklerinin Dağılımı

Türkçe “eklemeli” bir dildir. Bu nitelikteki diğer iki dil Macarca ve Moğolcadır.

Türkçede kullandığımız kelimeleri türeten eklerin konumlarını ve frekanslarını belirleyen bir çalışma yaptım.

Bu amaçla ekleri ayrıştırıp sınıflandırmak için Zemberek kütüphanesinden yararlandım.

Çalışmamın bir bölümünde derlem dosyasındaki kelimeleri kullandım.

Rekorumuz “ilişki” isminde.

Bu isme 10 ayrı ek ulanarak “ilişkilendirilemeyeceklerini” sözcüğünün oluştuğunu görüyoruz.

Daha fazla kök içeren başka kelimeler de bulunabilir. Ama bu tür örnekler büyük olasılıkla uygulanabilirlikten uzak olacaklardır.

Bu sözcüğün Zemberek ile elde ettiğimiz kırılım yapısı şu şekilde:
ilişkilendirilemeyeceklerini
ilişki ISIM_KOK 0
ilişki-le ISIM_DONUSUM_LE 1
ilişki-le-n FIIL_EDILGENSESLI_N 2
ilişki-le-n-dir FIIL_ETTIRGEN_TIR 3
ilişki-le-n-dir-il FIIL_EDILGEN_IL 4
ilişki-le-n-dir-il-e FIIL_YETERSIZLIK_E 5
ilişki-le-n-dir-il-e-me FIIL_OLUMSUZLUK_ME 6
ilişki-le-n-dir-il-e-me-yecek FIIL_DONUSUM_ECEK 7
ilişki-le-n-dir-il-e-me-yecek-ler ISIM_COGUL_LER 8
ilişki-le-n-dir-il-e-me-yecek-ler-in ISIM_TAMLAMA_IN 9
ilişki-le-n-dir-il-e-me-yecek-ler-in-i ISIM_BELIRTME_I 10

Aynı yöntemle alice.txt öyküsünü sözcüklerine, sözcükleri de eklerine ayrıştırdım ve konum frekanslarını saptadım.

Öyküde kullanılan kelimelerin ek kırılım tablosu aşağıdaki gibidir:

Şimdi toplam ek frekanslarını görselleştirelim:

Türkçe Kelime Eklerinin Dağılımı

Konum 0’daki ek sayısı, aslında hiç ek almayan kelime sayısına karşılık geliyor.
Sadece bir ek alan kelimelerin toplamı, 4545.
6 ek alan kelime ise öyküde sadece 1 kez kullanılmış:(alamadıklarından: al-a-ma-dık-lar-ın-dan)
5 ek alan kelimeler şunlar: (toplandıklarında, resimlerindekine, mırıldandığından, kestiremiyordu, götüremeyeceğini, olamayacağını, kullanmamalıydın, bahsedemezdiniz, kesilemezdi, dolamadığını, söyleyebileceklerimin, beceremiyormuşum)

Sınırlı sayıda kelime kökü (20 bin civarı) ile kısıtlı sayıda ekin (yaklaşık 100 civarı) kombinasyonu, Türkçenin zenginliğini oluşturuyor.

Siz de aşağıda verdiğim kodlardaki kaynak dosyayı değiştirerek benzer incelemeler yapabilirsiniz.

Beni izlemeye devam edin.

Ahmet Aksoy

Keywords: türkçe kökler, kelime kökleri, türkçe kelime ekleri, zemberek, python, türkçe, eklemeli dil

Eyl 162018
 
pösteki saymak
2.390 kez okundu

Pösteki Saymak

Sizce, tek bir Türkçe kelime kökünden yapım ve çekim ekleri kullanarak en fazla kaç kelime türetilebilir?

Tam 5081 kelime. Bu kelimelerin türetildiği kök: et.

Bu sayının büyüklüğünde aynı kökün hem yüklem hem de isim olması elbette etkilidir.

Yazının sonunda “et” kökünden türemiş sözcüklerin bazılarını vereceğim.(Hepsini vermek yazıyı gereksiz yere uzatacaktır.)

İkinci sıradaki çok kullanılan kökümüz “ol” yüklemidir. Ondan türeyen kelime sayısı: 3536.

Aşağıdaki grafikte en verimli 20 Türkçe kökü görüyorsunuz.

pösteki saymak

Sözcük türetmede kullanılan ekleri de benzer şekilde ayrıştırıp, frekanslarını buldum. En fazla kullanılan ilk iki ek “ler” ve “leri” ekleri. Onları “ları” ve “lar” izliyor. Onların peşinden gelenlerin çoğunluğunu yine çoğul eklerinin çeşitlemeleri oluşturuyor.

Sözcük türetiminde en fazla kullanılan ilk 20 eki de aşağıdaki grafikte görebilirsiniz:

pösteki saymak

Sözkonusu sayıları elde ederken bir milyon altı yüz altı bin yedi yüz yirmi iki (1,606,722) kelime içeren, kısmen denetlenmiş bir listeden yararlandım. Bu listeden çıkan tekil kök sayısı 20910. Tekil ek sayısı ise 77815.

Son günlerde Türkçe sözcüklerin kök ve eklerine ayrılması çalışmalarına yeniden yoğunlaştım. Bunda Yavuz Kömeçoğlu ve Birol Kuyumcu’nun yayınladığı örnek kodun büyük etkisi oldu: https://github.com/deeplearningturkiye/kelime_kok_ayirici
Seq2seq yöntemiyle çalışan bu kodlar 5572 kelime ve kökünü içeren bir verisetini eğitiyor ve test ediyor. Başarı oranı %97.

Aynı sistemi, kelime sayısını 42600 civarına çıkararak tekrarladım. Bu kez başarı oranı 93.6 oldu.

Parametrelerle oynayarak başarı oranı biraz daha yükseltilebilir sanırım. Ama her bir deneme GPU’lu bir makinede bile bazen saatler sürüyor.

Türkçe Doğal Dil İşleme (NLP) çalışmalarında kök ayırıcı olarak bu sistemden yararlanmak mümkün. Küçük hatalar bu tür çalışmalarda kolaylıkla hoş görülebilir.

Ancak, bu başarı düzeyleri beni bir türlü tatmin etmiyor. Çünkü ben, aslında, yazım hatalarını otomatik olarak -dışarıdan- denetleyen bir sistem geliştirme peşindeyim. Hedefim “SIFIR HATA”!

İşte burada yeni -ve çok daha basit- bir yöntem kullanmanın çok daha verimli olacağına inanıyorum: denetimden geçmiş, doğru ve güvenilir bir kelime listesi kullanmak.

Elimde iki milyona yakın sözcük barındıran ve kısmen denetlenmiş bir liste var. Bu haliyle bile oldukça iyi sonuçlar veriyor. (https://drive.google.com/drive/folders/0B_iRLUok9_qqOFozeHNFMjRHTVk adresinde paylaştığım derlem dosyalarından siz de böyle bir liste oluşturabilirsiniz.)

Aynı listeyi kök ayrımında kullanılacak şekilde geliştirmek de mümkün.

İşte bu tür çalışmaların hemen hepsi, “pösteki saymak” kavramıyla örtüşebilecek nitelikte… Çok fazla emek, sabır ve dikkat gerektiriyor. Üstelik bu çabanın “Türkçe dilgisi” ile de yoğrulmuş olması şart. Türkçe bilgime her ne kadar güveniyor olsam da, bu konunun akademik uzmanı değilim. Umuyorum ki, bir gün “bu işlerin uzmanları” da taşın altına elini koyar.

Çalışmalarımı -şimdilik- kendi kişisel emek ve bilgilerimi kullanarak gerçekleştiriyorum. “SIFIR HATA” hedefime ulaşana kadar da sürdüreceğim.

Liste (aslında sözlük) yöntemini kullanarak çözümlemeye çalıştığım kaynakların pek çoğu aşırı derecede kirli. Bu kaynakların pek çoğu tarayıcı kullanılarak sayısallaştırılmış. Bu sırada, uygulamalardaki Türkçe uyum sorunları nedeniyle pek çok yazım hatası oluşmuş. İnsan beyni bu tür hataları kolaylıkla tolere edebilse de, temiz ve güvenilir bilgi derleme açısından işler büyük ölçüde zorlaşıyor.

Bir kaç kez gönüllü ekip oluşturmayı denedik, ama sonuç alamadık.

Şimdi, yaptığım çalışmalardan elde ettiğim sonuçları -veya bir kısmını- kaynaklara ekleyerek – bir tür forward propagation ve backward propagation yöntemiyle- daha sağlıklı sonuçlar elde etmeye çalışıyorum. İşin içine insan emeği girince, çalışmalar yavaşlıyor ister istemez. Ama sonuçtan memnunum.

Kelimeleri ayrıştırıp görselleştirdiğim Python kodları şöyle:

Bunlar da “et” sözcüğünden türetme yapan eklerden bazıları:
et
edebildi
edebildik
edebildikleri
edebildikleridir
edebildiklerim
edebildiklerimden
edebildiklerime
edebildiklerimi
edebildiklerimiz
edebildiklerimizden
edebildiklerimizdi
edebildiklerimize
edebildiklerimizi
edebildiklerimizin
edebildiklerince
edebildiklerinde
edebildiklerinden
edebildiklerine
edebildiklerini
edebildiklerinin
edebildikleriydi
edebildikleriyle
edebildikse
edebildikten
edebildiler
edebildilerse
edebildim
edebildin
edebildiniz
edebildiydi
edebildiyse
edebildiysek
edebildiysem
edebildiysen
edebildiyseniz

Liste uzayıp gidiyor…

Çalışmalarımın gelişimini ve aldığım sonuçları bu sayfalarda yeri geldikçe paylaşmaya devam edeceğim.
Yeni yazılarımdan haberdar olmak istiyorsanız, Sayfanın en altındaki “Beni yeni yazılarda e-posta ile bilgilendir” seçeneğini işaretleyin.

Ahmet Aksoy

Ağu 102018
 
2.215 kez okundu

Kaçıncı Yeni

Kaçıncı Yeni

1950’li yıllarda edebiyat sahnesine giren “2. Yeni” şiir akımı, bir tepkiyi dile getiriyordu. Bu tepki, Varlık Dergisi etrafında Orhan Veli ve arkadaşlarının başlattığı Garip akımına karşıydı. Eş zamanlı olarak, 2. Dünya Savaşının tetiklediği bunalım ortamlarından filizlenen dadaizm ve varoluşçuluk gibi akımlardan esinlendi.

Bu akımın önde gelen isimleri Cemal Süreya, İlhan Berk, Edip Cansever, Ece Ayhan, Turgut Uyar, Ülkü Tamer ve Sezai Karakoç gibi isimlerdi.

İkinci yenicilerin sloganı “şiir için şiir”dir. Onlar için söz sanatları, kelime oyunları ve hayal dünyası ön plandadır. Bu yüzden mesajlarını doğrudan doğruya vermek yerine imgeleri ve metaforları kullanmayı tercih ettiler.

Bazı 2. yeni şiirleri peşpeşe dizilmiş, ilgisiz sözcüklerden oluşan anlamsız bir biçim gibi görünür. Cümleler belirsiz veya devriktir. Hatta hiç cümle yoktur.

İşte Ece Ayhan’dan birkaç dize:

geçer sokaktan bakışsız bir
Kedi Kara.
Çuvalında yeni ölmüş bir çocuk.
Kanatları sığmamış.
Bağırır Eskici Dede.
Bir korsan gemisi! girmiş körfeze

Biraz kargalarlı, aykırı düşüncelerdir.

Peki bunları niye anlatıyorum?

Çünkü, Tensorflow ile “Char-RNN” yöntemini kullanarak oluşturduğum örnekler bir bakıma bu “2. Yeni” şiirlerine benziyor.
Ancak bu sonucu yaratan baş etmen, sistemi eğitmek amacıyla kullandığım veri kümesinin yeterli büyüklüğe sahip olmayışıdır.
Bir diğer etken ise verilerin içinde yer alan dizim hatalarıdır. Bu durumu ne yazık ki sonradan farkettim. Bütün dizeleri tek tek gözden geçirip düzeltmeye çalışmak, olağanüstü bir çaba ve zaman gerektiriyor.

Yine de, durumu biraz olsun hafifletmek amacıyla “geçersiz sözcük barındıran dizeleri” silen bir süzgeç kullandım. Bu sayede elde ettiğim tüm dizeler, tamamiyle geçerli Türkçe sözcüklerden oluşmaktadır.

İşte benim haylaz öğrencinin dile getirdiği bazı dizeler:

Ne herşey evleri
kağıttan görüyorum
Mutlaka kalacaktı bana inat
İstememiş, sokaklarımız

Kan deniz öyle biri
Anlama gittiğimiz yok
Ben ayı açık sızlar,
umuttan ömrümüz

Kaygılar her şeyleri yerinde

Yağmurları sis böyle düştüm
perde, ilk zamanmış bütün
Ve bu zaman bir güllerden
Aşktı
Acısıyla kaybettiğim karanlıkta

Sonuçların ileride daha fazla anlamsal bütünlük kazanacağını umuyorum. Bunu sağlamak için, öncelikle eğittiğim veri kümesini daha büyük boyutlu ve sorunsuz dizelerden oluşan bir yapıya kavuşturmam gerek. Bu da uzunca bir zamana ihtiyaç duyacak.
Şimdilik, geçici bir yöntem olarak, elde ettiğim ayıklanmış dizeleri mevcut veri kümesine ekleyip, yeniden eğitiyorum. Bu tekrarların ne kadar yarar sağlayacağını zaman gösterecek. Sonuçları yine burada, sizlerle paylaşacağım.

Veri kümesini eğitmek için kullandığım Python kodlarını daha önce paylaşmıştım: http://python.gurmezin.com/tensorflow-ile-acemi-siirler/. Orijinal kodlara, https://github.com/sherjilozair/char-rnn-tensorflow adresinden ulaşabilirsiniz.

Bu çalışmada Python 3.6.5 kullandım. Tensorflow sürümü 1.5.0. 6GB belleği olan GPU ile eğitim işlemi yaklaşık 15 dakika sürüyor.

Veri kümesini internet üzerinden rasgele derlediğim için, şimdilik paylaşmam mümkün değil. İleride, paylaşılabilecek bir veri kümesi oluşturma şansı elde edersem, elbette o veri kümesini sizlerle de paylaşacağım.

Soru, öneri ve eleştirileriniz için yorum alanını kullanabilirsiniz.

Tekrar görüşmek üzere,

Ahmet Aksoy

Oca 172018
 
4.835 kez okundu

Tensorflow ile Acemi Şiirler

Bu yazımda internet üzerinden rasgele derlenmiş şiirler kullanarak eğittiğim sistemden aldığım -şiirimsi- çıktıları paylaşacağım.

şiirimsi tensorflow

Henüz abartılı bir sonuç beklemeyin. Nasıl ki bir bebeğin konuşmayı öğrenmesi için belli bir zamana ihtiyacı varsa, makine öğrenmesi sistemlerinin de öğrenmek için zamana ve çabaya ihtiyacı var.

Bu çalışmada Kullandığım veri seti internet üzerinden rasgele toplanmış yaklaşık 70 bin dize içeriyor. Bu veri özel bir denetimden geçmedi. Şair veya biçem konusunda herhangi bir ayrım uygulanmadı. Tek kaygı, dişe dokunur sonuçlar elde edebilmek için veri boyutunun en az 1 milyon karakter olması gereğiydi. (Bu bir kural olmasa da, bir çok uzmanın önerisi bu yönde.) Kullandığım veri setinin boyutu yaklaşık 2MB.

Program, Tensorflow kütüphanesiyle karakter düzeyli RNN (Recurrent Neural Network) eğitimi yapıyor.

Raspberry Pi 3 üzerinde Tensorflow kurulumunu “Raspberry Pi ile Tensorflow 2” başlıklı yazımda ele almıştım. Tensorflow 1.1.0, Python 3.4 üzerinde sorunsuz bir şekilde çalışıyor. (Halen en son Tensorflow sürüm numarası 1.5)

Eğitim çalışmasında Sherjil Ozair’in github deposundaki kodlarını kullandım: https://github.com/sherjilozair/char-rnn-tensorflow

Eğitim için Python 2 veya Python 3 kullanmak mümkün. Ancak Tensorflow sürümü en az 1.0 olmalıdır.

EĞİTİM İŞLEMLERİ

Eğitim işlemi

komutuyla yapılıyor. Eğer herhangi bir parametre vermezseniz, otomatik olarak “Tiny Shakespeare” verisi kullanılıyor. İsterseniz, internet üzerinden başka veri setleri de bulup indirebilirsiniz.

Sanal ortam üzerindeki kendi eğitim çalışmamda şu kodları kullandım:

Tensorflow

Her batch işlemi yaklaşık .25 saniye tutuyor. Toplam 40050 batch olduğuna göre yaklaşık 10 bin saniyelik bir eğitim süresi olacak. Yani 3 saate yakın bir süre.

Bilgisayarım 4 çekirdekli bir i5. Ancak tam yükte aşırı ısındığından, çökmemesi için işlemcileri 2.53GHz yerine 2.40GHz hızla çalıştırabiliyorum. Aynı işlemler Raspberry Pi 3 üzerinde 8 kat daha fazla bir zamana ihtiyaç duyuyor. Bu yüzden tek bir Raspberry Pi ile bu tür bir eğitim yapmak pek de verimli değil.

Ancak, bir başka bilgisayarda eğitilmiş veri setini Raspi’ye aktarıp, kullanabilirsiniz. Ben de bu yöntemi tercih ediyorum.

SONUÇLAR

Eğitilmiş bir veri setini kullanarak sonuç elde etmek için verilecek komut şu:

Yukarıdaki komuttan da anlaşılacağı gibi, eğitilmiş veri “save/siirler” klasöründe bulunuyor.

Dizüstü bilgisayarımda eğittiğim veriyi Raspberry Pi 3 üzerine “rsync” komutu ile çektim ve raporladım:

Raspberry Pi 3 üzerinde rapor alma işlemi bile yaklaşık 30 saniye sürüyor.

Bir örnek daha:

Çok daha büyük bir veri seti ve -tercihen- GPU kullanabilen bir bilgisayarda eğitilmiş veri setleriyle çok daha anlamlı sonuçlar elde etmek mümkün olabilir.

Eğer güçlü bir bilgisayara sahipseniz veya sabırlı biriyseniz siz de kendi veri kümelerinizi eğitebilirsiniz.

Ahmet Aksoy

Referanslar:

Oca 162018
 
2.222 kez okundu

Raspberry Pi Maceralarım No-09

Raspberry Pi 3 GPIO ile Bir Ledin Parlaklığını ve Frekansını Kontrol etmek

Önceki yazımda “İki Yönde Yürüyen ışık” örneğini vermiştim. Bu kez bir LED’in parlaklığını ve yanıp sönme frekansını denetleyeceğiz.

Yazının sonunda linkini verdiğim videda konu ile ilgili ayrıntılar mevcut. O yüzden burada sadece kodları ve devre şemasını vermekle yetineceğim.

Raspberry Pi Maceralarım No-09

Kodlar hem Python 2, hem de Python 3 ile uyumludur.
Parlaklık ve frekansı GPIO’nun 12 nolu iğnesinin PWM (Pulse Wave Modulation) özelliğini kullanarak kontrol ediyoruz.

Program kodlarını, devre montajını ve örneğin çalışmasını gösteren videomuz aşağıda.

GPIO ile ilgili örneklerimi burada sonlandırıyorum.

Bir sonraki yazımda yeni bir Tensorflow örneğini ele alacağım.

Beni izlemeye devam edin.

Ahmet Aksoy

Raspberry Pi Maceralarım No-09

Ara 162017
 
Raspberry Pi ve Makine Öğrenmesi
3.510 kez okundu

Raspberry Pi ve Makine Öğrenmesi

Yeni bir startup olan Jetpac, görsel tanıma yazılımı Deepbelief’i farklı sistem ve cihazlar üzerinde kolayca kurulup kullanılabilir hale getirdi. Bu girişim, Raspberry Pi ve Makine Öğrenmesi açısından da önemli bir kazanım olacak gibi görünüyor.

DeepBelief sistemini Linux, iOS, OSX, Android, Raspberry Pi ve Javascript üzerinde kullanmak mümkün.

Bu yazımda DeepBelief’in Raspberry Pi üzerinde kurulumunu ve çalıştırılmasını ele alacağım.

Aynı konu http://www.instructables.com/id/Machine-learning-with-Raspberry-Pi/ adresinde işlenmiş. Ancak orada verilen direktifler benim kullandığım Raspberry Pi B+ v1.2 üzerinde biraz sorun yarattı. Ama bu sorunun çözümü de var.

Şimdi en başından başlayarak aşamalar halinde işlemlerimize geçelim:

1. Önce Raspi’ye bağlanalım: (Ben Ubuntu 16.04 üzerinde ssh komutuyla bağlanıyorum. Siz de kendi sisteminizin gerektirdiği şekilde veya cihazınıza klavye, fare ve ekran bağlayarak çalışabilirsiniz.)

Uzaktan bağlanabilmek için Raspinin IP numarasını bilmeniz gerekir. Bu amaçla

komutunu kullanabilirsiniz. sudo kullanırsanız, root yetkisiyle daha ayrıntılı bir rapor alırsınız.

2. GPU kullanımı için bellek tanımlama:

Dosyanın sonuna aşağıdaki satırı ekleyelim:

3. Bellekte yaptığımız değişikliğin sistem tarafından algılanması için cihazımızı yeniden başlatalım:

4. Raspinin kendini yeniden başlatması birkaç dakika sürebilir. Yeteri kadar bekledikten sonra yeniden bağlanalım.

5. Dosyalarımızı github üzerinden indireceğimiz için git uygulamasını kurmamız gerekiyor.

6. Artık DeepBeliefSDK dosyalarını indirip kurulumunu yapabiliriz.

7. Kurulumu yaptık. Sonucu denetlemek için örnek uygulamayı çalıştıralım:

Eğer herşey yolunda gittiyse 998 satırlık bir rapor elde edeceksiniz.

Ya da benim gibi “Can’t open device file: /var/lib/jpcnn/char_dev” mesajını alacaksınız. Bu hata mesajından kurtulmak için aşağıdaki komutları verin:

Artık uygulamamızı yeniden çalıştırabiliriz:

Elde edeceğimiz rapor resimdekine benzeyecektir.

Raspberry Pi ve Makine Öğrenmesi

deepbelief uygulaması, herhangi bir parametre verilmeden çalıştırıldığı zaman “lena.png” dosyasını varsayılan olarak yükler ve öntanımlı imagenet nesneleriyle karşılaştırarak benzerlik oranlarını bulur.

Raporda sıra no, benzerlik olasılığı ve nesne etiketi sıralanır.
En büyük olasılığa sahip olan görüntülerle eşleşme gerçekleşmiştir diyebiliriz.
Eğer sonuçları olasılık değerine göre sıralarsak, benzerlikleri yorumlamamız daha kolay olur.

İstediğiniz bir başka görseli taratmak isterseniz, adını parametre olarak vermek gerekir. Örneğin “cicek.jpg” dosyasını taratmak istediğimizde vereceğimiz komut şöyledir:

DeepBelief sistemini Ubuntu üzerinde kurmak çok daha kolay oluyor. Siz de kendi sisteminizde deneyin.

Ahmet Aksoy

Referanslar:

Ara 112017
 
2.385 kez okundu

Bottle Örnek Yapılacaklar Listesi

Önceki yazımda Python Bottle Mikro Ağ-Çerçevesi konusunu kısaca ele almıştım.

Bu yazımda ise https://bottlepy.org sitesindeki örneği, bazı mesajlarını Türkçeleştirerek aktaracağım.

bottle örnek yapılacaklar listesi

İlk çalışmamda edit, save, new gibi terimleri de Türkçeleştirmiştim. Ama sonra Python programcılarının ister istemez teknik İngilizce terimleri bilmeleri gerektiğini düşünerek sadece bazı mesajları Türkçeleştirmekle yetindim.

Orijinal kod listesinde eksik bırakılan help.html dosyasını ekledim ve içine kısaca bottle projesi çalışırken kullanılacak terimlerin işlevini basit bir tablo olarak ilave ettim.

Örijinal kodlarda static_file(‘help.html’, root=’.’) satırında bulunması gereken return anahtar sözcüğü unutulmuştu. Onu da ekledim.

Uygulama, basit “Yapılacaklar Listesi” için gereken işlevlere sahip. Veritabanı olarak SQLite3 kullanıyor.

Düzenlemeleri yaparken Pycharm Community Edition sürümünü kullandım. Python sürümü 3.6.3 ve bottle sürümü 0.12.13.

Pycharm ile “bottle” isimli yeni bir proje klasörü tanımladım.

İlk aşamada veritabanını oluşturmalıyız. Sitede verilen kod satırlarını biraz revize edip veritabani.py dosyasına kaydettim. Bu betik veritabanını oluşturmak amacıyla sadece bir kez çalıştırılacak.

Sistemde ana kod dosyamız dışında help.html isimli bir yardım dosyamız, 3 tane de şablon (template) dosyamız bulunuyor. (SQLite3 veritabanı dosyası todo.db de aynı klasörde.)

Önce html ve şablon dosyaların içeriğini aktarayım:

help.html dosyası

make_table.tpl şablon dosyası

edit_task.tpl şablon dosyası

new_task.tpl şablon dosyası

Son olarak Python kod dosyası todo.py

Dosyalarımızın hepsi bottle proje klasörünün içinde yer alıyor.

Kodların, ek açıklamaya gerek duymayacak kadar açık olduğunu düşünüyorum. Arada bir kaç satırlık açıklama da var zaten.

Yine de sormak istedikleriniz olursa, yorum alanını kullanabilirsiniz.

Ahmet Aksoy

Bottle Örnek Yapılacaklar Listesi


Referanslar: