Evrişimli Sinir Ağları(CNN)| TensorFlow ve OpenCV Kütüphanesi İle Katı Atık Tespiti | by Büşra Sulukan | Jan, 2024


Evrişimli Sinir Ağları, temel olarak görüntüleri sınıflandırmak ve nesne tanıma yapmak için kullanılır.Bir girdi görüntüsünü alıp, görüntüdeki çeşitli görünüşleri/nesneleri birbirinden ayırabilen derin öğrenme ağ çeşididir.

Sinir ağının evrişimsel yapıda olması, görüntüdeki örüntüyü basitten karmaşığa doğru analiz edebilmesini ifade etmektedir. Bu durum eğitim aşamasında öğrenilmesi gereken parametre sayısını da azaltabilmektedir.

Genel olarak yüzbinlerce (ihtiyaca göre daha fazla veya daha az) görsel öğe üzerinden bir CNN eğitilir, böylelikle bu eğitilmiş olan Derin Sinir Ağı aracılığıyla bilgisayar sistemleri görüntünün hangi nesneye ait olduğunu ayırt edebilme özelliğini gerçekleştirebilir. Böylelikle ihtiyaca yönelik diğer işlemleri bilgisayarlara yaptırabilmemize olanak tanır.

Derin Öğrenmenin her alt başlığında mantık aynıdır, insan sinir sistemi ve öğrenme(algılama) şekli örnek alınarak yapay eğitim modelleri gerçekleştirilmiştir. Bu nedenle tıpki insan beyni gibi yapay sinir ağları da burada öğrenme işlemini gerçekleştirirken detaya değil ayırt edici özelliklere ihtiyaç duyarlar. Daha fazla açıklayıcı olması için örnek vermek gerekirse; aklınızdan bir masa canlandırmanızı istersem şu an bu yazıyı okuyan herkesin zihninde canlanan masa farklı özelliklere sahip olacaktır, yüksekliği, genişliği, hammaddesi ve hatta tasarımsal özellikleri her birimizin zihninde farklı canlanabilir. Fakat bu zihnimizde canlananlar resim olarak karşımıza gelse her birimiz bu görselleri “masa” diye tanımlarız. Bunun sebebi “masa” nesnesinin zihnimizde, onu diğer nesnelerden ayıran iz düşümlere sebep olmasıdır. İşte insan beyninin bu davranışı baz alınarak, evrşimli sinir ağlarında da nesnelerin detayına değil, ayırt edici özelliklerine odaklanarak bir öğrenme süreci gerçekleştirilmesi amaçlanır.

Genel itibariyle 6 adet ana katmandan oluşurlar. Bunlar sırasıyla:

— Convolution(Evrişim) Katmanı

  • Stride(Adım)
  • Padding(Dolgu)

— Batch Normalization (Grup Normalleştirme) Katmanı

— Activation(Aktivasyon) Katmanı

— Pooling(Havuzlama) Katmanı

  • Max Pooling(Maksimum Havuzlama)
  • Average Pooling(Minimum Havuzlama)

— Fully Connected & Flattening (Tam Bağlantı ve Düzleştirme) Katmanı

— Dropout (Sönümleme) Katmanı

Yukarıdaki bu katmanlara ek olarak farklı mimarilerde farklı katmanlarda olabilir. Örneğim ; Evrişim katmanının bir kaç defa tekrarlandığı bir mimari olabilir.

A. Evrişim Katmanı

Evrişim, sinyal işleme ve görüntü işleme alanlarında yaygın kullanılan bir operatördür.

Evrişim Katmanları, özellikle görüntü işleme görevlerinde, girdi verilerinden özellik çıkarımları yapmak için kullanılan katmanlardır. Bu işlem insanların nesneyi algılayıp tanımlarken gönderilen resmin daha öne çıkan özellklerini kullanmasına benzetilir.Bu işlemler algoritmalar aracılığıyla gerçekleştirilir.

Filtre(çekirdek), verilen girdi veriyi tarayıp, veride bulunan kenar,köşe,nesne gibi spesifik özelliklerin yakalanmasını sağlar.Girdi veride proje amacına uygun tespit etmek istenilen spesifik özelliğe göre çeşitli özel filtreler kullanılabilir.Filtre sonucu çıkacak olan yapıya “çıkış matrisi” ya da “feature map(özellik haritası)” adı verilir.

