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

Hayvanlar Fotoğrafı Tahmini - (Functional API Model Kullanılarak)

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

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

Veri seti: 151 farklı klasör içersinde hayvan türlerine ait farklı boyutlarda toplamda 6270 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,Model
from tensorflow.keras.layers import Dense,Dropout,BatchNormalization
from tensorflow.keras.utils import plot_model,image_dataset_from_directory
from tensorflow.keras.models import model_from_json
from tensorflow.keras.preprocessing import image
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 seti "Kaggle" da bulunmaktadır. Kaggle'dan indirmek için tıklayınız. İndirdikten sonra çalışma dosyasının bulunduğu konuma çıkartabilirsiniz.

#Veri seti adresi tanımlanır
data_dir=pathlib.Path("dataset/dataset/")

#Veri setinde bulunan toplam resim sayısı
image_count=len(list(data_dir.glob("*/*")))
print("Toplam resim sayısı:{}".format(image_count))

Çıktı:

Toplam resim sayısı:6270
#Veri setinde bulunan "canis-lupus" klasöründen bir tane örnek fotoğraf
canis_lupus=list(data_dir.glob("canis-lupus/*"))
PIL.Image.open(canis_lupus[0])

Çıktı:

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

Çıktı:

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

batch_size=32 #alınacak parti boyutu
img_height=224 #resim yüksekliği
img_width=224 #resim genişliği
#Train verilerinin tanımlanması
train_ds=image_dataset_from_directory(
    directory=data_dir, #resimlerin bulunduğu dizin
    validation_split=0.2, #test için ayrılacak oran
    subset="training", #eğitim verisi(training) mi, test verisi(validation) mi?
    seed=42, #rasgele değer 
    image_size=(img_height,img_width), #resim boyutu
    batch_size=32 #alınacak parti boyutu
)

Çıktı:

Found 6270 files belonging to 151 classes.
Using 5016 files for training.

Yukarıdaki çıktıda görüldüğü üzere 6270 resimli 151 sınıftan oluşan veri setinde 5016 tane rasgele resim "train" için kullanılacaktır.

#Test verilerinin tanımlanması
test_ds=image_dataset_from_directory(
    directory=data_dir, #resimlerin bulunduğu dizin
    validation_split=0.2, #test için ayrılacak oran
    subset="validation", #eğitim verisi(training) mi, test verisi(validation) mi?
    seed=42, #rasgele değer 
    image_size=(img_height,img_width), #resim boyutu
    batch_size=32 #alınacak parti boyutu
)

Çıktı:

Found 6270 files belonging to 151 classes.
Using 1254 files for validation.

 Yukarıdaki çıktıda görüldüğü üzere 6270 resimli 151 sınıftan oluşan veri setinde 1254 tane rasgele resim "test" için kullanılacaktır.

