iOS Geliştiriciler için Makine Öğrenmesi 1.Bölüm: CreateML ile Görüntü Sınıflandırma


Bu yazıyla beraber iOS platformunda akıllı uygulamalar geliştirebilmek için gereken her şeyi bulabileceğiniz bir yazı dizisi hazırlamaya başlıyorum. Hedefim bu rehberin mobilde (özellikle iOS) uygulamalı makine öğrenmesi alanında Türkçe içerik olarak en kapsamlı yol gösterici olması. Bu yolculuk boyunca bu alandaki son teknoloji araçları incelemekle kalmayıp uygulamaya geçeceğiz. Yolculuk sonunda istediğiniz yapay zeka destekli mobil uygulamayı gerçekleştirmek için tam donanımlı bir geliştirici (armed with Apple ML Tools) haline gelmenizi hedefliyorum. Yazı dizisi ilk yazılarda üst seviye araçlardan başlayacak ve sona doğru en alt detaylara ineceğiz.

Makine Öğrenmesi Araçlarına Giriş

Makine öğrenmesiyle daha önceden ilgilenmediyseniz şu yazıma bir göz atmanızı tavsiye ederim: Makine Öğrenmesi Eğlencelidir!

Öncelikle Apple’ın sunduğu makine öğrenmesi araçlarının tarihine kısaca göz atalım. Bilindiği üzere Apple geliştirici konferansı WWDC etkinliklerinde her sene yeni araçlarını ve kütüphanelerini tanıtıyor. Apple 2017'de CoreML kütüphanesini tanıttı. CoreML ile birlikte önceden hazırlanmış makine öğrenmesi modellerini uygulamalarımıza entegre edebilir hale geldik. Ayrıca sunulan CoreMLTools isimli Python kütüphanesi; Keras, Caffe ve scikit-learn gibi popüler kütüphanelerde eğitilen derin öğrenme modellerini CoreML’e çevirerek kullanabilmemizi sağladı. CoreMLTools kullanmak için temel Python bilgisi gerektiğinden geliştiriciler için ufak bir öğrenme bariyeri yaratıyordu. Apple, WWDC 2018'de CreateML tanıttı ve artık basit şekilde yazı ve görüntü sınıflandırıcı eğitmek için hiçbir engel kalmadı. CreateML ile uçtan uca tüm model oluşturma sürecinin Swift ve Xcode ile yapılabilmesi sağlandı.

https://developer.apple.com/documentation/createml

CreateML ile kolayca istediğiniz görüntüler için derin öğrenme modeli eğitebilir ve sınıflandırma yapabilirsiniz. Diyelim ki Silikon Vadisi dizisindeki gibi resim hotdog resmi mi değil mi tespit edebilmek istiyorsunuz. CreateML üzerinde bu resimleri tanıyabilmesi için birçok örnek resimle modelinizi eğitebilir ve daha önceden görmediği resimlerle test edip modelinizin başarısını ölçebilirsiniz. Modelinizin yeterince iyi çalıştığına karar verdiğinizde bir sürükle bırakla projenize dahil edebilirsiniz.

https://developer.apple.com/documentation/createml

CreateML; Siri ve Fotoğraflar uygulamalarında da kullanılan iOS’in içinde hazır bulunan makine öğrenmesi altyapısını kullanmaktadır, bu sayede modeller daha hızlı eğitilmekte ve de daha az yer kaplamaktadır (transfer-learning).

Bu hızlı yöntemin literatürdeki adı öğrenim transferidir. Bu yöntem normalde haftalar sürebilecek bütün ağ modelini eğitmek yerine, daha önceden farklı bir resim veri kümesinde eğitilmiş bir modelin ağırlıklarını kullanır ve sadece son katmanı eğitir. Bu şekilde hem öğrenilmiş sınıflandırma özelliklerinden faydalanır hem de daha hızlı eğitim sağlar.

Mesela meşhur ImageNet resim sınıflandırma yarışmasında evrişimli sinir ağları bin sınıfı sınıflandırmayı öğrenmektedir. Öğrenim transferinin mantığı; aslanları ve maymunları ayırt etmeyi öğrenen bir ağın öğrendiği özniteliklerin, kedi ve köpek resimlerini ayırt etmekte de fayda sağlayacağı düşüncesine dayanmaktadır.

