Anasayfa / Makine Öğrenmesi / Derin Öğrenme / Tensorflow Lite Modeli ile Colab Üzerinden Görüntü Sınıflandırma: Derin Öğrenme Uygulaması

Tensorflow Lite Modeli ile Colab Üzerinden Görüntü Sınıflandırma: Derin Öğrenme Uygulaması

Bildiğiniz üzere derin ağlarda / katmanlarda öğrenme işlemine biz kabaca derin öğrenme diyoruz. Bu açıklama tam karşılığı olmasa da gözünüzde bu şekilde canlandırabilirsiniz. Bu ay, yazımda sizlerle çok faydalı olacağına inandığım ve Türkçe kaynak açısından eksik bilgilerin olduğu bir konuyu ele almak istiyorum. Bu yazımda önce gözümüze Kaggle’dan bir görüntü verisi kestireceğiz. Modelimize uygun veriyi öncelikle Colab’e aktarıp, her görseli 224 piksele indirgeyeceğiz. Son olarak Tensorflow Lite modeli geliştireceğiz.

Bu uygulama ile beraber sizlere, Transfer Learning modellerinin, Tensorflow Lite model çalışmalarınıza nasıl entegre edileceğini göstereceğim. İsterseniz Mobilenet, Imagenet, Densenet, SqueezeNet, MnasNet, EfficientNet ya da Resnet gibi altyapıları kullanabilirsiniz.

Bildiğiniz üzere son zamanlarda bilgisayar güçlerinin efsanevi yükselişi ile beraber veri ile oynamak çok kolay hale geldi. Bunu gören veri de durur mu hiç, o da kendi boyutunu yükseltti. Böyle bir döngü içinde günlerimizi geçiriyoruz. Veri katlanarak artsa da CPU/GPU/TPU gibi teknolojiler ile veriyi işleme hızımız ve veriye karşı kozumuz artıyor.

Derin katmanlarda öğrenme işleminin gerçekleştiği derin öğrenme, görüntü işlemede kullandığımız devasa bir alandır/kavramdır. Görüntü işleme problemleri ile uğraşırken genellikle insanların aklına Evrişimsel Derin Ağlar (CNN) gelmektedir. Aşağıdaki görselde kısaca CNN’in çalışma mantığı özetlenmektedir. Bu görseli açıklayıcılığı anlamında faydalı buluyorum çünkü algoritmanın yaptığı işlemler sırasıyla yazmaktadır.

Kaynak: https://towardsdatascience.com/a-comprehensive-guide-to-convolutional-neural-networks-the-eli5-way-3bd2b1164a53

Teknolojinin gelişmesiyle beraber, derin öğrenmede de çok ciddi atılımlar gerçekleşiyor. Derin öğrenmede (ilgili arkadaşlar bilecektir) model mimarisini belirlerken, katman sayısı, nöron sayısı, iletim sönümleme oranı (dropout) gibi önemli kararlar verilir ve bu kararlar modelin başarısını çok ciddi oranda etkiler. Model başarısı sadece bu mimari yapıya değil, hiper-parametrelere de bağlıdır.

Günümüzde “AutoML” gibi bir kavram çıktı ve dünyada bu konuyla alakalı çok ciddi çalışmalar var. “Acaba önceden belirlenmiş bir veride; şu kadar katman, şu katmanda şu kadar nöron, şu nöron şu kadar momentum-öğrenme oranı ile öğrense” gibi düşünceler, araştırmacıdan araştırmacıya göre değişir. Bu tür kararlar için çeşitli optimizasyonlar vardır.

Tüm bu teknolojiler kısaca şunu demektedir “Kardeşim Amerika’yı tekrar keşfetmeye gerek yok. Ben bazı şeyleri hazır biliyorum, sen gel şu mimarinin şu kısımlarını yeniden öğren, gerisi bende”. Bununla beraber hayatımıza Transfer Learning kavramı girmiştir.

