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

Çiçek Fotoğrafları Tahmini- (Sequential API Model Kullanarak)

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

Konu: 5 farklı çiçek grubuna ait resimler Derin Öğrenme modeli ile eğitilerek yeni girilen çiçek türünü tahmin etmek.

Veri seti: 5 farklı klasör içersinde 'papatya', 'karahindiba', 'gül', 'ayçiçeği' ve 'lale' çiçeklerine ait farklı boyutlarda toplamda 3670 adet fotoğrafın bulunduğu bir veri setidir.

Veri seti okuma işlemleri

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
%matplotlib inline
import seaborn as sns
import warnings
warnings.filterwarnings("ignore")

import glob
import pathlib
import PIL

from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense,Dropout,Conv2D,Rescaling,MaxPooling2D,Flatten
from tensorflow.keras.utils import plot_model,image_dataset_from_directory,get_file
from tensorflow.keras.preprocessing import image
from tensorflow.keras.models import model_from_json
from tensorflow.data import AUTOTUNE
from tensorflow.keras.applications.efficientnet_v2 import EfficientNetV2B1

from tensorflow.compat.v1 import ConfigProto,InteractiveSession
config = ConfigProto()
config.gpu_options.allow_growth = True
session = InteractiveSession(config=config)

Veri setini aşağıda bulunan kod yardımı ile indirebilirsiniz.

dataset_url = "https://storage.googleapis.com/download.tensorflow.org/example_images/flower_photos.tgz"
data_dir = tf.keras.utils.get_file(origin=dataset_url,
                                   fname='flower_photos',
                                   untar=True)
data_dir = pathlib.Path(data_dir)
print(data_dir)

Çıktı:

C:\Users\(Kullanıcı Adı)\.keras\datasets\flower_photos

 Yukarıdaki çıktıda da görüldüğü üzere veri seti ilgili adrese indirelecektir. İndirilen fotoğraf sayısını inceleyelim.

len(list(data_dir.glob("*/*.jpg")))

Çıktı:

3670
#Veri setinde bulunan "roses" klasöründen bir tane örnek fotoğraf
roses=list(data_dir.glob("roses/*"))
PIL.Image.open(str(roses[0]))

Çıktı:

#Veri setinde bulunan "sunflowers" klasöründen bir tane örnek fotoğraf
sunflowers=list(data_dir.glob("sunflowers/*"))
PIL.Image.open(str(sunflowers[0]))

Çıktı:

Veri seti için Train ve Test verilerini ayırma işlemi

batch_size=32
img_height=180
img_width=180

#Train veri seti
train_ds=image_dataset_from_directory(
    directory=data_dir, #dizin adı
    validation_split=0.2, #Test verisi boyutu
    subset="training", #eğitim mi test mi?
    seed=123,
    image_size=(img_height,img_width),
    batch_size=batch_size
)

#Test veri seti
test_ds=image_dataset_from_directory(
    directory=data_dir, #dizin adı
    validation_split=0.2, #Test verisi boyutu
    subset="validation", #eğitim mi test mi?
    seed=123,
    image_size=(img_height,img_width),
    batch_size=batch_size
)

Çıktı:

Found 3670 files belonging to 5 classes.
Using 2936 files for training.
Found 3670 files belonging to 5 classes.
Using 734 files for validation.

Yukarıdaki çıktıda görüldüğü üzere 3670 resimli 5 sınıftan oluşan veri setinde 2936 tane rasgele resim "train" için 734 tane resim ise "test" için kullanılacaktır.

#Verilerin bulunduğu klasörler(resimlerin sınıfları) listeleme işlemi
class_names=train_ds.class_names
print(class_names)

Çıktı:

['daisy', 'dandelion', 'roses', 'sunflowers', 'tulips']
#Train için ayrılan resimlerden birkaç tanesini görüntüleyelim
plt.figure(figsize=(15,10))

for image,label in train_ds.take(1):
    for i in range(25):
        ax=plt.subplot(5,5,i+1)
        plt.imshow(image[i].numpy().astype("uint8"))
        plt.xticks([])
        plt.yticks([])
        plt.title(class_names[label[i]])

Çıktı:

#32'li olarak gruplandırılan(bacth_size) Train verilerinin grup sayısı
print("Grup sayısı:{}".format(len(train_ds)))

#Train verilerindeki resim ve label boyutları
for image_batch,label_batch in train_ds.take(1):
    print("Resim boyutları:{}".format(image_batch.shape))
    print("Label boyutları:{}".format(label_batch.shape))

Çıktı:

Grup sayısı:92
Resim boyutları:(32, 180, 180, 3)
Label boyutları:(32,)
#32'li olarak gruplandırılan(bacth_size) Test verilerinin grup sayısı
print("Grup sayısı:{}".format(len(test_ds)))
#Test verilerindeki resim ve label boyutları
for image_batch,label_batch in test_ds.take(1):
    print("Resim boyutları:{}".format(image_batch.shape))
    print("Label boyutları:{}".format(label_batch.shape))

Çıktı:

Grup sayısı:23
Resim boyutları:(32, 180, 180, 3)
Label boyutları:(32,)

Model oluşturma ve model eğitme işlemleri

Bilgisayar CPU'sunun etkin bir şekilde kullanılabilmesi için aşağıdaki komutun eklenmesi gerekmetekdir.

autotune=AUTOTUNE

train_ds = train_ds.cache().prefetch(buffer_size=autotune)
test_ds = test_ds.cache().prefetch(buffer_size=autotune)
num_classes = len(class_names)