Apple bu son katman harici model yapısını iOS’un içinde gömülü olarak yayınladığı için bu yapı ortak kullanılabilmekte ve yeni eğitilen modeller diskte çok daha az yer kaplamaktadır.

Uygulamaya Geçelim

Bu kadar bilgi yeter artık biraz elimizi kirletelim:)

CreateML ile eğitim yapmak için Playground’u kullanıyoruz. Boş bir MacOS Playground’u oluşturalım.

Aşağıdaki gibi CreateMLUI’ı import edelim ve bir resim sınıflandırıcı oluşturalım.

Soldaki mavi play butonuna basarak (kısayol: shift+command+enter) Playground’u çalıştıralım.

Resimleri sürükleyeceğimiz alanı görmek için View->Assistant Editor->Show Assistant Editor’e (kısayol: alt+command+enter) tıklayalım. Sağ tarafta aşağıdaki gibi bir bölüm oluşacaktır.

ImageClassifier’ın yanındaki oka tıklayarak ayarlarına bir göz atalım. Burada model eğitiminin kaç devirde yapılacağını belirleyebiliyor ve direk eğitim ve validasyon klasörlerimizi seçebiliyoruz.

Augmentation ise resimlerimizden sentetik verilerin üretilmesini sağlıyor. Bu sayede döndürme, kırpma, bulanıklaştırma vb. gibi görüntü işlemleri uygulanarak resim çeşitliliği ve dolayısıyla kapsadığımız olası resim uzayı artmış oluyor. Aşağıda Apple’ın örnek resim manipülasyonlarını görebilirsiniz.

https://developer.apple.com/documentation/createml/improving_your_model_s_accuracy

Bu örnekte; elimde hazır banknot resimleri bulunduğu için banknot tanıma uygulaması yapacağım. CreateML’i eğitmek için resimlerinizi kategorilere ayırmanız gerekiyor. Bunun için iki yöntem var. Birincisi; resimleri aşağıdaki gibi klasörlere ayırmak.

İkincisi ise dosya isimlerini aşağıdaki gibi kategorilere göre düzenlemek.

Hızlı bir eğitim için küçük bir veri kümesiyle çalışıyorum. Veri kümemde her klasörde 120 olmak üzere toplamda 720 resim var. Daha sağlıklı eğitim için resim sayısının çok daha fazla olması gerekir. Ayrıca olabildiğince farklı durumlardaki resimleri (farklı açılar, ışıklandırmalar, uzaklıklar vb.) eşit sayılarda veri kümesinde bulundurmak da çok önemlidir. Modeli eğitmek için eğitim resimlerinin bulunduğu klasörü sürükleyip bırakıyorum. Öznitelik çıkarım işlemi (feature extraction) direkt başlıyor.

Eğitim süreci şu şekilde; öncelikle iOS ile birlikte gelen derin evrişimsel sinir ağı kullanılarak tüm resim kümesinin öznitelikleri çıkartılıyor. Öznitelik çıkarımı devam ederken sol altta işlenen resim sayısı, geçen süre vb. bilgileri takip edebiliyoruz.

720 resim için özellik çıkarımı 2 dakika 51 saniye sürdü ( mid2012 macbookPro).

Arkada Nasıl Bir Teknoloji Var?

Apple’ın Vision kütüphanesinin arkasında yatan derin öğrenme modeli VisionFeaturePrint_Screen birçok resim türünü tanımak üzere büyük bir veri kümesinde eğitilmiş. CreateML daha önceden eğitilmiş bu derin öğrenme modeli kullanarak öğrenim transferi yönteminden faydalanıyor. Derin öğrenmede kullanılan metodolojiyi anlamak için Ayyüce Kızrak’ın DERİNE DAHA DERİNE: Evrişimli Sinir Ağları yazısını okuyabilirsiniz. Apple da burada öznitelikleri çıkartırken bir evrişimli sinir ağı kullanıyor. Bu model resimleri sınıflandırmak için hangi özniteliklere bakması gerektiğini ve bunları nasıl birleştirmesi gerektiğini biliyor. Eğitim sürecinde bu model sizin veri kümeniz üzerinde kullanılarak resimlerin 2048 özniteliğini çıkarıyor. Resimlerdeki bu öznitelikler alt seviye genel şekiller, desenler olabileceği gibi; kulaklar, gözler arası uzaklık gibi üst seviye öznitelikler de olabilir. Çıkartılan öznitelikler üzerinde yapısal bağıntı (logistic regression) eğitimi yapılıyor, bu eğitim öznitelik çıkarımından daha kısa sürüyor.