Tensorflow 2.0 Lite modeli ve yöntemleri, mobil telefonlar için kullanıma uygun, çok hızlı ve başarılı bir teknolojidir. Bildiğim kadarıyla (emin değilim) Tensorflow Lite modeli, başında Laurence Moroney abimizin bulunduğu Google ekibi tarafından geliştirildi. Coursera da Laurance Moroney ve derin öğrenmenin hocası kabul edilen Andrew NG ile beraber bu alanla ilgili bir eğitim bulunmaktadır ve bu eğitim geçtiğimiz ay yayınlandı. Şiddetle eğitimi almanızı ve izlemenizi öneririm. Link üzerinden erişebilirsiniz.

Daha önceden de belirttiğim gibi Tensorflow Lite modelleri, mobil telefonlar ve IoT projeleri için kullanışlıdır. Mobil telefonlar için akan (canlı) veride sınıflandırma yapabilmek için modelin çok hızlı çalışması ve milisaniyeler içinde çıktı üretmesi gerekmektedir. Eğer Transfer Learning kullanacaksanız şu tabloyı incelemenizi öneririm. Bildiğiniz üzere bu tür projelerde optimizasyon ciddi bir problemdir. Modelin boyutu, saniyede alınan görüntü sayısı ve kaç milisaniye içinde çıktı üreteceği ve sınıflandırma başarısı…

Kaynak: https://www.tensorflow.org/lite/guide/hosted_models ve https://tfhub.dev/s?module-type=image-classification

Bu link üzerinden farklı Transfer Learning ve mimarilerde modelleri inceleyebilirsiniz. Tabloya göre daha başarılı modeller, daha gelişmiş ve derin mimariler kullandığı için modelin boyutunu/hacmini ve eğitim süresini ciddi yükseltmektedir. Örneğin Resnet ile eğitilen modelin hacmi 250 MB’ın üzerindeydi. Kullandığımız modelde bu altyapıları istediğimiz gibi değiştirebiliyoruz. Ayrıca isterseniz Keras ile kurduğunuz modelleri Tensorflow Lite Converter ile .tflite formatına çevirebiliyorsunuz.

Hadi biraz kodlayalım…

UYGULAMA

Kaggle Verisini Colab Üzerinden Nasıl Çalıştırabilirim?

Öncelikle Google hesabınızın olması ve Python Notebook için Colab çalışması açmanız gerekmektedir. Ardından Kaggle üzerinden bir veri bulmanız ve Kaggle hesabınıza giriş yapmanız gerekiyor.

Eğer Gmail hesabınız varsa, Google üzerinden Colab yazıp ilk linke tıkladığınızda otomatik olarak size Colab ekranına yönlendirileceksiniz, ardından Python 3-2 ve CPU-GPU-TPU gibi seçimleri yapmanız gerekecek. Şimdi Colab açtığınızı ve önünüze Jupyter (Python) ekranını geldiğini varsayarak devam ediyorum. Kaggle hesabınıza girdikten sonra sağ üstte profil resminize tıklayarak “My Account” yazan yere tıklamanız gerekiyor. Ardından açılan sayfada

“Create New API Token” yazan yere tıklamanız gerekmekte. Buna tıkladığınızda “kaggle.json” isimli bir dosyanın bilgisayarınıza inmesi gerekmektedir. Ardından Colab ekranına döndükten sonra

from google.colab import files
files.upload()

kodunu çalıştırmanız ve “kaggle.json” dosyasını yüklemeniz gerekmektedir. Bu işlemle beraber Colab ile Kaggle hesabınız birleşmiş olacaktır. Ardından aşağıdaki kodu doğrudan yazıp çalıştırmanız gerekiyor.

!pip install -q kaggle
!mkdir -p ~/.kaggle
!cp kaggle.json ~/.kaggle/
!ls ~/.kaggle
!chmod 600 /root/.kaggle/kaggle.json

Kodu “run” ettikten bir süre sonra kod çalışmasını durduracaktır ve diğer adıma geçmeye hazır olacağız. Ardından Kaggle üzerinden beğendiğimiz bir veriyi API linki üzerinden Colab üzerinden çalıştırmamız gerekecek. Ben Kaggle üzerinden “Intel Image Classification” verisini beğendim ve çalışmayı bunun üzerinden gerçekleştireceğim. Veriyi buradan inceleyebilirsiniz: https://www.kaggle.com/puneet6060/intel-image-classification/metadata

