Derin Öğrenme (Deep Learning) - Bilgisayar Görmesi Örnekleri
Hayvanlar Fotoğrafı Tahmini - (Functional API Model Kullanılarak)
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.