Stirde, filtreler aracılığıyla görselin üzerinde adım kaydırma işlemi yapmaya verilen isimdir.Evrişim katmanlarında, filtreler girdi veri üzerinde belirli bir adım aralığıyla kaydırılarak özellik haritaları oluşturulur.Örneğin; 3×3 boyutunda bir filtre kullanılıyorsa ve stride değeri 2 ise, filtre her adımda 2 pksel sağa ve 2 piksel aşağı kaydırılır.Aynı mantıkla eğer stride değeri 1 olarak kullanılırsa, fşltre her bir piksel aracılığıyla kaydırılır. Stride 1 değeri ile özellik çıkarımı yaptığımızda daha hassas,daha odaklı(detay) bir sonuç elde ederiz ve çıkan matrisimiz 3×3 ‘lük bir matris olur.

Şekil-1: Stride ile Çıkış Boyutunun Hesaplanması

Şekil-1’de olduğu üzere, stride değeri artırıldığında özellik çıkarımımızın matrisi küçülür.Bu bize daha hızlı ve performanslı işlem yapma olanağı sağlar.Fakat bu işlem detaydan uzaklaştıran bir işlem olduğu için bilgi kayıplarına yol açabilir.

Padding, evrişim işlemi sonrasında giriş matrisi boyutuyla çıkış matrisi boyutunun brbirine eşit olmasını sağlar.Bu işlemi yapma amacımız evrişim işlemleri sırasında, filtre boyutu ve giriş verisi boyutu arasında uyum sağlamanın önemli olmasıdır. Padding, bu uyumu sağlama görevi görür. Genellikle 2 türde uygulanır. Bunlar; “Valid(Kenar) Padding” ve “Same Padding”tir.

Şekil-2: Valid Padding ve Same Padding Karşılaştırılması

Valid padding, giriş verisinin kenarlarına hiçbir padding eklenmemesi anlamına gelir.Genellikle çıkış boyutunu küçültmek ve modelin öğrenme yeteneklerini daha iyi kontrol etmek için kullanılır.

Same padding, giriş verisinin kenarlarına padding eklenerek uygulanır.Padding işlemi, sıfırlarla veya diğer belirli değerlerle yapılabilir. Sıklıkla kullanılan bir tür “zero-padding”dir, yani kenarlara sıfırlar eklenir.Filtreleme işlemi sırasında, filtre giriş verisinin kenarlarına değer. Böylece, çıkış boyutu, giriş boyutuna eşit olur.

Same padding, giriş boyutunu korumak ve kenarlardaki bilgi kaybını önlemek amacıyla sıklıkla kullanılır.

B.Batch Normalization (Grup Normalleştirme) Katmanı

Batch Normalization katmanı, bir sinir ağının gizli katmanları arasında yapılan bir normalleştirme işlemidir.Bu katmanda tüm girdi veri yerine küçük gruplar halinde normalleştirme işlemi yapılmaktadır.Bu katman özellikle evrişim katmanı ve aktivasyon katmanı arasında yer alır.

Bu katman evrişimli sinir ağlarında zorunlu bir katman değildir.Özellikle Gradient Descent kullanılan modellerde featureların standartlaştırılması söz konusu olduğu için bu katmanda yapılan işlemler eğitim sürecini hızlandırır ve hata fonksiyonunu optimize eder.(0–1 arasında featureların değerlerini dönüştürür.)

C.Activation(Aktivasyon) Katmanı

Karmaşık veriler içerisinden yapay sinir ağlarının öğrenmesini sağlayabilmek için kullanılan fonksiyonların genel adı “aktivasyon fonksiyonu”dur.Bu aktivasyon fonksiyonlarının kullanıldığı katmana aktivasyon katmanı denir.

Katmanlara göre aktivasyon fonksiyonlarının kullanımı aşağıdaki gibidir:

— Hidden Layers : Relu

— Output Layer:

  • Eğer Regresyon problemi ise aktivasyon kodu kullanmaya gerek yok.
  • Eğer ikili sınıflandırma problemi ise :Sigmoid
  • Eğer multiclassification problemi ise : Softmax

D.Pooling(Havuzlama) Katmanı