#Model ve katmanlarını oluşturma işlemleri
model=Sequential()
model.add(Rescaling(1./255,input_shape=(img_height,img_width,3)))
model.add(Dropout(rate=0.2))
model.add(Conv2D(32,3,activation="relu"))
model.add(MaxPooling2D())
model.add(Dropout(rate=0.2))
model.add(Conv2D(32,3,activation="relu"))
model.add(MaxPooling2D())
model.add(Flatten())
model.add(Dropout(rate=0.2))
model.add(Dense(128,activation="relu"))
model.add(Dropout(rate=0.2))
model.add(Dense(64,activation="relu"))
model.add(Dropout(rate=0.2))
model.add(Dense(32,activation="relu"))
model.add(Dense(num_classes,activation="softmax"))
#Model özeti
model.summary()

Çıktı:

Model: "sequential"
_________________________________________________________________
 Layer (type)                Output Shape              Param #   
=================================================================
 rescaling (Rescaling)       (None, 180, 180, 3)       0         
                                                                 
 dropout (Dropout)           (None, 180, 180, 3)       0         
                                                                 
 conv2d (Conv2D)             (None, 178, 178, 32)      896       
                                                                 
 max_pooling2d (MaxPooling2D  (None, 89, 89, 32)       0         
 )                                                               
                                                                 
 dropout_1 (Dropout)         (None, 89, 89, 32)        0         
                                                                 
 conv2d_1 (Conv2D)           (None, 87, 87, 32)        9248      
                                                                 
 max_pooling2d_1 (MaxPooling  (None, 43, 43, 32)       0         
 2D)                                                             
                                                                 
 flatten (Flatten)           (None, 59168)             0         
                                                                 
 dropout_2 (Dropout)         (None, 59168)             0         
                                                                 
 dense (Dense)               (None, 128)               7573632   
                                                                 
 dropout_3 (Dropout)         (None, 128)               0         
                                                                 
 dense_1 (Dense)             (None, 64)                8256      
                                                                 
 dropout_4 (Dropout)         (None, 64)                0         
                                                                 
 dense_2 (Dense)             (None, 32)                2080      
                                                                 
 dense_3 (Dense)             (None, 5)                 165       
                                                                 
=================================================================
Total params: 7,594,277
Trainable params: 7,594,277
Non-trainable params: 0
model.compile(
    optimizer="adam",
    loss="sparse_categorical_crossentropy",
    metrics=["accuracy"]    
)
model.fit(
    train_ds,
    validation_data=test_ds,
    epochs=3,
    verbose=1,
    batch_size=64
)

Çıktı:

Epoch 1/3
92/92 [==============================] - 162s 2s/step - loss: 1.6421 - accuracy: 0.2575 - val_loss: 1.5152 - val_accuracy: 0.3338
Epoch 2/3
92/92 [==============================] - 149s 2s/step - loss: 1.4200 - accuracy: 0.3621 - val_loss: 1.3218 - val_accuracy: 0.5000
Epoch 3/3
92/92 [==============================] - 157s 2s/step - loss: 1.2458 - accuracy: 0.4690 - val_loss: 1.2396 - val_accuracy: 0.5136

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ı:

Modelin başarı yüzdesini gözlemleyelim;

_, accuracy=model.evaluate(test_ds)
print('Accuracy: %.2f' % (accuracy*100))

Çıktı:

23/23 [==============================] - 6s 241ms/step - loss: 1.2396 - accuracy: 0.5136
Accuracy: 51.36

Sonuç olarak; Derin Öğrenme Sequential API(sıralı) modeli ile veri setine tahmin etme işlemi uygulandı ve %51.36 oranında başarı elde edilmiş oldu. (Bir sonraki derste aynı veri setini Fonksiyonel API kullanarak tekrar derlendi ve başarı oranı %91 olarak tahmin edildi.) Bu model için başarı oranı artırılmak istenebilir, bunun için birkaç adım denenebilir, bu adımlardan bazıları yüksek bilgisayar gücü gerektirebilecektir. Bunlar;

  • Veri seti temizlemesi daha iyi yapılabilir.
  • Model katmanlarına "Dropout" katmanları da eklenebilir.
  • Model gizli katmanları artırılabilir.
  • Gizli katmanlardaki nöron sayısı artırılabilir.
  • Model fit işleminde epoch değeri artırılabilir.

Model kaydetme, okuma ve tahminleme işlemleri

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

#Model ağırlıkları kayıt işlemi
model.save_weights("modelFlowerSequential.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('modelFlowerSequential.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("modelFlowerSequential.h5")

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

Çıktı:

Model ve ağırlıkları dosya konumundan okundu.
def predictImage(img_path):
    #Resim 180x180 boyutlarında ve kendi rengi ile okunur.
    img = image.load_img(img_path, target_size=(180,180))
  
    #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=[1,2,3,4,5]
    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:",class_names[np.argmax(pred[0])]

Bir kaç tane çiçek fotoğrafı yükleyelim ve tahminleme işlemi sonrasında yüklenen fotoğrafların türünü gözlemleyelim.

predictImage("img7.png")

Çıktı:

('Tahmin edilen değer:', 'dandelion')

predictImage("img8.jpg")

Çıktı:

('Tahmin edilen değer:', 'tulips')

predictImage("img9.jpg")

Çıktı:

('Tahmin edilen değer:', 'dandelion'

1. ve 2. fotoğraflarda doğru tahminlemeye yaklaşılmış 3. fotoğrafta ise doğru bir tahminleme yapılmıştır. Modele iyileştirme yapılması gerekmektedir. 

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.