Bu işlem bittikten sonra CreateML veri kümesi içerisinden %5 oranında rastgele veri alarak validasyon kümesini oluşturuyor. Az önce çıkartılan resim öznitelikleri kullanılarak eğitim başlıyor. Bu eğitim çok hızlı bir şekilde (1.34 saniye) tamamlanıyor. Eğitim verisi üzerindeki başarım %84 iken, rastgele seçilen validasyon kümesi üzerinde %80.

Modeli Test Edelim

Şimdi eğitilen modeli daha önceden görmediği resimlerle test edeceğim. Bu işlem için test resimlerimin bulunduğu klasörü sürükleyip bırakıyorum. Test resimleri de klasörlenmiş halde olmalı çünkü doğru tahminleyip tahminlemediğini bu klasörlerden anlıyor.

Doğru sınıflandırılan ve yanlış sınıflandırılan resimleri direkt aşağıdaki gibi görebiliyoruz.

Sol altta ise karmaşıklık matrisini (confusion matrix) görebilirsiniz. Sol kolon ve üst başlıklar sınıflarınıza karşılık gelir. Test verisi üzerindeki resimlerinizden kaçı doğru sınıflandırılmış kaçı yanlış sınıflara gitmiş buradan görebilirsiniz. Görüldüğü üzere 18 doğru tahminle en az başarılı olduğumuz sınıf 100TL resimleri. 100'ü en çok 200'e benzetmiş.

Precision ve recall metrikleri her bir kategori için hesaplanmaktadır. Precision değeri modelin belirli bir kategoriyi etiketlerken ne kadar etkili olduğunu gösterirken(daha az false positive), recall değeri o kategoriyle ilişkili resimleri bulurken ne kadar etkili olduğunu gösterir (daha az false negative). Buradaki hesaplamalar modelin test resimleri üzerinde tahmin başarılarını göstermektedir. Bu değerler her bir kategori için hesaplanarak ortalamaları alınmaktadır. Değerlerin karşılıkları şu şekilde:

  • True positive: model para resmini X kategorisinde olarak tahmin etti ve gerçekten de X kategorisinde.
  • False positive: bu para X kategorisinde diye tahmin etti ama aslında Y kategorisinde
  • False negative: bu para X degil dedi ama o aslında X kategorisinde
https://developer.apple.com/documentation/createml/mlclassifiermetrics/3005453-precisionrecall

Eğitim başarımını artırmak için veri sayısını arttırabilir veya sentetik veri üretiminden faydalanabiliriz. Bu yazı için bu modelle devam edelim. Modelin adının üstüne tıklayarak modelin adını değiştirelim.

Modeli Projede Kullanalım

Apple’ın CoreML ile resim sınıflandırmak için örnek projesini indirelim. Bu projede hali hazırda resim sınıflandıran bir model mevcut bu modeli (Mobilenet.mlmodel) kaldıralım ve kendi modelimiz sürükleyip bırakalım.

Sürüklediğimiz modele tıklayarak modelin detaylarını görebiliriz. Gördüğünüz üzere model çok küçük bir yer kaplıyor, sadece 83kb. Resnet gibi bir modeli tekrar eğitip kullansaydık yaklaşık 94 mb’lık bir modelimiz olacaktı. Modelimiz 299x299 boyutunda resimler alıyor ve sonuç olarak her bir kategori için olasılığı dönen bir dictionary (classLabelProps) ve en olası sınıfı (classLabel) text olarak dönüyor.

Modelimizi kullanabilmek için birkaç değişiklik yapmamız gerekiyor. ImageClassificationViewController.swift dosyasını açalım ve ‘MobileNet’ yazısını aratarak önceki modelin çağrıldığı yeri bulalım ve buraya kendi modelimizin adını (MoneyClassifier) yazalım. Burada model sınıfımıza ulaşabiliyoruz, çünkü Core ML modelimize erişebilmemiz için otomatik olarak modelimize ait Swift sınıfını oluşturuyor.