Görüntünün özelliklerini kaybetmeden boyutunun azaltılmasını sağlama işlemine “pooling”adı verilir ve bu işlemler pooling katmanında yapılır. Bu katmanda herhangi bir öğrenme işlemi yapılmaz. Evrişim katmanını sonrası kullanılan bu katmanda, hesaplama karmaşıklığınnı azaltmak, süreci hızlandırmak için pooling işlemine ihtiyaç duyulur. Pooling katmanının en önemli faydaları arasında bilgi kaybına yol açmaması vardır.

Şekil-3: Max Pooling ve Average Pooling Karşılaştırılması

En yaygın kullanılan 2 pooling yöntemi vardır:

  • Max Pooling(Maksimum Havuzlama): Max pooling, her bir bölgenin maksimum değerini alarak çalışır.Belirli bir bölgeye ait en büyük özellik değeri, bu bölgenin temsilcisidir.
  • Average Pooling(Minimum Havuzlama):Average pooling, her bir bölgenin ortalamasını alarak çalışır.Belirli bir bölgeye ait özellik değerlerinin ortalaması, bu bölgenin temsilcisidir.Genellikle daha yumuşak bir özellik haritası elde etmek ve küçük değişikliklere daha hassas hale gelmek amacıyla kullanılır.

Not: Pooling katmanında özelliklerin korunması devam eder sadece boyut indirgeme yapılır.Bilgi kaybına yol açmaz.

E.Fully Connected & Flattening (Tam Bağlantı ve Düzleştirme) Katmanı

Mevcut matris boyutunda olan veriyi flatten işlemiyle yapay snir ağının algılayabileceği tek boyutlu bir formata getirilmesi işlemi Fully Connected & Flattening katmanında yapılır.

Bu aşama evrişimli sinir ağının modellemeye geçmeden önceki son katmandır.

Şekil-4: Flatten işlemi
Şekil-5: Evrişimli Sinir Ağları Katmanları

F. Dropout (Sönümleme) Katmanı

Sinir ağı içerisinde yer alan nöronların kullanıcı tarafından belirlenen bir oranda rastgele olarak söndürülmesiyle aşırı öğrenmeyi önleyerek performansın artırılmasını amaçlayan katmandır.

Şekil-6: DroupOut Öncesi ve Sonrası Modelin Temsili Gösterimi
Şekil-7: Kurulan Modelin Temsili CNN Katmanları

İlk olarak TrashNet (kaggle.com) sitesinden ilgili data seti indirilerek çalışılacak olduğunuz IDE ‘nin dosya dizinine kaydedilir. Benim gibi Google Colab Notebook kullanarak işlemlere devam edecek olanların veri setin Google Drive’a yüklemeleri ve kütüphane import işlemlerinden sonra Google Drive ile Google Colab Notebook’u aşağıdaki kodlarla entegre etmelidir.Başka IDE kullanacak olanlar dosya dizinini okutarak işleme devam edebilirler.

#Veriyi okuma ve işleme adımında kullanılacak olan kütüphaneler
import cv2
import urllib
import itertools
import numpy as np
import pandas as pd
import seaborn as sns
import random,os,glob
from imutils import paths
import matplotlib.pyplot as plt
from sklearn.utils import shuffle
from urllib.request import urlopen

# Warningleri kapatmak için
import warnings
warnings.filterwarnings("ignore")

# Model değerlendirme aşaması için
from sklearn.metrics import confusion_matrix, classification_report

#Model kurma için gerekli olan kütüphaneler
import tensorflow as tf
from tensorflow.keras.models import Sequential
from tensorflow.keras.preprocessing import image
from tensorflow.keras.utils import to_categorical
from tensorflow.keras.callbacks import ModelCheckpoint,EarlyStopping
from tensorflow.keras.layers import Conv2D, Flatten, MaxPooling2D, Dense, Dropout, SpatialDropout2D
from tensorflow.keras.preprocessing.image import ImageDataGenerator, img_to_array, load_img, array_to_img

