Derin Öğrenme (Deep Learning) - Bilgisayar Görmesi Örnekleri

El Yazması Tahmini

Yayın tarihi :28-Şub-22
Bölüm kodlarını ve/veya veri setlerini indir.

Konu: 60.000 adet el yazması rakam resimlerini Derin Öğrenme modeli ile eğitip yeni girilen el yazması rakamı tahmin etmek.

Veri seti: Keras kütüphanesi altında hazır olarak bulunan "mnist" veri setidir. Veri setinde toplam (train ve test verileri dahil) 70.000 adet 28x28 boyutlarında resim ve bu resimlere karşılık gelen sayılar bulunmaktadır.

Veri seti okuma ve model eğitme işlemleri

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
%matplotlib inline
import seaborn as sns

from sklearn.preprocessing import MinMaxScaler
from sklearn.model_selection import train_test_split
from sklearn.metrics import  r2_score

from tensorflow.keras import datasets
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense,Conv2D,Dropout,MaxPooling2D,Flatten
from tensorflow.keras.utils import plot_model
from tensorflow.keras.models import model_from_json
from tensorflow.keras.preprocessing import image
#Veri seti keras veri setleri içinden yüklenir
#Veri seti içersinde test ve train verileri ayrılır.
(train_images,train_labels),(test_images,test_labels)=datasets.mnist.load_data()
print("Train resim boyutları:",train_images.shape)
print("Train resimlerin değerler listesi boyutları:",train_labels.shape)
print("Test resim boyutları:",test_images.shape)
print("Test resimlerin değerler listesi boyutları:",test_labels.shape)

Çıktı:

Train resim boyutları: (60000, 28, 28)
Train resimlerin değerler listesi boyutları: (60000,)
Test resim boyutları: (10000, 28, 28)
Test resimlerin değerler listesi boyutları: (10000,)

60.000 adet resim ve açıklaması train verileri olarak kullanılacakken, 10.000 adet resim ve açıklaması da oluşturulan modelin başarı  oranını gözlemlemek için test verileri olarak kullanılacaktır. Train ve test resimleri içersinde fotoğrafları temsil eden matrisler bulunmaktadır. Bunlardan bir tanesini gözlemleyelim;

print(train_images[1234])

Çıktı:

[[  0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0
    0   0   0   0   0   0   0   0   0   0]
 [  0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0
    0   0   0   0   0   0   0   0   0   0]
 [  0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0
    0   0   0   0   0   0   0   0   0   0]
 [  0   0   0   0   0   0   0   0   0   0   0   0 149 255 129  37   0   0
    0   0   0   0   0   0   0   0   0   0]
 [  0   0   0   0   0   0   0   0   0   0   0   0 149 253 252 215  60   7
    0   0   0   0   0   0   0   0   0   0]
 [  0   0   0   0   0   0   0   0   0   0   0   0  53 150 249 252 252  38
    0   0   0   0   0   0   0   0   0   0]
 [  0   0   0   0   0   0   0   0   0   0   0   0   0   0 138 252 252 177
    0   0   0   0   0   0   0   0   0   0]
 [  0   0   0   0   0   0   0   0   0   0   0   0   0   0   7 129 252 243
....]

Yukarıdaki örnekte görüldüğü gibi resim (28,28) boyutunda 0-255 değerleri arasında sayısal değerleri içeren matristen oluşmaktadır. Bu resimleri ve resimlere karşılık gelen değerleri görselleştirelim.

#Veri seti içersinde bulunan fotoğrafları ve fotoğraf karşılıklarını gözlemleyelim
plt.figure(figsize=(20,12))
for i in range(25):
    plt.subplot(5,5,i+1)
    plt.xticks([]) #x ekseni rakamları kaldır
    plt.yticks([]) #y ekseni rakamları kaldır
    plt.imshow(train_images[i],cmap="gray")
    plt.xlabel(train_labels[i],color="blue",size="15")
plt.show()

Çıktı:

Bilgisayarı fazla yormaması için matris değerleri 255'e bölünerek tüm değerler 0-1 aralığına getirilir.(min değer:0, max değer:255 olduğu için)

#train verileri 0-1 aralığına getirilir.
train_images=train_images/255
#test verileri 0-1 aralığına getirilir.
test_images=test_images/255

Veri setinde bulunan train ve test matrisleri sırasıyla (60000,28,28) ve (10000,28,28) boyutlarında olduğu için oluşturulacak modelde başarılı bir şekilde eğitebilmek ive değerlendirebilmek çin boyut değerini yeniden oluşturarak (60000,28,28,1) ve (10000,28,28,1) değerine getirelim.  

n_rows=train_images.shape[1]
n_cols=train_images.shape[2]
train_count=train_images.shape[0]
test_count=test_images.shape[0]

#Resimlerin boyutları düzenlenir
train_images=train_images.reshape(train_count,n_rows,n_cols,1)
test_images=test_images.reshape(test_count,n_rows,n_cols,1)

print("Train resimleri yeni boyutları:",train_images.shape)
print("Test resimleri yeni boyutları:",test_images.shape)

Çıktı:

Train resimleri yeni boyutları: (60000, 28, 28, 1)
Test resimleri yeni boyutları: (10000, 28, 28, 1)

Veri setinde tüm hazırlıklar yapıldığı için artık model oluşturma ve katman ekleme işlemlerine geçilebilir. 

#Model oluşturma ve katman ekleme işlemleri
model=Sequential()
model.add(Conv2D(32,kernel_size=(3,3),activation="relu",input_shape=(n_rows,n_cols,1))) #giriş ve 1.Evrişim katmanı
model.add(Conv2D(64,kernel_size=(3,3),activation="relu")) #2.Evrişim katmanı
model.add(MaxPooling2D(pool_size=(2,2))) #Havuzlama katmanı
model.add(Dropout(rate=0.2)) #Verilerin %20'si rasgele atılarak gürültüleri azaltma işlemi yapılır
model.add(Flatten()) #Resim boyutları tek boyuta çevrildi
model.add(Dense(256,activation="relu")) #1.Gizli katman
model.add(Dropout(rate=0.2))#Verilerin %20'si rasgele atılarak gürültüleri azaltma işlemi yapılır
model.add(Dense(128,activation="relu")) #2.Gizli katman
model.add(Dropout(rate=0.2))#Verilerin %20'si rasgele atılarak gürültüleri azaltma işlemi yapılır
model.add(Dense(64,activation="relu")) #3.Gizli katman
model.add(Dropout(rate=0.2))#Verilerin %20'si rasgele atılarak gürültüleri azaltma işlemi yapılır
model.add(Dense(32,activation="relu")) #4.Gizli katman
model.add(Dropout(rate=0.2))#Verilerin %20'si rasgele atılarak gürültüleri azaltma işlemi yapılır
model.add(Dense(10,activation="softmax")) #Çıkış katmanı (10: 0-9 aralığında 10 farklı türden resmi temsil eder)

Oluşturulan modelin katmanları aşağıda görselleştirilmiştir. Bilgisayar gücüne göre katman eklemesi veya çıkartması yapılabilir.

plot_model(model,show_shapes=True)

Çıktı:

Model derleme aşamasında kayıp fonksiyonu(loss) olarak "sparse_categorical_crossentropy" kullanıldı. Bunun nedeni; iki veya daha fazla etiket sınıfı olduğunda bu çapraz entropi kaybı işlevi kullanılır. Bizim çıktı değerimiz 10 adet olduğundan dolayı bu kayıp fonksiyonu seçilmiştir.

model.compile(optimizer="adam",loss="sparse_categorical_crossentropy",metrics=["accuracy"])

Model eğitme aşamasında epochs değeri(10) veya batch_size değeri(32) bilgisayar gücüne göre değiştirilebilir.

model.fit(x=train_images,y=train_labels,epochs=10,batch_size=32,verbose=2,validation_data=(test_images,test_labels))

Çıktı:

...
Epoch 8/10
1875/1875 - 126s - loss: 0.0262 - accuracy: 0.9937 - val_loss: 0.0397 - val_accuracy: 0.9905 - 126s/epoch - 67ms/step
Epoch 9/10
1875/1875 - 241s - loss: 0.0244 - accuracy: 0.9943 - val_loss: 0.0524 - val_accuracy: 0.9911 - 241s/epoch - 129ms/step
Epoch 10/10
1875/1875 - 238s - loss: 0.0204 - accuracy: 0.9948 - val_loss: 0.0472 - val_accuracy: 0.9902 - 238s/epoch - 127ms/step

Kayıp değerleri(loss) ve başarı değerlerini(accuracy) train ve test verilerindeki durumlarına göre grafiksel olarak gözlemleyebiliriz. 

fig=plt.figure(figsize=(20,6))

#Accuracy Grafiklemesi
x1=fig.add_subplot(121)
x1.plot(model.history.history['accuracy'])
x1.plot(model.history.history['val_accuracy'])
x1.set_title('Model accuracy')
x1.set_ylabel('Accuracy')
x1.set_xlabel('Epoch')
x1.legend(['Train', 'Test'], loc='upper left')

#Loss Grafiklemesi
x2=fig.add_subplot(122)
x2.plot(model.history.history['loss'])
x2.plot(model.history.history['val_loss'])
x2.set_title('Model loss')
x2.set_ylabel('Loss')
x2.set_xlabel('Epoch')
x2.legend(['Train', 'Test'], loc='upper left')

plt.show()

 Çıktı:

Test verileri ile başarı oranı değerini gözlemleyelim;

model.evaluate(test_images,test_labels)

Çıktı:

313/313 [==============================] - 10s 33ms/step - loss: 0.0472 - accuracy: 0.9902

[0.04722350835800171, 0.9901999831199646]

Başarı değerimiz %99.02 olarak gözlemlendi.

 Model kaydetme, okuma ve tahminleme işlemleri

Oluşturulan modeli daha sonra kullanmak üzere "JSON" formatında kaydedelim.

#Model kayıt işlemi
model_json=model.to_json()
with open("model.json", "w") as json_file:
    json_file.write(model_json)

#Model ağırlıkları kayıt işlemi
model.save_weights("model.h5")

print("Model ve ağırlıkları dosya konumuna kaydedildi.")

Çıktı:

Model ve ağırlıkları dosya konumuna kaydedildi.
#Modeli yükle
json_file = open('model.json', 'r')
loaded_model_json = json_file.read()
json_file.close()
loaded_model = model_from_json(loaded_model_json)

# Model ağırlıklarını yükle
loaded_model.load_weights("model.h5")

print("Model ve ağırlıkları dosya konumundan okundu.")

Çıktı:

Model ve ağırlıkları dosya konumundan okundu.

Model ve ağırlıkları başarı bir şekilde okundu ve modelin adı "loaded_model" olarak atandı. Bu model artık istenilen projede sadece "Model yükleme" işlemi yapılarak kullanılabilecektir. 

Veri setine göre tahmin edilecek olan etiket değerleri; [0,1,2,3,4,5,6,7,8,9] olmak üzere 10 tane değerdir. Model tahmin değeri olarak sayısal değerler oluşturacaktır. Oluşan bu sayısal değerlerden en büyük değer tahmin edilecek değeri göstermektedir.

def predictImage(img_path):
    #Resim 28x28 boyutlarında "gri" tonda okunur.
    img = image.load_img(img_path, target_size=(28,28,1),color_mode="grayscale")
    
    #Okunan resim matrise çevrilir.
    img_array = image.img_to_array(img)
    img_batch = np.expand_dims(img_array, axis=0)
    
    #Tahminleme işlemi uygulanır
    pred=loaded_model.predict(img_batch)
    
    #Grafikleme yapılır.
    labels=[0,1,2,3,4,5,6,7,8,9]
    fig=plt.figure(figsize=(15,4))

    x1=fig.add_subplot(121)
    x1.imshow(img)
    x1.set_title("Yüklenen Fotoğraf")
    x1.set_xticks([])
    x1.set_yticks([])

    x2=fig.add_subplot(122)
    x2.bar(labels,pred[0])
    x2.set_title("Tahmin Değeri")
    
    return "Tahmin edilen değer:",np.argmax(pred[0])

Oluşturulan "predictImage" fonksiyonuna istenilen boyuttaki fotoğraf yüklenebilir. Fonksiyon içersinde fotoğrafın boyutu 28x28 olarak ayarlanacak ve tahminleme işlemine geçilecektir.

predictImage("img1.png")

Çıktı:

('Tahmin edilen değer:', 2)
predictImage("img2.png")

Çıktı:

('Tahmin edilen değer:', 5)
Paylaş:

Yorum Yap (*Yorumunuza kod eklemek isterseniz Kod Parçacığı Ekle butonuna tıklayarak ekleyebilirsiniz.)

Yorumlar

Henüz hiç yorum yapılmamış, ilk yorum yapan sen ol.