TensorFlow İle İkili (Binary) Resim Sınıflandırma

Muhammed Buyukkinaci
4 min readMar 23, 2018

--

İnternette Deep Learning için genelde MNIST, CIFAR-10 gibi hep hazır datasetler kullanılmaktadır. Sürekli hazır, düzenli veri ile çalışmak, insanı tembelleştirmektedir ve gerçek hayattan uzaklaştırmaktadır. Bu yüzden, ben de sıfırdan, önceden hiç kullanılmamış bir dataset ile proje yapmaya karar verdim. . Bu proje, Keras veya TFLearn gibi herhangi bir high-level API kullanılmadan hazırlanmıştır. GitHub linkine buradan ulaşabilirsiniz. TensorFlow ile ikili resim sınıflandırma (binary image classification) projem aşağıdaki basamaklardan oluşmaktadır:

Source:(https://www.onlinebooksreview.com/articles/best-tensorflow-books)

1 ) İlk önce dataseti indirmek. Dataset, 6400 training ve 1243 testing datasından oluşmaktadır. Training ve testing datası, Kaggle’daki şu yarışmanın training datasıdaki en yaygın 2 class’tan oluşmaktadır. Yani, 6400 resmin 3200 tanesi masa(table), 3200 tanesi ise bardak(glass) resmidir. Yani datasetimiz dengelidir (balanced). Testing datamız da yine dengeli bir dağılıma yakındır.

2) Bardak resimlerini içeren linkler kullanılarak indirilen bardak resimleri, glass_+no şeklinde, masa resimlerini içeren linkler kullanılarak indirilen masa resimleri ise table_ + no şeklinde isimlendirilmiştir. Mesela glass_1294 ve table_777 gibi.

3) Kullanılan resimlerin yaklaşık %1-%2'lik kısmı, OpenCV’nin imread fonksiyonu ile okunurken, sorun çıkardı. Bu yüzden, sorunlu olan resimleri sildim. Bu Dropbox linki ile training ve testing verilerini indirebilirsiniz. Dropbox’ı kullanma sebebim, GitHub’ın 25 MB üzerindeki dosyaları yüklemeyi engellemesidir. Veriler, ‘.npy’ formatına sahiptir. Sıkıştırılmış hali 101 MB civarındadır. Veriyi .jpg değil de .npy formatında koyma sebebim, verinin .jpg halinin 1.5 GB’ın üzerinde olmasıdır. Veriyi DropBox’tan indirdikten sonra .npy formatına sahip dosyaları, GitHub’dan indirdiğiniz klasörün içine kopyalayın. Fotolar, 80x80x3 boyutlarına sahiptir. İşin yüzde 60–70'lik kısmı şu aşamaya kadarki kısımlardır.

Source:(http://he.memegenerator.net/instance/67965538/the-lorax-and-the-onceler-data-cleaning-is-a-thing-which-everyone-needs)

4) Kullandığım kütüphaneleri import ettim. TensorFlow’u graph operation’ları için, OpenCV’yi görüntüyü işlemek için, tqdm kütüphanesini döngülerdeki progress bar’ı için, pandas’ı output sonuçlarını plot etmek için, matplotlib’i ise input resimlerini plot etmek için kullandım.

5)İndirdiğim .npy uzantılı dosyaları, çalışacağım Working Directory’ye koydum.

6) Resmin ismine göre label atadım. Eğer ki resmin ismi glass_ ise [1 0], table_ ise [0 1] şeklinde etiketledim.

7) Sonra, OpenCV’nin imread ve resize fonksiyonlarını kullanarak resimleri yükleyip aynı formata getirdim. Tüm resimler, 80x80x3 boyutlarındadır yani renklidir. Tüm resimlerin input’u 80x80x3'lük bir array, output layer’ı ise 2 boyutlu bir array’dir. Resimleri Python’a yüklerken, tqdm progress bar’ını(ilerleme çubuğu) kullandım. For loop’un ne zaman biteceği konusunda kolaylık sağlıyor. Size de döngüler için tqdm kullanmayı tavsiye ederim.