#Google Colab Notebook ile Google Drive'ın eşleştirilmesi
from google.colab import drive
drive.mount('/content/drive')
#Drive'a yüklenen resimleri Google Colab Notebook'a çekme
dir_path = '/content/drive/MyDrive/Garbage classification/dataset-resized'
#Target Size ve Label Değerlerinin Belirlenmesi (Veri setimiz etketsiz.Biz klasör isimlerini kullanarak bir labellama yapacağız)
target_size = ( 224,224)
waste_labels = {"cardboard": 0, "glass":1, "metal":2, "paper":3, "plastic":4, "trash": 5 } #Klasör isimlerinin etiket ismi olarak kullanılması ve etiketlerin encode edilmesi işlemi
def load_datasets(path):
"""
Görsellerin bulunduğu görüntüyü okuyup etiketlerini oluşturur.

Parametreler:

path: Görsellerin bulunduğu dizini ifade eder.

Return:

x: Görüntülere ait matris bilgilerini tutar.

labels: Görüntünün ait olduğu sınıf bilgisini tutan liste.

"""
x = []
labels = []
#Gönderdiğimiz pathdeki görüntüleri listeyip sıralamaktadır.
image_paths= sorted(list(paths.list_images(path)))

for image_path in image_paths:
#Belirtilen pathdeki görüntüler openCV kütüphanesi ile okunmaktadır.
img = cv2.imread(image_path)

#Okunan görüntüler başlangıçta belirlenen target_size'a göre yeniden ölçeklendirilir.
img = cv2.resize(img, target_size)

#Ölçeklendirilen görüntüler x listesine eklenir.
x.append(img)
#Her bir path '/' ifadesi ile ayrıldığında dönen listenin sondan ikinci elemanı labelı temsil etmektedir.
label = image_path.split(os.path.sep)[-2]
#Yakalanan labelların sayısal değerleri waste_labels sözlüğünün value değerine karşılık gelir.Value değeri alınarak label oluşturulur.
labels.append(waste_labels[label])

#Veri seti random bir şekilde karıştırılır.
x,labels = shuffle(x,labels, random_state = 42)

#Boyut ve Sınıf Bilgisi raporlanır.
print(f"X Boyutu: {np.array(x).shape}")
print(f"Label Sınıf Sayısı: {len(np.unique(labels))} Gözlem Sayısı: {len(labels)}")

return x,labels

Bu işlemden sonra daha sonraki aşamalarda kullanmak için görüntü boyutunun tutulmasına ihtiyacımız vardır.

x,labels = load_datasets(dir_path)
#Görüntü boyutlarının tutulması
input_shape = (np.array(x[0]).shape[1], np.array(x[0]).shape[1],3 )

Artık veri setimize kolaylıkla ulaşabiliyoruz.Bunu göstermek için veri setinden görsellere ulaşma işlemleri yapılabilir.Bu işlem adımı için aşağıdaki fonksiyon tanımalaması yapılır.

def visualize_img(image_batch,label_batch):
"""

Veri seti içerisinden görüntü görselleştirir. (Alt Alta beşer beşer resimleri gösterir.)

Parametreler:
image_batch: Görüntülere ait matris bilgilerini tutar.

label_batch: Görüntünün ait olduğu sınıf bilgisini tutan liste.

"""
plt.figure(figsize= (10,10))
for n in range(10):
ax = plt.subplot(5,5,n+1)
plt.imshow(image_batch[n])
plt.title(np.array(list(waste_labels.keys()))[to_categorical(labels,num_classes=6)[n]==1][0].title())
plt.axis("off")

Şekil-8: Gözlem Değerleri

Kaggledan indirdiğimiz veri setimizdeki görüntüler yukarıda görüldüğü üzere arka planları çok temiz şekilde hazırlandığı ve gerçek dünyada arka plan , ışık, görüntü kalitesi vb. bakımlardan temiz görseller olmadığı için gürültü ekleme işlemi yaparak hem veri setimize resmin farklı açılarından oluşan yan datalar ekleme işlemi yaparak veri setimizi çoğaltarak modelin öğrenmesine katkı sağlamalıyız hem de, gerçek dünya ile veri seti arasındaki farkı eğitim setinde ortadan kaldırmaya çalışmalıyız. Bu işlemler için aşağıdaki kodlar yazılır. Bu kodlar ile modeli fit etmez, model kurulum aşamasından önce hazırlık işlemlerini gerçekleştirir.

