Mobil Görü — Keras ve CoreML ile Gerçek Zamanlı Görüntü Sınıflandırma

Source: Deep Learning on Medium


Go to the profile of Umut Boz
iOS Vision

Bilgisayarla Görü (Computer Vision) işlemlerinin, yani görme eyleminin bilgisayarla sağlanmasının mobil cihazlar üzerinden gerçekleşmesine Mobil Görü (Mobile Vision) diyebiliriz. Özellikle son dönemlerde mobil cihazların donanım gücünün artması ve donanım gücüne bağlı olarak sürdürülebilir olan yazılımlar sayesinde yüksek performans gerektiren Örüntü Tanıma, Nesne Algılama gibi işlemleri mobil cihazlarımızda daha yaygın olarak kullanabilmekteyiz.

Daha derin ve çok katmanlı yapay sinir ağlarının uygulanabilir olması ve CNN (Convolutional Neural Networks) mimarilerinin bilgisayar görü alanında başarısı ile birlikte önde gelen teknoloji şirketleri derin öğrenme alanında yatırımlarını ciddi seviyede arttırmaktalar. Yine şirketler tarafından ve akademik alanda üretilmiş çok sayıda Derin Öğrenme kütüphaneleri bulunmaktadır.

Bu gelişmelerle birlikte mobil dünyada ise; Google’ın Mobile Vision için; Vision, Apple’ın ise aynı isme sahip Vision yazılım kütüphaneleri biz geliştiricilere sunulmaktadır.

Bu yazıda, mobil cihaz kamerası üzerinden şirketimiz bünyesindeki agile takımların logolarını tanıyan bir uygulamanın geliştirme süreçlerini açıklayacağım. Benzer bir süreci özelleştirerek uygulayabilirsiniz.

Koçsistem Agile takım logoları

Uygulama kapsamında ise; Keras python kütüphanesi kullanılmıştır. Deep Learning kütüphanesi olan Keras ki arka planda Tensorflow’u kullanan ve wrap eden (Tensorflow’u daha high-level hale getiren) bünyesinde bir çok kolaylaştırıcı yardımcı aracı barından Yapay Sinir Ağı kütüphanesidir.

Uygulamamız için gerekli olan araç ve gereçleri açıklamakla başlıyorum.

1-Mantıksal olarak grupladığımız görseller

Uygulamada 7 farklı sınıf için gruplanmış 2744 görsel kullanılmıştır. Bu kadar veriyi bulmak bir mesele… Evet duyar gibiyim. Ama telaşa gerek yok, bunun için bazı yöntemler var. En azından 7 farklı sınıf için, her bir sınıf için 10 ile 15 arasında görsel temin edersek Data Augmentation yöntemi ile eldeki görsellerimizi çoğaltabiliriz. Data Augmentation konusunda detaylı bilgi için kaynağı inceleyebilirsiniz.

2 -Python geliştirme ortamı

Geliştirme ortamım Mac OS işletim sistemi üzerinde conda virtual envoirment ile hazırlanmıştır. Python 3.6 versiyonu ile geliştirme yapılmıştır.

conda create --name viertualEnvName python=3.6
conda activate viertualEnvName
conda install pip

3-iOS Geliştirme ortamı

Xcode 10.2 versiyonu ile geliştirdim fakat burada bağımlılık için min. iOS 11.0 yeterlidir.

4 -Derin Öğrenme (Deep Learning), CNN Mimarisi

Makine Öğreniminin bir alt konusu olan Derin Öğrenme için Erchan Hoca’nın röportajı ufuk açabilir. CNN (Convolutional Neural Network) Evrişimli Sinir Ağı yapısı için güzel bir kaynak.

5- Python kütüphaneleri

Keras ile eğitmiş olduğumuz modeli iOS platformuna taşıyıp dönüştürebilmemiz için coremltools paketini kullanacağız. Öte yandan numpy, PIL, matplotlib,os saymış olduğum Python kütüphanenin alt modülleri kullanılmışıtır.

6- Apple’ın iOS ML framework’u olan CoreML

7- Yukarıda bahsi geçen iOS ve Python kütüphaneleri kullanımı ve geliştirmeler için Python ve Swift programlama bilgisi.


Eldeki verilerimizi çoğaltmak adına Keras kütüphanesi alt modülü olan ImageDataGenerator kullanılmıştır. Örnek kod içerisinde bir array içindeki görsellerin rotate, size sclae, zoom vb. gibi çeşitli kombinasyonlarda dönüştürülerek veri çoğaltmasını bulabilirsiniz.

Data çoğaltma işlemi için, daha detaylı bilgiler için bağlantıyı inceleyebilirsiniz.

Hazırlamış olduğumuz veri kümesi ile Keras kütüphanesinin classification işlemleri için kullanılan kütüphanelerilimiz..


Elde ettiğimiz görsel veri kümesi, 300×300 olarak eğitim öncesinde yeniden ölçeklenerek memory üzerinde numpy array olarak saklanmaktadır.

Oluşturduğumuz evrişimli yapay sinir ağı modelimiz, aşağıdaki katmanlardan oluşmaktadır. Görseller RGB olarak kullanıldığından 3 x 300 x 300 düzleştirilmiş bir matrise dönüşmektedir. Burada önemli bir nokta, eğer görselleri grayscale olarak dönüştürmüş olsaydık shape değerimizi 1 olarak evrişimli sinir ağımıza göndermemiz gerecekti. Aksi takdirde eğitim aşamasında uyumsuzluk nedeniyle hata almış oluruz.

26. adıma gösterilen (7,1,1) son olarak oluşturduğumuz 7 kategorilendirilmiş sınıfı temsil etmektedir.

