Yapay Zeka ve Makine Öğrenmesi Dersleri

TensorFlow 2 ile Resim Sınıflandırma

TensorFlow 2 ve Keras API kullanarak derin öğrenme ile resimleri sınıflandırma için örnek uygulama | Bilgisayar görüşüne (computer vision) giriş

Tirendaz Akademi
8 min readApr 16, 2021
Photo by Josh Rose on Unsplash

Bilgisayar Görüşü (Computer Vision)

Bilgisayar görüşü, makine öğrenmesindeki önemli araştırma alanlarından biridir. Akıllı telefonlar ve tabletler ile insanlar her gün resim çekiyor ve bu resimleri sosyal medya platformlarına yüklüyor. Bu devasa miktarda üretilen resimleri analiz eden uzmanlara ihtiyaç vardır.

Bilgisayar görüşü, robotik bilimi, sağlık hizmetleri, dronlar, sürücüsüz arabalar, spor ve eğlence gibi bir çok alanda kullanılmaktadır.

Geçen yazımda TensorFlow ile derin öğrenmeye giriş yapmıştım.

Bu yazımda derin öğrenme ile resim sınıflandırmayı anlatacağım.

Fashion MNIST Veriseti

Fashion MNIST dataset

İlk önce veri setini yükleyelim. Kullanacağım veri, fashion MNIST veri seti. Bu veri seti rakamların resimlerini içeren klasik MNIST veri seti ile aynı formattadır. Fashion MNIST veri setinde, klasik MNIST veri setinden farklı olarak rakamların görüntüleri yerine moda ürünlerinin görüntüleri yer alır.

Fashion MNIST veri setindeki sınıfların, klasik MNIST veri setinden daha çok çeşidi vardır. Dolayısıyla bu veri setindeki resimleri sınıflandırmak klasik MNIST veri setini sınıflandırmaktan daha zordur.

MNIST Veri Setini Yükleme

Fashion MNIST veri seti, 70,000 gri tonlamalı görüntüden ve 10 kategoriden oluşur. 70,000 örneklemden 60,000 görüntü, modeli eğitmek için 10,000 görüntü, modeli test etmek için kullanılır. Görüntüler, 28 x 28 piksel boyutlarındaki moda ürünlerini göstermektedir.

Fashion MNIST veri seti kullanarak yapılan analiz, bilgisayar görüsünün “Merhaba Dünya” sıdır.

Bu veri setinin boyutları kısmen küçük olduğundan bilgisayar görüsü modeli kurmak ve test etmek kolaydır. Bu veri setini, TensorFlow ile direk yükleyebilirsiniz.

import tensorflow as tf
fashion_mnist = tf.keras.datasets.fashion_mnist
(X_train, y_train), (X_test, y_test) = fashion_mnist.load_data()

Veri seti yüklendiğinde dört NumPy dizi döndürülür. X_train ve y_train dizileri, modeli eğitmek için kullanılır. X_test ve y_test dizileri modeli test etmek için kullanılır. Görüntülerdeki pikseller 0'dan 255'e tam sayılardır.

Hadi eğitim ve test setinin şekline ve veri tipine bakalım.

X_train.shape, X_test.shape

Veri Ön İşleme

Sinir ağını eğitmeden önce veri setini ön işlemek gerekir.

Veri ön işleme veri analizinin önemli adımlarından biridir.

Veri setindeki etiketler rakamlardan oluşur. Bu rakamlara karşılık gelen moda ürünlerinin isimlerini bir değişkene atayalım.

class_names = ["T-shirt/top", "Trouser", "Pullover", "Dress",     
"Coat", "Sandal", "Shirt", "Sneaker", "Bag", "Ankle boot"]

İkinci görüntüyü görmek için matplotlib kütüphanesini kullanalım.

import matplotlib.pyplot as plt
plt.figure()
plt.imshow(X_train[1])
plt.colorbar()
plt.grid(False)
plt.show()

Eğitim veri setindeki ikinci görüntüye baktığınızda piksel değerlerinin 0 ile 255 arasında olduğunu görebilirsiniz.

Veri Setini Normalleştirme

Modelin eğitim hızını ve performansını arttırmak için girdileri ölçekleyelim. Veri setindeki girdilerin piksellerini basitçe 255'e bölerek bunu yapabilirsiniz.

X_train = X_train / 255.0
X_test = X_test / 255.0

Model Kurma

Bir sinir ağını inşa etmek için modelin katmanlarını ayarlamak ve daha sonra modeli derlemek gerekir. Hadi şimdi Sequential API kullanarak modelin katmanlarını ayarlayalım.