Yenide boyutlandırılmış(resized) bir masa resmi.

8) Veriyi .npy uzantılı olacak şekilde veriyi kaydettim. Böylece, veriyi Python’a aktarırken zamandan kazandım.

9) Training verisinin 800 resmini Cross-Validation verisi olarak ayırdım. Yani, 5600 train data, 800 CV data, 1243 test datası olacak bir dağılım oldu.

10)Hyperparameter’ları belirledim. 50 epoch train ettim. Batch size’ı 16 aldım. Learning rate 0.00001 olarak seçtim.

11)Weight’leri ve bias’i başlatan, convolution, pooling ve Fully-Connected layer’ları yazmayı kolaylaştıran fonksiyonları tanımladım. Pooling olarak, 2x2'lik bir parametre kullandım. Mesela, Pooling layer’ı (40,40,32) boyutlarını (20,20,32)’ye düşürmektedir.

12) Aşağıdaki resimdeki gibi bir 14 layer’lık bir architecture kullandım. 1 Input layer, 4 Convolution layer, 4 Max Pooling layer, 2 Fully-Connected Layer, 2 Dropout Layer ve 1 Output Layerdan oluşmaktadır. Output layer, 2 node’dan oluşmaktadır. Modelimi, laptopumun GPU’su (GTX 1050) üzerinde train ettim. Size de CPU yerine güçlü bir GPU üzerinde train etmenizi tavsiye ederim.Her ne kadar laptopumun GPU’su çok güçlü olmasa da, 1 epoch yaklaşık 3–4 dakika sürdü. Kullandığım mimarinin detayları aşağıdaki resimdedir.

Resim sınıflandırmada kullandığım architecture.

13) Loss fonksiyonu olarak tf.nn.softmax_cross_entropy_with_logits_v2, optimizer türü olarak gradient descent’in farklı bir versiyonu olan Adam’ı seçtim.

14) Session’ımızı açıp, verimizi feed ediyoruz. Dropout layerlar’da keeping probability’yi 0.8 olarak seçtim.

15)TensorFlow’a çok yeni olduğum için TensorBoard konusunda da çok fazla bilgili değilim. O yüzden, Cross-Validation datası üzerindeki Accuracy ve Cross-Entropy sonuçlarını ayrı birer list içinde tuttum. Cross-Validation verisi için Accuracy ve Loss grafikleri aşağıdadır:

50 epoch boyunca CV datası üzerinde Accuracy grafiği.
50 epoch boyunca Loss fonksiyonun(Cross Entropy) CV üzerindeki grafiği.

Test datası üzerindeki sonuçlar CV üzerindeki sonuçlara yakın çıkmaktadır. Model, Test datası üzerinde %89.12'lik bir accuracy’ye sahiptir. CV üzerinde ise skor %90 civarıdır. Bu da bize modelimizin overfit etmediğini göstermektedir.

Özet olarak ifade etmek gerekirse, bu proje bana; TensorFlow konusunda baya şey öğretti. Olumlu ve özellikle de olumsuz feedback’lerinizi bekliyorum. Siz de bu linkteki veriyi indirdikten sonra, farklı nesnelerin fotoğraflarını içeren linkleri kullanarak resimleri indirebilirseniz ve yukarıdaki aşamaları takip ederek kendi projenizi yapabilirsiniz.

Kaynakça:

  1. https://pythonprogramming.net/convolutional-neural-network-kats-vs-dogs-machine-learning-tutorial/
  2. https://github.com/aymericdamien/TensorFlow-Examples/blob/master/examples/3_NeuralNetworks/convolutional_network.py
  3. https://www.udemy.com/complete-guide-to-tensorflow-for-deep-learning-with-python/

--

--