Artık projeyi çalıştırıp cihazda test edebiliriz. Çalıştırırken ‘development team’ seçilmediğinden hata verebiliyor bu durumda projeye tıklayarak targets bölümünden team seçerek devam edelim. Çalıştırıp fotoğraf çekip test edelim. Sol alt bölümde en olası iki sınıf için tahmin olasılıklarını görebiliriz.

ImageClassificationViewController.swift dosyasına geri dönüp proje içeriğini inceleyelim. Aşağıdaki bölümde, CoreML modeline bir resim analizi çağrısı yapmak için bir VisionCoreMLRequesti (VNCoreMLRequest) oluşturuluyor. Lazy olarak oluşturulmasının sebebi bu nesnenin kullanımına ihtiyaç olduğu anda oluşturulmasını sağlamaktır.

Yukarıda görüldüğü üzere VnCoreMLRequest çağrısından dönüş sağlandığında processClassifications metodu çağrılmaktadır. Model çalıştırılıp sonuç döndüğünde sonuçlar bu metoda geçirilmektedir.

Bu ML modeli input olarak belirli bir en-boy oranında resimler bekliyor ama çekilen veya yüklenen resimler farklı en-boy oranında olabilir. Burada Vision kütüphanesi resmi ölçeklendirmek ve kırpmak için çeşitli seçenekler sunuyor. Apple en iyi sonuçlar için eğitimde kullanılan oranların aynısının kullanılmasını tavsiye ediyor. VNImageCropAndScaleOption.centerCrop resmin kısa kenarına denk gelicek şekilde en boy oranını korur ve buna göre kareyi ortalayarak resmi kırpar.

https://github.com/bumptech/glide/issues/613

Yukarıda göründüğü gibi resim yüklendiğinde ise updateClassifications metodu çağrılmaktadır. Bu metottaVNImageRequestHandler objesi oluşturulur. Bu obje bir resme ilişkin resim analizlerini yönetir. Parametre olarak işlenecek resmi ve resmin oryantasyonunu alır. Daha sonra bu objenin perform(_:) metodu çağrılarak Vision requesti sıraya sokulur. Bu metot senkronize bi şekilde çalışır bundan dolayı ana kuyruğu (main queue) bloklamamak için arkaplan kuyruğu (background queue) kullanılması tavsiye edilir. DispatchQueue kuyrukların yönetimini ve senkron veya asenkron çağrı yapabilmeyi sağlar.

Model her çalıştığında çağrılan processClassifications metodu ise aşağıdaki gibidir. Ekranı kilitlememek için işlemler asenkron olarak yapılmaktadır. Model çalıştığında dönen VNRequest’in içinde results dizisi bulunmaktadır. Bu dizide resmin tahmin sonuçları yer almaktadır. Her bir sınıf olasılıklarına göre azalan şekilde sıralanmıştır yani en emin olunan sınıf en üsttedir. Burada prefix metoduyla olasılığı en yüksek iki sınıf alınarak bunlar ekranda gösterilmektedir.

Bu seferlik bu kadar, dizinin ikinci yazısında CreateML ile metin sınıflandırma yapıyorum. Bu alandaki yeni yazılarımdan ilk siz haberdar olmak isterseniz aşağıdan mail bültenime kayıt olabilirsiniz. Bu yazı dizisi sonunda Udemy kursu yayınlamayı planlıyorum. Mail grubum bu eğitimden de ilk önce faydalanma fırsatını yakalayacak.

Apple’ın makine öğrenmesi hakkında teknik blog dizisine buradan ulaşabilirsiniz. Burada ilginç bilgiler edinebilirsiniz, mesela Sirinin aktifleşmesi için Siri diye seslenmeniz gerekiyor, bu işlemde sürekli dinleme ve sınıflandırma gerektiğinden maliyetli bir işlem. Apple bu sesi sınıflandırmak için öncelikle bu sesi sınıflandırmaya yönelik küçük bir ön yapay sinir ağı modeli kullanarak işlem maliyetini düşürüyormuş. Bu ses sınıflandırıldığında diğer sesleri tanıyan daha kompleks modelini aktif ediyormuş.

Bu sayfanın en altında Apple’ın sunduğu eğitilmiş CoreML modelleri bulabilir ve direkt projenize ekleyip kullanabilirsiniz.

Buraya kadar okuduğunuz için teşekkürler :) Benzer yazılardan haberdar olmak için beni Medium’da ve Twitter’da takip edebilirsiniz. Esenlikle kalın :)