# Train veri seti için bir generator tanımlanır.
train = ImageDataGenerator(horizontal_flip=True,
vertical_flip = True,
validation_split= 0.1,
rescale= 1./255,
shear_range = 0.1,
zoom_range = 0.1,
width_shift_range = 0.1,
height_shift_range= 0.1)

#Test veri seti için generator tanımlanır.
test = ImageDataGenerator(rescale=1/255,
validation_split=0.1)

train_generator=train.flow_from_directory(directory = dir_path,
target_size =(target_size),
class_mode = "categorical", #Bu ikiden fazla sınıf bilgisini temsil eder, eğer iki adet sınıfımız olsaydı "binary" girecektik
subset = "training"
)

test_generator=test.flow_from_directory(directory= dir_path,
target_size= (target_size),
batch_size=251,
class_mode= "categorical",
subset = "validation")

"""
Output: Found 2276 images belonging to 6 classes.
Found 251 images belonging to 6 classes.
"""

Yukarıda hazırlanan generatörler ile gürültü işleminden sonra artık modelleme aşamasına geçiş yapmak için katmanların ve fonksiyonlarının tanımlaması aşağıdaki şekilde yapılır. Burada verilen filtre,stride,pool size vb değerler yaygın olarak kullanılan biçimde yazılmıştır. Farklı kombinasyonlar ile de modelin katmanlarını oluşturmak mümkündür. Burada model kurulumu yapılmaz sadece öncesinde katmanlar tanımlanır.

model = Sequential()
model.add(Conv2D(filters = 32, kernel_size = (3,3), padding ="same", input_shape =(input_shape),activation ="relu"))#Evrişim Katmanı oluşturma
model.add(MaxPooling2D(pool_size = 2, strides= (2,2))) #Pooling Katmanı

#Deep Neural Networks için birden fazla evrişim ve pooling katmanı kullanılması:

model.add(Conv2D(filters = 64, kernel_size = (3,3), padding ="same",activation ="relu"))
model.add(MaxPooling2D(pool_size = 2, strides= (2,2)))

model.add(Conv2D(filters = 32, kernel_size = (3,3), padding ="same",activation ="relu"))
model.add(MaxPooling2D(pool_size = 2, strides= (2,2)))

model.add(Flatten()) #Flatten Katmanı

model.add(Dense(units = 64, activation = "relu")) #Dense Katmanı
model.add(Dropout(rate=0.2)) #Dropout Katmanı

model.add(Dense(units = 32, activation = "relu")) #2.Dense Katmanı
model.add(Dropout(rate=0.2)) #2.Dropout Katmanı

model.add(Dense(units = 6, activation = "softmax")) #Çıkış katmanı, units= 6 olmasının sebebi 6 classa sahip olmamız.

Şekil-9:Modelin Özeti

Model kurma işlemine geçmeden önce optimizasyon ve model katmanlarının değerlendirilme işlemi yapılır. Bu optimizasyon ve değerlendirme işlemleri, modelin eğitim süreci boyunca tekrarlanabilir. Modelin ağırlıkları daha iyi bir performans elde etmek üzere sürekli olarak güncellenir ve değerlendirme işlemleri, modelin genelleme yeteneğini izlemek ve hiperparametre ayarlamak için kullanılır. Bu sayede, daha iyi bir model elde edebilmek ve istenen sonuçlara ulaşabilmek mümkün olur.

model.compile(loss = "categorical_crossentropy",
optimizer = "adam",
metrics = [tf.keras.metrics.Precision(),tf.keras.metrics.Recall(),"acc"])
callbacks = [EarlyStopping(monitor = "val_loss", patience=50, verbose = 1 , mode="min"),
ModelCheckpoint(filepath= "mymodel.h5",monitor="val_loss",mode= "min",save_best_only=False,verbose=1)]

Değerlendirme(call_backs) kod bloğunda,verilen parametrelere göre test seti için en az kaybı veren değerleri bizim için kaydetmesini söylüyoruz.

Optimizasyon ve model katmanlarının değerlendirilmesi işlemlerinden sonra yukarıda oluşturmuş olduğumuz değerler ile model kurulumu yapılır.