[“agilestudio”, “cifar1”,”cifar2",”gamechangers”, “ghostbusters”,”ronesans”,”starforce”]

Ve son olarak eğitim sonucunda loss ve accuracy değerlerimiz aşağıdaki gibi olmaktadır.

Epoch 1/5
2744/2744 [==============================] — 336s 122ms/step — loss: 0.1826 — acc: 0.9330
Epoch 2/5
2744/2744 [==============================] — 329s 120ms/step — loss: 0.0711 — acc: 0.9732
Epoch 3/5
2744/2744 [==============================] — 329s 120ms/step — loss: 0.0593 — acc: 0.9776
Epoch 4/5
2744/2744 [==============================] — 322s 117ms/step — loss: 0.0508 — acc: 0.9819
Epoch 5/5
2744/2744 [==============================] — 322s 117ms/step — loss: 0.0282 — acc: 0.9893

Test

Üretmiş olduğumuz .h5 uzantılı Keras modelimizi test işlemi için aşağıdaki yöntemleri takip edebilirsiniz

keras prediction

Output
filename : starforce_test.jpeg : starforce prediction : 1.0
filename : ghostbusters_test.jpeg : ghostbusters prediction : 0.9999976
filename : 0300.png : cifar1 prediction : 0.9802493
filename : g11.png : ghostbusters prediction : 1.0
filename : g9.png : ghostbusters prediction : 1.0
filename : gamechangers_01.png : gamechangers prediction : 0.99996185
filename : r6.png : ronesans prediction : 0.9995158
filename : ronesans__0_1687.jpg : ronesans prediction : 0.9999999

Keras kütüphanesi ile oluşturmuş olduğumuz agile takımlarımızı tanıyan modeli coremltools paketi sayesinde Xcode geliştirme ortamımıza dönüştürebilir ve uyumlu bir şekilde taşıyabiliriz. Aşağıda hazırlamış olduğumuz keras modelimizin Xcode üzerindeki künyesi gösterilmektedir.

keras_vision.mlmodel

iOS platformu üzerinde yapacağımız tüm geliştirmeleri Swift programlama dili ile gerçekleştireceğiz. Agile takımlarımızın logolarını tanıyan modelimiz ile mobil cihaz kamerası ile gerçek zamanlı olarak yakaladığımız görselleri yeniden boyutlandırarak tahminleme işlemi gerçekleştireceğiz. Bunun için, iOS uygulamamızda ViewController’a delegate olarak AVCaptureVideoDataOutputSampleBufferDelegate protocol’unu eklemeliyiz. Ardından, protocol üzerinden yakalayacağımız görselleri kullanacağız. Bu görsellerle keras mlmodel’i ile tahminleme gerçekleştirilmektedir.

func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) {

captureOutput methodu içerisine aşağıdaki kodlar ile tahminleme başlatılır.

guard let pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer) else {
return
}
let attachments = CMCopyDictionaryOfAttachments(kCFAllocatorDefault,
pixelBuffer,
CMAttachmentMode(kCMAttachmentMode_ShouldPropagate)) as? [String: Any]
connection.videoOrientation = .portrait
var requestOptions:[VNImageOption: Any] = [:]
if let cameraIntrinsicData = CMGetAttachment(sampleBuffer, kCMSampleBufferAttachmentKey_CameraIntrinsicMatrix, nil) {
requestOptions = [.cameraIntrinsics: cameraIntrinsicData]
}
let ciImage = CIImage(cvImageBuffer: pixelBuffer, options: attachments).convertUIImage().pixelBuffer(width: newImageSize, height: newImageSize)
let imageRequestHandler = VNImageRequestHandler(cvPixelBuffer: ciImage!, orientation: .upMirrored, options: requestOptions)
do {
try imageRequestHandler.perform(self.visionRequests)
} catch {
print(error)
}

Yukarıdaki kod bloğunda newImageSize değerini 300 piksel olarak tanımladık. Döönüştürme işlemi için ise extension methodlar kullanılmıştır.

Keras mlmodel’imiz üzerinde tahminleme yapabilmek için iOS Vision kütüphanesini kullanacağız.

let kerasModel = keras_vision().model
var visionRequests = [VNRequest]()
do {
guard let agileTeamsModel = try? VNCoreMLModel(for: kerasModel) else {
fatalError("Could not load model")
}
let classificationRequest = VNCoreMLRequest(model: agileTeamsModel, completionHandler: handleClassifications)
visionRequests = [classificationRequest]
} catch {
fatalError(error.localizedDescription)
}

handleClassifications delegate metodumuz ise :

func handleClassifications(request: VNRequest, error: Error?) {
if let theError = error {
print("Error: \(theError.localizedDescription)")
return
}
guard let classificationObservations = request.results as? [VNClassificationObservation] else
{
fatalError("Unexpected result type from VNCoreMLRequest.")
return
}
guard let best = classificationObservations.first else
{
fatalError("Can't get best result.")
return
}
if best.confidence > recognitionThreshold {
selectedTeam = best.identifier
DispatchQueue.main.async {
self.resultView.text = self.selectedTeam
self.selectTeamButton.isHidden = false
}
}else{
selectedTeam = ""
DispatchQueue.main.async {
self.resultView.text = self.selectedTeam
self.selectTeamButton.isHidden = true
}
}

Son olarak tanınan logoya ait agile takım bilgileri için seçim butonu ile başka bir ekrana yönlendirip, ekran gösterimini sağlıyoruz.

Yeni yazılarda buluşlmak üzere : )

Devamını gör eleştiri sadece gizli hayranlıktır. Cengiz Aytmatov