Gördüğünüz üzere verimiz zipli hali 352 MB ve içinde 14034 görsel ve 6 sınıf bulunmaktadır. Ardından veriyi Colab’e indirmemiz gerekiyor. Bu işlem için sağ üstte “New Notebook” yazan mavi linkin yanındaki 3 noktaya tıklayıp “Copy API Command” ‘e tıklamanız gerekiyor.

Kopyaladıktan sonra aşağıdaki kodu çalıştırmanız gerekmektedir. Aşağıdaki kod, az önce bizim kopyaladığımız koddur. Kopyaladığımız kodu Colab’e yapıştırıp “run” edersek, veri yüklenmiş olacaktır.

!kaggle datasets download -d puneet6060/intel-image-classification

Ve böylece veriyi yüklemiş olduk. Ayrıca 1-2 saniyede 350 MB indirdiğimizi görünce hep beraber “Vay bee” dedikten sonra zip dosyasından kurtulmamız gerekmektedir. Bu sebeple aşağıdaki kodu çalışmamız gerekiyor.

!unzip intel-image-classification

Bir süre bekledikten sonra verimiz tamamen ön işlemlere hazır hale gelmekte. Fotoğraflara baktığımızda 6 farklı sınıfın görsellerini görmekteyiz. Dağ-taş, deniz, sokak ve bina gibi sınıflar mevcut. Fotoğraflar incelendiğinde boyutlarının farklı olduğunu görüyoruz. Bu yüzden fotoğrafları yeniden boyutlandırıp “resize” edip modele öyle sokmamız gerekiyor. Ben her görselin boyutunu 224x224x3 seviyesine indireceğim. Eğer Transfer Learning kullanacaksanız bu rakamlar, modele göre değişiklik gösterebilir. Fakat 224 piksel kullanımı yaygındır.

Öncelikle fotoğrafları yeniden boyutlandıracağımız için yeni bir klasör oluşturmamız gerekiyor. Yeniden boyutlandırılmış görselleri bir yere kaydetmek için bu işlemi yapacağız. Orijinal resimleri bozmadan, yeni bir klasöre “resize” edilmiş görselleri yükleyeceğim. Bunun için öncelikle kendi “local” bilgisayarınızda bir klasör oluşturmanız gerekiyor ve o klasörde, verimizde hangi sınıflar varsa o sınıflar için ayrı ayrı ve aynı isimle klasörler oluşturmanız gerekiyor. Bunun sebebi dosya yolunun orijinal yol ile aynı olması. İsterseniz bunu kod üzerinden de değiştirebilirsiniz, ben bu şekilde yapıyorum, bu araştırmacıya kalmış bir durum.

Veri Ön İşleme ve Model

import os
import numpy as np
import random
import cv2
import matplotlib.pyplot as plt

img_rows=224
img_cols=224
num_channel=3
train_input_shape = (224, 224, 3)

img_data_list=[]
classes_names_list=[]
target_column=[]

PATH = 'seg_train/seg_train'
save_here = 'resized_vbo'

data_dir_list = os.listdir(PATH)
print(data_dir_list)

>> ['forest', 'sea', 'glacier', 'mountain', 'street', 'buildings']

Kendi “Local”imde oluşturduğum dosyayı (resized_vbo) zip haline getirerek Colab’e “files.upload()” komutu ile yüklüyorum, ardından “!unzip resized_vbo” dosyamı zip’ten kurtarıyorum. Ardından yazdığım döngü ile her görseli yeniden boyutlandırıyorum. Kendi projelerimde ve iş yerimde yaptığımda genelde bu göndünün içinde “Data Augmentation” işlemi yapıyorum. Gereksinim duyduğunuz problemlerde veri çoğaltma – üretme yani “Data Augmentation” işlemini şiddetle öneririm. Model başarımızı ciddi oranda arttırdığını her projemde gözlemliyorum. Bu uygulamada ise bu işleme gerek duymadım. İsterseniz siz de yapabilirsiniz. O kısmı siz değerli ve pek kıymetli okuyucularıma bırakıyorum.

Öncelikle veri setimizde her sınıftan kaç tane görsel olduğuna bakalım…

for dat in data_dir_list:
  img_list = os.listdir(PATH+'/'+ dat)
  print(dat, "---Sınıfından toplam görsel sayısı --->",len(img_list))