Bir sinir ağının temel bloku katmandır. Katmanlar veriden temsiller çıkarır. Bu temsillerin ele aldığınız problem için anlamlı olmasını umut edersiniz. Çoğu derin öğrenme modeli katmanların zincirleme bir araya gelmesi ile oluşur.

Hadi modelimizi inşa etmeye başlayalım.

model = tf.keras.Sequential ([
tf.keras.layers.Flatten (input_shape = (28, 28), name = "Input"),
tf.keras.layers.Dense (128, activation='relu', name = "Hidden"),
tf.keras.layers.Dense (10, name = "Output")
])

Bu yazdığım kodların üzerinden satır satır geçelim.

(1) İlk satır bir Sequential model oluşturur. Sequential model, Keras’ın en basit modelidir. Sequential modelde katmanlar sırayla dizilir.

(2) Daha sonraki satırda Flatten katmanını yazdım ve modele ekledim. Flatten katman, 28 x 28 piksel boyutlarındaki girdi görüntülerini, 1 boyutlu diziye çevirir (28*28=784). Bu katman, herhangi bir parametre almaz sadece verinin formatını değiştirir.

(3) Bir sonraki satırda, modele 128 nöronluk gizli bir Dense katmanı ekledim. Bu katmanda ReLU aktivasyon fonksiyonunu kullandım. Dense katman bir önceki katmandaki bütün nöronlar ile bağlanır. Her bir Dense katmanı kendi ağırlık matrisine sahiptir ve bu katman girdi ve çıktı arasındaki bütün ağırlıkları içerir.

(4) En son, sınıf başına bir nöron olacak şekilde 10 nöron ile Dense katmanı ekledim. Son katman 10 uzunluklu bir lojit dizi döndürür. Her bir nöron, görüntünün 10 sınıftan birine ait olduğunu gösteren bir skoru içerir. Modelin summary() metodu, katmanların isimleri ile modelin bütün katmanlarını gösterir.

model.summary()

Katmana isim vermezseniz katman ismi Keras tarafından otomatik olarak üretilir.

Çıktıdaki None’ın anlamı batch size’ın herhangi bir değer olabileceği anlamına gelir. Özetin sonunda toplam parametre sayısı gösterilir.

Modelin katmanlarına kolayca ulaşabilirsiniz ve indeksleri kullanarak bir katmanı yakalayabilirsiniz.

model.layers
hidden = model.layers[1]
print(hidden.name)

Bir katmanın bütün parametrelerine get_weights() ve set_weights() metotları ile ulaşılabilir. Hadi ilk katmanın hem ağırlıklarına hem de bias’a bakalım.

weights, biases = hidden1.get_weights()
print(weights)
print(biases)
weights.shape, biases.shape

Dikkat ederesiniz ilk Dense katmanın ağırlıkları rastgele ve bias sıfır ile başlatılıyor. Katmandaki ağırlıkları ve bias’ı, sırasıyla kernel_initializer ve bias_initializer metotlarını kullanarak da başlatabilirsiniz. Bu metotlar hakkında daha fazla bilgiye buradan ulaşabilirsiniz.

Modeli Derleme

Modelin eğitimine başlamadan önce modeli compile() metodu ile derlemek gerekir. Modeli derlerken loss fonksiyonu ve optimeze edici belirlenir. İsteğe bağlı olarak eğitim ve değerlendirme esnasında hesaplamaları görmek için ekstra bir metrik kullanılabilir.

Loss fonksiyonu, eğitim esnasında modelin ne kadar doğru tahmin yaptığını ölçer. Modeli doğru yöne yönlendirmek için bu fonksiyonu minimize etmek isteriz. Optimize edici loss fonksiyonu ve gördüğü veriye dayanarak modeli günceller.

Metrics argümanı, eğitim ve test adımlarını izlemek için kullanılır.

model.compile(loss=tf.keras.losses.SparseCategoricalCrossentropy(
from_logits=True),
optimizer=’adam’,
metrics=[‘accuracy’])

Hadi bu yazdığım kodların üzerinden geçelim.

(1) 0'dan 9'a etiketler olduğu için loss fonksiyonu olarak SparseCategoricalCrossentropy kullandım. Etiketleri one-hot kodlama ile kodlarsanız CategoricalCrossentropy kullanabilirsiniz.

(2) Optimize edici olarak son yıllarda popüler olan “adam” kullandım.

(3) Ele aldığımız problem sınıflandırma olduğu için metrik olarak “accuracy” ölçümünü kullandım.

Modeli Eğitme

Artık fit() metodunu çağırarak modeli eğitebiliriz.

Model eğitim esnasında görüntü ve etiketler arasındaki ilişkiyi öğrenir.

history = model.fit(X_train, y_train, 
epochs=10,
validation_split=0.1)