#Verilerin bulunduğu klasörler(resimlerin sınıfları) listeleme işlemi
class_names=train_ds.class_names
#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ı:157
Resim boyutları:(32, 224, 224, 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ı:157
Resim boyutları:(32, 224, 224, 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)

EfficientNetV2B1 ile ImageNet üzerinde önceden eğitilmiş ağırlıklarla yüklenen bir Keras görüntü sınıflandırma modeli döndürür. Bizde bu modeli başlangıç olarak kullanarak başarı oranımızı artıracağız. Modelin görselleştirilmesi aşamasında EfficientNetV2B1 ile modele eklenen katmanları görüntüleyebilirsiniz.

efficientNet =EfficientNetV2B1(
    include_top=False,
    input_shape=(224,224,3),
    pooling='avg',
    classes = 3, 
    weights='imagenet')
num_classes=len(class_names) #Çıktı boyutu

x=efficientNet.output
x=BatchNormalization()(x)
x=Dense(512,activation="relu")(x)
x=Dropout(rate=0.2)(x)
x=Dense(256,activation="relu")(x)
x=Dropout(rate=0.2)(x)
x=Dense(num_classes,activation="softmax")(x)
model=Model(efficientNet.input,x)
#Modelin görüntüsünü inceleyelim
plot_model(model,show_shapes=True)

Çıktı:

model.compile(
    optimizer="adam",
    loss="sparse_categorical_crossentropy",
    metrics=["accuracy"]    
)
model.fit(
    train_ds,
    validation_data=test_ds,
    epochs=10,
    verbose=1,
    batch_size=64
)

Çıktı:

...
Epoch 8/10
157/157 [==============================] - 1132s 7s/step - loss: 0.3996 - accuracy: 0.8975 - val_loss: 1.0898 - val_accuracy: 0.7895
Epoch 9/10
157/157 [==============================] - 1034s 7s/step - loss: 0.1770 - accuracy: 0.9553 - val_loss: 1.1360 - val_accuracy: 0.7759
Epoch 10/10
157/157 [==============================] - 1023s 7s/step - loss: 0.1910 - accuracy: 0.9504 - val_loss: 1.0959 - val_accuracy: 0.7903

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

40/40 [==============================] - 49s 1s/step - loss: 1.0959 - accuracy: 0.7903
Accuracy: 79.03

Sonuç olarak; Derin Öğrenme Functional API modeline önceden ağırlıkları hesaplanmış EfficientNetV2B1 eklenmesi sonucunda %79.03 oranında başarı elde edilmiş oldu. 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("modelAnimalsFunctional.json", "w") as json_file:
    json_file.write(model_json)

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

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

Çıktı:

Model ve ağırlıkları dosya konumundan okundu.
 class_names=['acinonyx-jubatus', 'aethia-cristatella', 'agalychnis-callidryas', 'agkistrodon-contortrix',
                        'ailuropoda-melanoleuca', 'ailurus-fulgens', 'alces-alces', 'anas-platyrhynchos',
                        'ankylosaurus-magniventris', 'apis-mellifera', 'aptenodytes-forsteri', 'aquila-chrysaetos',
                        'ara-macao', 'architeuthis-dux', 'ardea-herodias', 'balaenoptera-musculus', 'betta-splendens', 
                        'bison-bison', 'bos-gaurus', 'bos-taurus', 'bradypus-variegatus', 'branta-canadensis', 
                        'canis-lupus', 'canis-lupus-familiaris', 'carcharodon-carcharias', 'cardinalis-cardinalis', 
                        'cathartes-aura', 'centrochelys-sulcata', 'centruroides-vittatus', 'ceratitis-capitata', 
                        'ceratotherium-simum', 'chelonia-mydas', 'chrysemys-picta', 'circus-hudsonius', 'codium-fragile',
                        'coelacanthiformes', 'colaptes-auratus', 'connochaetes-gnou', 'correlophus-ciliatus', 
                        'crocodylus-niloticus', 'crotalus-atrox', 'crotophaga-sulcirostris', 'cryptoprocta-ferox', 
                        'cyanocitta-cristata', 'danaus-plexippus', 'dasypus-novemcinctus', 'delphinapterus-leucas', 
                        'dendrobatidae', 'dermochelys-coriacea', 'desmodus-rotundus', 'diplodocus', 'dugong-dugon', 
                        'eidolon-helvum', 'enhydra-lutris', 'enteroctopus-dofleini', 'equus-caballus', 'equus-quagga', 
                        'eudocimus-albus', 'eunectes-murinus', 'falco-peregrinus', 'felis-catus', 'formicidae', 
                        'gallus-gallus-domesticus', 'gavialis-gangeticus', 'geococcyx-californianus', 'giraffa-camelopardalis',
                        'gorilla-gorilla', 'haliaeetus-leucocephalus', 'hapalochlaena-maculosa', 'heloderma-suspectum', 
                        'heterocera', 'hippopotamus-amphibius', 'homo-sapiens', 'hydrurga-leptonyx', 'icterus-galbula', 
                        'icterus-gularis', 'icterus-spurius', 'iguana-iguana', 'iguanodon-bernissartensis', 'inia-geoffrensis',
                        'lampropeltis-triangulum', 'lemur-catta', 'lepus-americanus', 'loxodonta-africana', 
                        'macropus-giganteus', 'malayopython-reticulatus', 'mammuthus-primigeniu', 'martes-americana',
                        'megaptera-novaeangliae', 'melanerpes-carolinus', 'mellisuga-helenae', 'mergus-serrator', 
                        'mimus-polyglottos', 'monodon-monoceros', 'musca-domestica', 'odobenus-rosmarus', 'okapia-johnstoni',
                        'ophiophagus-hannah', 'orcinus-orca', 'ornithorhynchus-anatinus', 'ovis-aries', 'ovis-canadensis',
                        'panthera-leo', 'panthera-onca', 'panthera-pardus', 'panthera-tigris', 'pantherophis-alleghaniensis',
                        'pantherophis-guttatus', 'papilio-glaucus', 'passerina-ciris', 'pavo-cristatus', 'periplaneta-americana', 
                        'phascolarctos-cinereus', 'phoebetria-fusca', 'phoenicopterus-ruber', 'phyllobates-terribilis', 
                        'physalia-physalis', 'physeter-macrocephalus', 'poecile-atricapillus', 'pongo-abelii', 'procyon-lotor', 
                        'pteranodon-longiceps', 'pterois-mombasae', 'pterois-volitans', 'puma-concolor', 'rattus-rattus', 
                        'rusa-unicolor', 'salmo-salar', 'sciurus-carolinensis', 'smilodon-populator', 'spheniscus-demersus',
                        'sphyrna-mokarran', 'spinosaurus-aegyptiacus', 'stegosaurus-stenops', 'struthio-camelus', 'tapirus',
                        'tarsius-pumilus', 'taurotragus-oryx', 'telmatobufo-bullocki', 'thryothorus-ludovicianus', 
                        'triceratops-horridus', 'trilobita', 'turdus-migratorius', 'tursiops-truncatus', 'tyrannosaurus-rex', 
                        'tyrannus-tyrannus', 'ursus-arctos-horribilis', 'ursus-maritimus', 'varanus-komodoensis', 'vulpes-vulpes',
                        'vultur-gryphus']
    
def predictImage(img_path):
    #Resim 224x224 boyutlarında ve kendi rengi ile okunur.
    img = image.load_img(img_path, target_size=(224,224))
  
    #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=class_names
    
    plt.imshow(img)
    plt.title("Yüklenen Fotoğraf")
    plt.xticks([])
    plt.yticks([])
    
    fig=plt.figure(figsize=(20,4))
    plt.bar(labels,pred[0])
    plt.title("Tahmin Değeri")
    plt.xticks(rotation=90,fontsize=8)
    
    ratio=np.round(pred[0][np.argmax(pred[0])]*100,2)
    type_=class_names[np.argmax(pred[0])]
 
    return "%{} oranında '{}' olarak tahmin edilmiştir.".format(ratio,type_)

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

predictImage("img10.jpg")

Çıktı:

"%86.89 oranında 'canis-lupus' olarak tahmin edilmiştir."



predictImage("img11.jpg")

Çıktı:

"%99.99 oranında 'ailuropoda-melanoleuca' olarak tahmin edilmiştir."



predictImage("img12.jpg")

Çıktı:

"%66.86 oranında 'pantherophis-alleghaniensis' olarak tahmin edilmiştir."



3 fotoğraf denemesinde de yaklaşık olarak başarılı bir şekilde tahminleme yapılmış oldu. 

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.