Ardından görsellerimizi yeniden boyutlandıralım ve belirttiğimiz dosya dizinine (save_here) yeniden kaydedelim.

from PIL import Image, ImageFile

ImageFile.LOAD_TRUNCATED_IMAGES = True

for dataset in data_dir_list:
    print("İşleme Alınan Sınıf = {} , Yeniden Boyutlandırılıyor...\n".format(dataset))
    img_list = os.listdir(PATH+'/'+ dataset)
    for img in img_list:
        input_img_2 = Image.open(PATH + '/' + dataset + '/' + img)
        input_img_3 = input_img_2.resize((244, 244), Image.ANTIALIAS)
        input_img_3.save(save_here + '/' + dataset + '/' + img)

Bu kod kısmında istediğiniz ön işlemeyi yapabilirsiniz. İsterseniz merkeze zoom yapabilir, isterseniz center crop yapabilir ya da yeni veri üretebilirsiniz. Bu araştırmacının amacına bağlı olarak değişebilir. Bir süre bekledikten sonra aşağıdaki gibi çıktılarımız oluşacaktır. Böylece her görselin boyutunu 224x224x3’lük piksellere çevirmiş olduk.

Böylece veri ön işleme kısmını sonlandırmış bulunuyoruz. Şimdi modelimize geçebiliriz. Bu kısımdan önce, yazımda belirttiğim gibi Transfer Learning yapmak isterseniz aşağıdaki kodu kullanabilirsiniz. Bu sizin model performansını doğrudan etkileyecektir. Çıktı süresi, eğitim süresi, model boyutu ve model başarısı değişecektir.

from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

class ImageModelSpec(object):
  input_image_shape = [224, 224]
  mean_rgb = [0, 0, 0]
  stddev_rgb = [255, 255, 255]

  def __init__(self, name, uri):
    self.name = name
    self.uri = uri

mobilenet_v1_075_224 = ImageModelSpec(
    name='mobilenet_v1_075_224',
    uri='https://tfhub.dev/google/imagenet/mobilenet_v1_075_224/quantops/feature_vector/3')

resnet_v2_50 = ImageModelSpec(
    name='resnet_v2_50',
    uri='https://tfhub.dev/google/imagenet/resnet_v2_50/classification/4')

İstediğiniz transfer öğrenme yöntemini buradan bakarak seçebilirsiniz ve “uri” linkini buradan bulabilirsiniz. Ben bu çalışmada özel olarak bir transfer modeli kullanmadım.

Tensorflow Lite modeli geliştirebilmek için Tensorflow 2.0 sürümünün mevcut olması gerekmektedir. Bende Tensorflow 2’nin 2.1.0-rc1 versiyonu var. Bu çalışmayı sürümden yaptım. Aşağıdaki indirme kodunu sizlere iletiyorum.

%tensorflow_version 2.x
!pip install -q tf-hub-nightly==0.8.0.dev201912300005
!pip install -q git+https://github.com/tensorflow/examples

Bu kodu çalıştırmanız gerekmektedir. Ardından model için gerekli kütüphaneleri alalım.

from tensorflow_examples.lite.model_customization.core.data_util.image_dataloader import ImageClassifierDataLoader
from tensorflow_examples.lite.model_customization.core.task import image_classifier
from tensorflow_examples.lite.model_customization.core.task.model_spec import ImageModelSpec
import tensorflow as tf

Şimdi modelimize başlayabiliriz.

data = ImageClassifierDataLoader.from_folder(save_here)
#data.size ile toplam görsel sayınızı görebilirsiniz. Bizim verimizde toplam 14.034 görsel ve 6 sınıf mevcut.
model = image_classifier.create(data,   
                                validation_ratio = 0.20, 
                                test_ratio = 0.20,
                                epochs= 10,
                                shuffle = True) # , model_spec =  mobilenet_v1_075_224 / resnet_v2_50 isterseniz mobilenet - 224 ya da resnet_v2_50 mimarisini kullanabilirsiniz. Karar araştırmacıya ait…

Burada görüldüğü üzere toplamda 2.257.984 parametre var ve biz sadece 7.686 tanesini eğiteceğiz / güncelleyebileceğiz. Modelin eğitimini daha fazla uzatmamak için 10 Epoch ile çalıştırdım. Bu rakamı yükselterek biraz daha stabil sonuçlara ve kayıp grafiklerine ulaşabilirsiniz.