Modeli eğitirken eğitim setleri kullanılır. Validasyon verileri ile model değerlendirilir. validation_split argümanı ile verilerin bir kısmını doğrulama için ayırabiliriz. Ben bu argümana 0.1 yazarak eğitim verilerinin yüzde 10'nun validasyon için kullanılmasını istedim.

Model eğitilirken her bir epoch’un bitiminde loss ve accuracy metrikleri gösterildi. Bu metrikleri izlemek modelin gerçek performansını görmek için yararlıdır. Modelin eğitim setteki doğruluğu validasyon setten daha iyi ise overfitting problemi olabilir.

İşte bu kadar. Modeli eğitmiş oldum.

Gördüğünüz gibi her bir epoch’da loss değeri düşüyor. Bu modelin verilerden öğrendiği anlamına gelir. 10 epoch sonunda eğitim ve validasyon doğrulukları ekrana yazıldı.

Accuracy ve validasyon accuracy değerlerinin birbirine yakın olması overfitting probleminin olmadığı anlamına gelir.

fit() metodu, eğitim parametrelerini içeren bir history nesnesi döndürür. history.history bir sözlük yapısındadır. Bu sözlük, eğitim ve eğer varsa validasyon setlerinde her bir epoch’dan sonra ölçülen metrik ve loss’u içerir. Bu sözlük yapısını bir Pandas DataFrame yapısına çevirirseniz ve plot() metodunu kullanırsanız eğitim eğrisinin grafiğini çizdirebilirsiniz.

import pandas as pd
pd.DataFrame(history.history).plot(figsize=(8, 5))
plt.grid(True)
plt.show()
Eğitim ve validasyon için doğruluk ve kayıplar

Grafikten gördüğünüz gibi eğitim ve validasyon setlerinde modelin doğruluğu artarken, kayıp azalıyor.

Modelin performansı iyi değil ise hiperparametreleri tekrar ayarlayabilirsiniz. İlk kontrol etmeniz gereken parametre öğrenme oranıdır. Bu parametreyi değiştirmek işe yaramıyorsa farklı bir optimize edici seçebilirsiniz. Eğer hala modelin performansı iyileşmezse o zaman katman sayısını, her katmandaki nöron sayısını ve gizli katmanlardaki aktivasyon fonksiyonunu değiştirebilirsiniz. Ayrıca fit() metodundaki ön tanımlı 32 olan batch_size argümanını ayarlayabilirsiniz.

Model Değerlendirme

Eğitim verisi ile model kurdum ama modelin daha önce görmediği verileri nasıl tahmin ettiğini görmek isteyebilirsiniz. Modeli değerledirmek için eğitim esnasında kullanılmayan test seti kullanılır.

Hadi evaluate() metodunu çağıralım ve test seti kullanarak modeli değerlendirelim.

test_loss, test_acc = model.evaluate(X_test, y_test, verbose=2)
print(‘\nTest accuracy:’, test_acc)

Modelin test set üzerindeki doğruluğu eğitim verisi üzerindeki doğruluğundan biraz daha az. Eğitim ve test doğrulukları arasındaki bu fark overfitting problemini gösterir. Overfitting problemi modelin ezberlediğini gösterir. Diğer bir ifade ile model eğitim verilerini iyi tahmin ederken daha önce görmediği verileri iyi tahmin edemez. Bu problemin üstesinden gelmek için L1, L2 veya geçen ders kullandığım regülerleştirme tekniği kullanılabilir.

Tahmin Yapma

Eğittiğiniz model ile yeni görüntüleri tahmin etmek isteyebilirsiniz. Modelin lineer çıktısı lojittir. Daha kolay yorumlamak için bir softmax katman ekleyerek lojitleri olasılıklara çevirebilirsiniz.

probability_model = tf.keras.Sequential(
[model, tf.keras.layers.Softmax()])

Şimdi bu modele göre test verilerini tahmin edelim.

predictions = probability_model.predict(X_test)

Böylece model test set üzerinde her bir görününün etiketini tahmin etti. Hadi ilk tahmine bakalım.

predictions[0]

Dikkat ederseniz her bir moda ürününe karşılık gelen 10 olasılık döndürüldü. En yüksek olasılığa sahip etiketi NumPy’daki argmax metodu ile görebilirsiniz.

np.argmax(predictions[0])

Model, ilk resmi ankle boot olarak tahmin etti. Hadi ilk görüntünün gerçek etiketine bakalım.

y_test[0]

Gördüğünüz gibi model doğru tahmin yaptı.

İşte bu kadar. Özetle bu yazıda, MNIST veri setini kullanarak görüntü sınıflandırma için,

  • Model kurma
  • Model hiperparametreleri
  • Model değerlendirme
  • Yeni görüntüyü tahmin etme

gibi konuları anlattım.

--

--