history = model.fit_generator(generator= train_generator,
epochs= 100,
validation_data=test_generator,
callbacks= callbacks,
workers=4,
steps_per_epoch= 2276//32,
validation_steps = 251//32)

Epoch sayımız 100 olduğu için bu işlem yaklaşık bir, bir buçuk saat aralığında tamamlanır. Tamamlandığında aşağıdaki görüntü çıktı olarak verilir.

Şekil-10:Model Kurma Sonucu

Bu çıktıda görüldüğü üzere loss, precision, recall, acc, val_loss, val_precision, val_recall, val_acc değerlerine 100 döngülük bir model eğitimi sonucunda sahip oluruz.Her bir adımda modelimiz bizim için bu değerleri kaydeder ve tanımlamış olduğumuz callbacks bizim için bu 100 turluk değer sonunda en az test hata kaybına (val_loss) sahip modelin değerlerini kaydeder.

Şekil-11: Loss,Precision,Recsll,Accuracy Değerlerinin Ekrana Yazdırılması

Bu işlem sonrasında kurmuş olduğumuz modelin Eğitim ve Test Başarısını ile Eğitim ve Test Kaybı değerlerini daha iyi yorumlayabilmek için grafiklerini yazdırırız.

#-------------------------------------- Grafik 1: Accuracy----------------------------#
plt.figure(figsize=(20,5))
plt.subplot(1,2,1)
plt.plot(history.history['acc'],color = "b",label= "Training Accuracy")
plt.plot(history.history["val_acc"], color = "r", label = "Validation Accuracy")
plt.legend(loc = "lower right")
plt.xlabel("Epoch", fontsize= 16)
plt.ylabel("Accuracy",fontsize = 16)
plt.ylim([min(plt.ylim()),1])
plt.title("Eğitim ve Test Başarım Grafiği", fontsize = 16)

#-------------------------------------- Grafik 2: Loss ------------------------------#

plt.figure(figsize= (20,5))
plt.subplot(1,2,2)
plt.plot(history.history["loss"],color= "b",label="Training Loss")
plt.plot(history.history["val_loss"],color="r",label="Validation Loss")
plt.legend(loc= "upper right")
plt.xlabel("Epoch",fontsize=16)
plt.ylabel("Loss",fontsize = 16)
plt.ylim([0,max(plt.ylim())])
plt.title("Eğitim ve Test Kayıp Grafği",fontsize= 16)
plt.show()

Şekil 12- Eğitim ve Test Setlerinin Başarı ve Kayıp Grafikleri

Bu grafiklerin ilki olan eğitim ve test veri seti için başarı grafiğine bakacak olursak epoch sayısı arttıkça aralarında tam bir açılım gözlemleyememişiz. Bu durum modelin eğitim veri setindeki başarıyı test veri setine başarıyla genelleme yeteneği olduğunu gösterir. Genellikle istenilen bir durumdur ve modelin genelleme yeteneğinin güçlü olduğunu gösterir.

Aynı şekilde ikinci grafik olan eğitim ve test veri seti için kayıp(loss) grafiğine baktığımızda ise epoch değeri arttıkça eğitim veri seti ile test veri seti belli bir noktaya kadar beraber düşüş gerçekleştirirken 35.tur ile 40.tur aralığında test veri setinin loss değerinin veri setine göre düşüş göstermediğini görüyoruz. 35.tur ile 40. tur arasında test veri seti kaybının artmaya başlaması, modelin o noktada eğitim veri setine aşırı uyum sağladığını ve bu noktadan sonra genelleme yeteneğinin azaldığını gösterir. Bu durumu önlemek veya hafifletmek için aşağıdaki adımlar düşünülebilir:

  1. Eğer mümkünse, daha fazla eğitim verisi eklemek, modelin genelleme yeteneğini artırabilir.
  2. Öğrenme hızı, batch boyutu gibi hiperparametreleri ayarlamak, modelin genelleme yeteneğini etkileyebilir.
  3. Modelin karmaşıklığını azaltmak, aşırı uyumu önleyebilir. Örneğin daha az katman veya daha az nöron içerebilecek bir model ile model eğitilerek çıktılar karşılaştırılabilir.

Modelimizin raporlarına ve confusion matrixine ulaşmak istersek aşağıdaki işlemleri gerçekleştirmemiz gerekir.

#Raporlama
x_test,y_test = test_generator.next()
y_pred = model.predict(x_test)
y_pred = np.argmax(y_pred,axis = 1)
y_test = np.argmax(y_test, axis =1)

target_names= list(waste_labels.keys())

print(classification_report(y_test,y_pred,target_names = target_names))

Şekil-13: Model Raporu
#Confusion Matrix 

cm = confusion_matrix(y_test,y_pred)

def plot_confusion_matrix(cm, classes,
normalize = False,
title= "Confusion Matrix",
cmap = plt.cm.Blues):
if normalize:
cm = cm.astype("float") / cm.sum(axis=1)[:,np.newaxis]

plt.figure(figsize=(8,6))
plt.imshow(cm,interpolation="nearest",cmap = cmap)
plt.title(title)
plt.colorbar()
tick_marks = np.arange(len(classes))

plt.xticks (tick_marks, classes, rotation = 45)
plt.yticks(tick_marks,classes)
fmt = "2.f" if normalize else "d"
thresh = cm.max() / 2.
for i,j in itertools.product(range(cm.shape[0]), range(cm.shape[1])):
plt.text(j,i, format(cm[i,j], fmt),
horizontalalignment = "center",
color="white" if cm[i, j] > thresh else "black"
)
plt.tight_layout ()
plt.ylabel("True Label", fontweight = "bold")
plt.xlabel("Predicted Label", fontweight = "bold")

plot_confusion_matrix(cm,waste_labels.keys(),
title = "Confusion Matrix",
cmap = plt.cm.OrRd)
Şekil-14:Confusion Matrix

Kurduğumuz modeli test etme işleminde ise daha önceden yaptığımız etiketleme bilgisini numerik bir biçimde tuttuğumuz waste_labels sözlüğü kullanılır.Test edilmek istenilen resimler manuel olarak rastgele seçildikten sonra aşağıda bulunan kodda olduğu gibi tanımlanır. (Google Drive için)

img1,p1,predicted_class1 =model_testing('/content/drive/MyDrive/Garbage classification/dataset-resized/metal/metal56.jpg')
img2,p2,predicted_class2 =model_testing('/content/drive/MyDrive/Garbage classification/dataset-resized/glass/glass90.jpg')
img3,p3,predicted_class3 =model_testing('/content/drive/MyDrive/Garbage classification/dataset-resized/paper/paper27.jpg')
img4,p4,predicted_class4 =model_testing('/content/drive/MyDrive/Garbage classification/dataset-resized/trash/trash89.jpg')

Resimlerin çıktısını bastırmak için aşağıdaki fonksiyon kullanılır.

def model_testing(path):
img =image.load_img(path,target_size=(target_size))
img = image.img_to_array(img,dtype=np.uint8)
img= np.array(img)/255.0
p = model.predict(img.reshape(1,224,224,3))
predicted_class = np.argmax(p[0])

return img,p,predicted_class

plt.figure(figsize=(20,60))

plt.subplot(141)
plt.axis("off")
plt.imshow(img1.squeeze())
plt.title("Maximum Probability:" + str(np.max(p1[0])) + "\n" + "Predicted Class:" + str(waste_labels['metal']))

plt.imshow(img1)

plt.subplot(142)
plt.axis("off")
plt.imshow(img2.squeeze())
plt.title("Maximum Probality:" + str(np.max(p2[0])) + "\n" + "Predicted Class:" + str(waste_labels["glass"]))
plt.imshow(img2)

plt.subplot(143)
plt.axis("off")
plt.imshow(img2.squeeze())
plt.title("Maximum Probality:" + str(np.max(p3[0])) + "\n" + "Predicted Class:" + str(waste_labels["paper"]))
plt.imshow(img3)

plt.subplot(144)
plt.axis("off")
plt.imshow(img4.squeeze())
plt.title("Maximum Probality:" + str(np.max(p4[0])) + "\n" + "Predicted Class:" + str(waste_labels["trash"]))
plt.imshow(img4)

Sonuç olarak burada ekrana getirdiğimiz görsellere ait model tahmin sonuçlarımızı ve modelin hangi oranla o sınıfa karar verdiğini aşağıdaki şekilde görmüş oluruz.



Source link

Be the first to comment

Leave a Reply

Your email address will not be published.


*