Ardından tahminlerimize biraz bakalım, gerçekte ne olana biz ne dedik… Test verimiz ile inceleyelim.

def ne_renk_vereyim_abime(val1, val2):
  if val1 == val2:
    return 'black'
  else:
    return 'red'

plt.figure(figsize=(16, 16))
for i, (image, label) in enumerate(model.test_data.dataset.take(100)):
  ax = plt.subplot(10, 10, i+1)
  plt.xticks([])
  plt.yticks([])
  plt.grid(False)
  plt.imshow(image.numpy(), cmap=plt.cm.gray)

  image, _ = model.preprocess(image, label)
  image = tf.expand_dims(image, 0).numpy()

  predict_prob = model.model.predict(image)
  predict_label = np.argmax(predict_prob, axis=1)[0]

  ax.xaxis.label.set_color(ne_renk_vereyim_abime(predict_label,\
                                                 label.numpy()))
  plt.xlabel('Predicted: %s' % model.test_data.index_to_label[predict_label])
plt.show()

Görselde de görüldüğü üzere tahminlerimiz gayet başarılı. Kırmızı renkle gördüğümüz sonuçlar bizim hatalı tahminlerimiz. Modelimizin başarı ise 0.9010 olduğunu görmüş olduk.

Overfit – Underfit (ezberleme – az öğrenme) incelemesi için de kayıp ve başarı değerlerimize bakalım.

acc = model.model.history.history['accuracy']
val_acc = model.model.history.history['val_accuracy']

loss = model.model.history.history['loss']
val_loss = model.model.history.history['val_loss']

epochs_range = range(10)

plt.figure(figsize=(12, 12))
plt.subplot(1, 2, 1)
plt.plot(epochs_range, acc, label='Training Accuracy')
plt.plot(epochs_range, val_acc, label='Validation Accuracy')
plt.legend(loc='lower right')
plt.title('Training and Validation Accuracy')

plt.subplot(1, 2, 2)
plt.plot(epochs_range, loss, label='Training Loss')
plt.plot(epochs_range, val_loss, label='Validation Loss')
plt.legend(loc='upper right')
plt.title('Training and Validation Loss')
plt.show()

Evet… Grafiğimiz bu şekilde oluştu. Modelimizde “overfit” var ve açıkçası grafik pek tatmin etmedi beni, bunu gidermemiz için modelimize “dropout_rate” oranı, “batch_size” değeri, validasyon-test oranlarını değiştirmemiz / girmemiz gerekecek ve Epoch sayımızı 50+ civarına çıkarttıktan sonra oluşan grafiğe göre nihai modelimiz için karar verebilecek duruma gelebileceğiz. Modelin bu kısmını size ve sabrınıza bırakıyorum.

Bu çalışmada sizlerle beraber Tensorflow Lite modeli geliştirmiş olduk. Türkçe içerik açısından bu yazıyı çok faydalı buluyorum çünkü Türkçe literatürde bu alandaki çalışmalarda ciddi anlamda eksiklikler mevcut. Bu uygulama ile beraber öncelikle Kaggle verisini Colab ortamına nasıl aktarıldığını öğrendik, ardından veri ön işleme yaparak lite modeli geliştirdik.

Şimdi sıra sizde, iyi eğlenceler.

Saygılarımla,

Varsayımlarınızın sağlanması dileğiyle,

Veri ile kalın, Hoşça kalın..

Utku Kubilay Çınar –Makine Öğrenmesi ve Yapay Zeka Çözümleri Takımında Data Scientist @ DoğuşTeknoloji

Kaynakça

Hakkında Utku Kubilay ÇINAR

YTÜ - Yüksek Lisans Doğuş Teknoloji - Data Scientist

GÖZ ATMAK İSTEYEBİLİRSİNİZ

MATLAB SİMULİNK İLE GÖRÜNTÜ İŞLEME -1

Herkese merhabalar. Yeni bir seriye başlıyoruz Matlab simulink ile görüntü işleme. Bu serimizde kod yazmadan …

Bir cevap yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir