İçeriğe geç

Derin Öğrenme #3: iPhone ile Çekilen Resimlerden Görüntü Sınıflandırma Modeli Geliştirme (Kapak, Beyblade ve Yoyo Tanıma)

Not: Bu yazı, öğrendiğim bilgileri daha iyi pekiştirmek ve yanlış bir yorum yapmamak adına GPT-4o tarafından incelenmiş ve düzenlenmiştir.

Kapak, Beyblade ve Yoyo Tanıma

Merhaba!
Bu yazıda, iPhone ile çektiğim çalışma masamda bulunan bir kapak, beyblade ve yoyo’yu tanıyabilen bir derin öğrenme modeli geliştirme sürecimi anlatacağım. Eğer elinizdeki fotoğrafları kullanarak basit bir nesne tanıma modeli yapmak istiyorsanız, adım adım bu projeyi nasıl gerçekleştirdiğimi buradan takip edebilirsiniz. Ayrıca projeye https://github.com/kudayDOTsite/Derin-renme adresinden de ulaşabilirsiniz.

Bu model sayesinde, iPhone ile çekilen bir fotoğrafı yüklediğimde model bunun bir kapak mı, beyblade mi yoksa yoyo mu olduğunu yüksek doğrulukla tahmin edebiliyor.
Projeyi gerçekleştirmek için TensorFlow ve Keras kütüphanelerini kullandım. Kodun tamamına göz attıktan sonra adım adım neler yaptığımı detaylandıracağım.

Tam Kod:

import tensorflow as tf
from tensorflow.keras import layers, models
from tensorflow.keras.preprocessing import image_dataset_from_directory
from PIL import Image, UnidentifiedImageError
import os
import matplotlib.pyplot as plt

# --- Dizinler ---
dataset_dir = '/Users/kuday/Documents/AI/Derin Öğrenme/2. ünite/dataset/augmented_train'
test_dir = '/Users/kuday/Documents/AI/Derin Öğrenme/2. ünite/dataset/test'

# --- Hatalı Resimleri Temizle ---
def remove_corrupt_images(directory):
    num_removed = 0
    for root, dirs, files in os.walk(directory):
        for file in files:
            file_path = os.path.join(root, file)
            try:
                img = Image.open(file_path)
                img.verify()  # Bozuksa hata fırlatır
            except (IOError, UnidentifiedImageError):
                print(f"Hatalı dosya kaldırıldı: {file_path}")
                os.remove(file_path)
                num_removed += 1
    print(f"Toplam {num_removed} dosya kaldırıldı.")

remove_corrupt_images(dataset_dir)
remove_corrupt_images(test_dir)

batch_size = 16

# --- Veri Setini Yükle ---
train_dataset = image_dataset_from_directory(
    dataset_dir,
    image_size=(64, 64),
    batch_size=batch_size,
    label_mode='int'
)

test_dataset = image_dataset_from_directory(
    test_dir,
    image_size=(64, 64),
    batch_size=batch_size,
    label_mode='int'
)

# --- Sınıfları Göster ---
class_names = train_dataset.class_names
print("Sınıflar:", class_names)

# --- Görselleştirme ---
plt.figure(figsize=(10, 10))
for images, labels in train_dataset.take(1):
    for i in range(min(9, len(images))):
        plt.subplot(3, 3, i + 1)
        plt.imshow(images[i].numpy().astype("uint8"))
        plt.title(class_names[labels[i]])
        plt.axis("off")
plt.show()

# --- Veri Artırma Katmanları ---
data_augmentation = tf.keras.Sequential([
    layers.RandomFlip("horizontal_and_vertical"),
    layers.RandomRotation(0.2),
    layers.RandomZoom(0.2),
])

# --- Normalleştirme ---
def normalize(image, label):
    image = tf.cast(image, tf.float32) / 255.0
    return image, label

# --- Doğrulama ve Eğitim Setini Ayır ---
val_size = int(len(train_dataset) * 0.2)
val_dataset = train_dataset.take(val_size)
train_dataset = train_dataset.skip(val_size)

# --- Veri Artırma ve Normalizasyon ---
train_dataset = train_dataset.map(lambda x, y: (data_augmentation(x), y))
train_dataset = train_dataset.map(normalize)
val_dataset = val_dataset.map(normalize)
test_dataset = test_dataset.map(normalize)

# --- CNN Modeli ---
def create_cnn_model(input_shape=(64, 64, 3), num_classes=3):
    model = models.Sequential([
        layers.Conv2D(32, (3, 3), activation='relu', input_shape=input_shape),
        layers.MaxPooling2D((2, 2)),

        layers.Conv2D(64, (3, 3), activation='relu'),
        layers.MaxPooling2D((2, 2)),

        layers.Conv2D(128, (3, 3), activation='relu'),
        layers.MaxPooling2D((2, 2)),

        layers.Flatten(),
        layers.Dense(128, activation='relu'),
        layers.Dropout(0.5),
        layers.Dense(num_classes, activation='softmax')
    ])
    return model

model = create_cnn_model()

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

model.summary()

# --- Model Eğitimi ---
epochs = 15
history = model.fit(
    train_dataset,
    validation_data=val_dataset,
    epochs=epochs
)

# --- Modeli Test Et ---
test_loss, test_accuracy = model.evaluate(test_dataset)
print(f"Test Doğruluğu: {test_accuracy:.2f}")

# --- Modeli Kaydet ---
model.save('/Users/kuday/Documents/AI/Derin Öğrenme/2. ünite/cnn_model.h5')
print("Model başarıyla kaydedildi!")

Kodun Adım Adım Açıklaması:

Kütüphaneler ve Dizinler

Kodun başında TensorFlow, Keras ve PIL (Pillow) gibi temel kütüphaneler projeye dahil ediliyor. Ayrıca os modülü, dosya işlemleri için kullanılıyor.

  • dataset_dir ve test_dir dizinleri, eğitim ve test veri setlerinin yollarını içeriyor. Fotoğraflar bu dizinlerde organize edilmiştir.

Hatalı Resimleri Temizleme

remove_corrupt_images fonksiyonu, bozuk ya da okunamayan resimleri tespit edip siliyor.

  • Bu işlem, veri setinde olası hataları önlemek için kritik. img.verify() metodu, resmin açılıp açılamayacağını kontrol eder ve bozuk resimlerde hata verir.

Veri Setini Yükleme ve Hazırlama

Kodun bu bölümünde, resimler doğrudan dizinden yükleniyor ve TensorFlow veri setine dönüştürülüyor. Bunu yapmak için image_dataset_from_directory fonksiyonunu kullanıyoruz.

train_dataset = image_dataset_from_directory(
    dataset_dir,
    image_size=(64, 64),
    batch_size=batch_size,
    label_mode='int'
)
  • dataset_dir: Eğitim verilerinin bulunduğu ana klasörün yolu.
  • image_size=(64, 64): Tüm resimler 64x64 piksele yeniden boyutlandırılıyor. Bu, modelin daha hızlı çalışmasını sağlıyor ve belleği daha verimli kullanıyor.
  • batch_size=16: Her seferinde 16 resim yükleniyor. Bu, eğitim sırasında işlemci veya GPU’yu fazla yormadan verimli bir şekilde çalışmamızı sağlıyor.
  • label_mode='int': Sınıf etiketleri tamsayı olarak ayarlanıyor (örneğin, 0 = kapak, 1 = beyblade, 2 = yoyo).

Benzer şekilde, test veri seti de aynı şekilde yükleniyor:

test_dataset = image_dataset_from_directory(
    test_dir,
    image_size=(64, 64),
    batch_size=batch_size,
    label_mode='int'
)

Sınıfların Görselleştirilmesi

Kodun bu kısmı, yüklenen resimlerin doğru bir şekilde etiketlenip etiketlenmediğini görselleştirmek için kullanılıyor.

plt.figure(figsize=(10, 10))
for images, labels in train_dataset.take(1):
    for i in range(min(9, len(images))):
        plt.subplot(3, 3, i + 1)
        plt.imshow(images[i].numpy().astype("uint8"))
        plt.title(class_names[labels[i]])
        plt.axis("off")
plt.show()
  • train_dataset.take(1): Eğitim veri setinden bir parti (batch) resim alır.
  • plt.imshow(): Resimleri ekrana basar.
  • plt.subplot(3, 3, i + 1): 3x3’lük bir ızgarada en fazla 9 resim gösterilir.
  • class_names[labels[i]]: Resmin üst kısmına, sınıf adı yazdırılır (örneğin “beyblade”).

Bu işlem, modelin doğru veriyle eğitildiğinden emin olmamı sağladı.

Veri Artırma (Data Augmentation)

Veri artırma, modelin daha fazla veri görmesini sağlar ve aşırı öğrenmenin (overfitting) önüne geçer. Burada, resimler rastgele çevrilir, döndürülür ve yakınlaştırılır.

data_augmentation = tf.keras.Sequential([
    layers.RandomFlip("horizontal_and_vertical"),
    layers.RandomRotation(0.2),
    layers.RandomZoom(0.2),
])
  • RandomFlip("horizontal_and_vertical"): Resim rastgele yatay ve dikey olarak çevrilir.
  • RandomRotation(0.2): Resim 20 dereceye kadar rastgele döndürülür.
  • RandomZoom(0.2): Resim rastgele %20 oranında yakınlaştırılır.

Normalizasyon

Resimlerin piksel değerleri 0-255 arasında değişir. Ancak sinir ağları, küçük değerlerle daha iyi çalışır. Bu nedenle tüm piksel değerleri 0 ile 1 arasına normalize ediliyor.

def normalize(image, label):
    image = tf.cast(image, tf.float32) / 255.0
    return image, label

Burada, resimler float32 formatına dönüştürülüyor ve 255’e bölünerek tüm piksel değerleri [0,1] aralığına getiriliyor.

Eğitim ve Doğrulama Veri Setlerini Ayırma

Veri setinin %20’si doğrulama (validation) için ayrılıyor. Bu sayede modelin eğitim sırasında ne kadar iyi performans gösterdiği izlenebiliyor.

val_size = int(len(train_dataset) * 0.2)
val_dataset = train_dataset.take(val_size)
train_dataset = train_dataset.skip(val_size)
  • train_dataset.take(val_size): İlk %20’lik kısım doğrulama için kullanılır.
  • train_dataset.skip(val_size): Geri kalan %80’lik kısım modelin eğitimi için ayrılır.

Modelin Oluşturulması (CNN)

Bu projede Convolutional Neural Network (CNN) kullanıyoruz. CNN, görüntü sınıflandırma için mükemmel sonuçlar veren bir ağ yapısıdır.

def create_cnn_model(input_shape=(64, 64, 3), num_classes=3):
    model = models.Sequential([
        layers.Conv2D(32, (3, 3), activation='relu', input_shape=input_shape),
        layers.MaxPooling2D((2, 2)),

        layers.Conv2D(64, (3, 3), activation='relu'),
        layers.MaxPooling2D((2, 2)),

        layers.Conv2D(128, (3, 3), activation='relu'),
        layers.MaxPooling2D((2, 2)),

        layers.Flatten(),
        layers.Dense(128, activation='relu'),
        layers.Dropout(0.5),
        layers.Dense(num_classes, activation='softmax')
    ])
    return model

Bu CNN modeli 3 ana katmandan oluşuyor:

  • Conv2D: Resimden özellik çıkarır. Filtre boyutu (3,3) ve relu aktivasyon fonksiyonu kullanılır.
  • MaxPooling2D: Resmi küçültür ve en belirgin özellikleri alır.
  • Flatten: Çok boyutlu veriyi tek boyuta çevirir.
  • Dense: Tam bağlantılı (fully connected) katman. 128 nöron içerir ve relu aktivasyonu kullanılır.
  • Dropout(0.5): Aşırı öğrenmeyi önlemek için %50 oranında nöronları devre dışı bırakır.
  • Dense(num_classes, activation='softmax'): Modelin son çıktısı 3 sınıfa ayrılır (kapak, beyblade, yoyo).

Modelin Eğitimi

Model adam optimizer ve sparse_categorical_crossentropy kayıp fonksiyonu ile derleniyor.

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

Eğitim 15 epoch boyunca gerçekleşiyor:

history = model.fit(
    train_dataset,
    validation_data=val_dataset,
    epochs=epochs
)

Modelin Test Edilmesi ve Kaydedilmesi

Model test veri seti üzerinde doğrulanıyor:

test_loss, test_accuracy = model.evaluate(test_dataset)
print(f"Test Doğruluğu: {test_accuracy:.2f}")

Son olarak model .h5 formatında kaydediliyor:

model.save('/Users/kuday/Documents/AI/Derin Öğrenme/2. ünite/cnn_model.h5')
print("Model başarıyla kaydedildi!")

Bu proje sayesinde artık telefonumla çektiğim fotoğrafları yükleyip anında sınıflandırabiliyorum!

Şimdi bu kodu çalıştırdığımızda ekran çıktısına bakalım.

 python main.py
Toplam 0 dosya kaldırıldı.
Toplam 0 dosya kaldırıldı.
Found 4352 files belonging to 3 classes.
2025-01-04 02:57:11.341738: I metal_plugin/src/device/metal_device.cc:1154] Metal device set to: Apple M1
2025-01-04 02:57:11.341773: I metal_plugin/src/device/metal_device.cc:296] systemMemory: 16.00 GB
2025-01-04 02:57:11.341784: I metal_plugin/src/device/metal_device.cc:313] maxCacheSize: 5.33 GB
2025-01-04 02:57:11.341968: I tensorflow/core/common_runtime/pluggable_device/pluggable_device_factory.cc:306] Could not identify NUMA node of platform GPU ID 0, defaulting to 0. Your kernel may not have been built with NUMA support.
2025-01-04 02:57:11.342231: I tensorflow/core/common_runtime/pluggable_device/pluggable_device_factory.cc:272] Created TensorFlow device (/job:localhost/replica:0/task:0/device:GPU:0 with 0 MB memory) -> physical PluggableDevice (device: 0, name: METAL, pci bus id: <undefined>)
Found 3 files belonging to 3 classes.
Sınıflar: ['beyblade', 'kapak', 'yoyo']
2025-01-04 02:57:13.015 python[12368:696259] +[IMKClient subclass]: chose IMKClient_Modern
2025-01-04 02:57:13.015 python[12368:696259] +[IMKInputSession subclass]: chose IMKInputSession_Modern
Model: "sequential_1"
_________________________________________________________________
 Layer (type)                Output Shape              Param #   
=================================================================
 conv2d (Conv2D)             (None, 62, 62, 32)        896       

 max_pooling2d (MaxPooling2  (None, 31, 31, 32)        0         
 D)                                                              

 conv2d_1 (Conv2D)           (None, 29, 29, 64)        18496     

 max_pooling2d_1 (MaxPoolin  (None, 14, 14, 64)        0         
 g2D)                                                            

 conv2d_2 (Conv2D)           (None, 12, 12, 128)       73856     

 max_pooling2d_2 (MaxPoolin  (None, 6, 6, 128)         0         
 g2D)                                                            

 flatten (Flatten)           (None, 4608)              0         

 dense (Dense)               (None, 128)               589952    

 dropout (Dropout)           (None, 128)               0         

 dense_1 (Dense)             (None, 3)                 387       

=================================================================
Total params: 683587 (2.61 MB)
Trainable params: 683587 (2.61 MB)
Non-trainable params: 0 (0.00 Byte)
_________________________________________________________________
2025-01-04 02:57:28.400380: I tensorflow/core/grappler/optimizers/custom_graph_optimizer_registry.cc:117] Plugin optimizer for device_type GPU is enabled.
Epoch 1/15
218/218 [==============================] - 11s 31ms/step - loss: 0.1488 - accuracy: 0.9289 - val_loss: 0.0077 - val_accuracy: 0.9965
Epoch 2/15
218/218 [==============================] - 8s 31ms/step - loss: 0.0134 - accuracy: 0.9951 - val_loss: 0.0019 - val_accuracy: 0.9988
Epoch 3/15
218/218 [==============================] - 8s 31ms/step - loss: 0.0191 - accuracy: 0.9948 - val_loss: 0.0014 - val_accuracy: 0.9988
Epoch 4/15
218/218 [==============================] - 8s 31ms/step - loss: 0.0073 - accuracy: 0.9971 - val_loss: 0.0012 - val_accuracy: 0.9988
Epoch 5/15
218/218 [==============================] - 8s 31ms/step - loss: 0.0266 - accuracy: 0.9928 - val_loss: 0.0122 - val_accuracy: 0.9954
Epoch 6/15
218/218 [==============================] - 8s 31ms/step - loss: 0.0124 - accuracy: 0.9957 - val_loss: 7.4663e-04 - val_accuracy: 1.0000
Epoch 7/15
218/218 [==============================] - 8s 31ms/step - loss: 0.0368 - accuracy: 0.9911 - val_loss: 0.0295 - val_accuracy: 0.9977
Epoch 8/15
218/218 [==============================] - 8s 30ms/step - loss: 0.0174 - accuracy: 0.9963 - val_loss: 0.0053 - val_accuracy: 0.9988
Epoch 9/15
218/218 [==============================] - 8s 31ms/step - loss: 0.0077 - accuracy: 0.9966 - val_loss: 0.0017 - val_accuracy: 0.9988
Epoch 10/15
218/218 [==============================] - 8s 31ms/step - loss: 0.0108 - accuracy: 0.9974 - val_loss: 2.8028e-04 - val_accuracy: 1.0000
Epoch 11/15
218/218 [==============================] - 8s 31ms/step - loss: 0.0072 - accuracy: 0.9983 - val_loss: 0.0036 - val_accuracy: 0.9988
Epoch 12/15
218/218 [==============================] - 8s 31ms/step - loss: 0.0268 - accuracy: 0.9948 - val_loss: 0.0162 - val_accuracy: 0.9942
Epoch 13/15
218/218 [==============================] - 8s 31ms/step - loss: 0.0089 - accuracy: 0.9974 - val_loss: 0.0051 - val_accuracy: 0.9965
Epoch 14/15
218/218 [==============================] - 8s 30ms/step - loss: 0.0120 - accuracy: 0.9977 - val_loss: 0.0014 - val_accuracy: 1.0000
Epoch 15/15
218/218 [==============================] - 8s 30ms/step - loss: 0.0011 - accuracy: 1.0000 - val_loss: 0.0062 - val_accuracy: 0.9977
1/1 [==============================] - 0s 311ms/step - loss: 0.0000e+00 - accuracy: 1.0000
Test Doğruluğu: 1.00
/Users/kuday/miniforge3/envs/tf_env/lib/python3.9/site-packages/keras/src/engine/training.py:3079: UserWarning: You are saving your model as an HDF5 file via `model.save()`. This file format is considered legacy. We recommend using instead the native Keras format, e.g. `model.save('my_model.keras')`.
  saving_api.save_model(
Model başarıyla kaydedildi!
(tf_env) kuday@Beren-Mac-mini dataset % 

Ekran görüntüsü ise aşağıdaki gibiydi:

Çıktı Analizi ve Yorum

Model eğitimi sırasında elde edilen bazı önemli noktaları inceleyelim:

Veri Seti:

Found 4352 files belonging to 3 classes.
Found 3 files belonging to 3 classes.
Sınıflar: ['beyblade', 'kapak', 'yoyo']
  • 4352 eğitim verisi ve 3 test verisi bulundu. Test veri seti biraz küçük gözüküyor, bu yüzden modelin gerçek dünya performansını ölçmek için daha fazla test verisine ihtiyaç duyabilirsin.
  • Sınıflar net olarak tanımlanmış: beyblade, kapak, yoyo.

Donanım Tespiti:

Metal device set to: Apple M1
systemMemory: 16.00 GB
maxCacheSize: 5.33 GB
Created TensorFlow device (/device:GPU:0 with 0 MB memory)
  • TensorFlow, Apple M1 GPU’yu tespit etmiş ve eğitim bu GPU üzerinde gerçekleşmiş. Apple M1 çipleri, makine öğrenimi işlemlerinde oldukça hızlıdır. Bu da eğitim süresini kısaltır.

Model Özeti:

Total params: 683,587 (2.61 MB)
Trainable params: 683,587
  • Modelde 683,587 parametre var. Bu, nispeten küçük bir model. Yine de 64x64 boyutundaki resimler için gayet yeterli. Model, overfitting olmadan hızlı çalışacak şekilde tasarlanmış.

Eğitim Sonuçları:

218/218 [==============================] - 11s 31ms/step - loss: 0.1488 - accuracy: 0.9289 - val_loss: 0.0077 - val_accuracy: 0.9965
  • İlk epoch’ta %92 doğruluk elde edilmiş. Eğitim ilerledikçe doğruluk artarak %100’e ulaşmış.
  • Val_loss (doğrulama kaybı) düşük. Bu, modelin eğitim verisi dışında kalan doğrulama verilerinde de iyi performans gösterdiğini gösteriyor.

Overfitting Kontrolü:

loss: 0.0000e+00 - accuracy: 1.0000
  • Test doğruluğu %100. Bu harika bir sonuç ancak dikkatli olunmalı.
  • %100 doğruluk genellikle modelin veri setini ezberlediği (overfitting) anlamına gelebilir. Gerçek dünyada bu kadar mükemmel bir sonuç pek olası değildir. Modelin farklı veri setleri üzerinde test edilmesi önerilir.

Model Kaydetme Uyarısı:

UserWarning: You are saving your model as an HDF5 file. This file format is considered legacy.
  • TensorFlow, .h5 formatında model kaydetmenin eski bir yöntem olduğunu söylüyor. Bu bir uyarı, hata değil. Ancak model.save('cnn_model.keras') şeklinde kaydederek daha modern bir format kullanabilirsin.

Çıktıya Dayalı Öneriler

  • Test Verisini Artır: Test setinde sadece 3 resim var. Modelin gerçek dünya performansını ölçmek için en az 50-100 test verisi eklemelisin.
  • Veri Seti Dengesini Kontrol Et: Eğer sınıflar arasında dengesizlik varsa, model belirli sınıflarda daha iyi sonuç verebilir. Augmentation bu konuda yardımcı olabilir.
  • Modeli Farklı Fotoğraflarla Test Et: Modeli, çalışma masan dışındaki fotoğraflarla test et. Yani aynı kapak, beyblade veya yoyo farklı açılardan çekilip test edilmelidir.
  • Model Kaydetme Yöntemini Güncelle: .keras formatı daha yeni ve önerilen bir yöntemdir.
model.save('/Users/kuday/Documents/AI/Derin Öğrenme/2. ünite/cnn_model.keras')

Test Süreci

Şimdi ise telefonumdan çekmiş olduğum bir fotoğrafı nasıl burada test edeceğimiz. Kodumuz aşağıdaki gibi:

import tensorflow as tf
from tensorflow.keras.models import load_model
from tensorflow.keras.preprocessing import image
import numpy as np
from PIL import Image

# --- Modeli Yükle ---
model_path = '/Users/kuday/Documents/AI/Derin Öğrenme/2. ünite/cnn_model.h5'
model = load_model(model_path)
print("Model başarıyla yüklendi!")

# --- Test Edilecek Fotoğrafın Yolu (Manuel Olarak Verin) ---
img_path = '/Users/kuday/Documents/AI/Derin Öğrenme/2. ünite/dataset/IMG_1046.jpeg'  # iPhone ile çekilen fotoğraf yolu

# --- Fotoğrafı Yükle ve Yeniden Boyutlandır ---
def preprocess_image(img_path):
    img = Image.open(img_path)

    # Fotoğrafı 64x64 boyutuna küçült
    img = img.resize((64, 64))

    # Modelin beklediği formata dönüştür (numpy array)
    img_array = image.img_to_array(img)

    # Batch formatına dönüştür
    img_array = np.expand_dims(img_array, axis=0)

    # 0-255 aralığındaki piksel değerlerini 0-1 arasına getir (normalize et)
    img_array = img_array / 255.0

    return img_array

# --- Fotoğrafı Ön İşlemden Geçir ---
input_image = preprocess_image(img_path)

# --- Tahmin Yap ---
prediction = model.predict(input_image)
predicted_class = np.argmax(prediction)

# --- Sınıf İsimlerini Yükle ---
class_names = ['beyblade', 'kapak', 'yoyo']  # Modelin eğitildiği sınıflar
predicted_label = class_names[predicted_class]

# --- Sonucu Göster ---
print(f"Tahmin Edilen Sınıf: {predicted_label}")

Bu kod, daha önce eğitilmiş bir CNN modelini kullanarak bir görüntünün sınıfını tahmin eden basit bir görüntü sınıflandırma uygulamasıdır. Kodun her bir bölümünü adım adım inceleyelim:

Kodun Genel Yapısı

Bu kod, TensorFlow ve Keras kullanarak bir görüntü sınıflandırma modeli oluşturduktan sonra, modeli kullanarak yeni bir fotoğrafın hangi sınıfa ait olduğunu tahmin etmek için kullanılır. Özellikle, bir iPhone ile çekilmiş bir fotoğrafın beyblade, kapak veya yoyo sınıflarından hangisine ait olduğunu belirlemek amacıyla tasarlanmıştır.

Modelin Yüklenmesi

model_path = '/Users/kuday/Documents/AI/Derin Öğrenme/2. ünite/cnn_model.h5'
model = load_model(model_path)
print("Model başarıyla yüklendi!")
  • Bu kısım, daha önce .h5 formatında kaydedilmiş bir CNN modelini yükler.
  • load_model fonksiyonu, modelin yapısını ve ağırlıklarını yükleyerek kullanıma hazır hale getirir.
  • Model başarıyla yüklendiğinde bir mesaj yazdırılır: “Model başarıyla yüklendi!”

Not: Modelin .keras formatında kaydedilmesi daha güncel bir yaklaşımdır:

model.save('cnn_model.keras')
model = load_model('cnn_model.keras')

Test Edilecek Fotoğrafın Yolu

img_path = '/Users/kuday/Documents/AI/Derin Öğrenme/2. ünite/dataset/IMG_1046.jpeg'
  • Test edilecek fotoğrafın dosya yolu manuel olarak belirtiliyor.
  • Burada iPhone’dan çekilmiş bir fotoğraf doğrudan modele verilecek şekilde işleniyor.

Fotoğrafın Ön İşlenmesi (Preprocessing)

def preprocess_image(img_path):
    img = Image.open(img_path)

    # Fotoğrafı 64x64 boyutuna küçült
    img = img.resize((64, 64))

    # Modelin beklediği formata dönüştür (numpy array)
    img_array = image.img_to_array(img)

    # Batch formatına dönüştür
    img_array = np.expand_dims(img_array, axis=0)

    # 0-255 aralığındaki piksel değerlerini 0-1 arasına getir (normalize et)
    img_array = img_array / 255.0

    return img_array

Bu kısımda, test edilecek fotoğraf modelin anlayabileceği formata dönüştürülüyor:

Adımlar:

  • Fotoğrafı aç: Image.open(img_path)
  • Boyutlandır: Fotoğraf, modelin girişi olan 64x64 piksel boyutuna ayarlanıyor. Bu, modelin eğitim sırasında kullanılan aynı boyut olmalı.
  • Array’e dönüştür: img_to_array fonksiyonu, görüntüyü numpy dizisine çevirir. Model, görüntüleri bu formatta işliyor.
  • Batch ekle: Model, birden fazla görüntü üzerinde çalışabilir. Ancak test sırasında yalnızca tek bir görüntü veriyoruz. expand_dims fonksiyonu, bu görüntüyü batch formatına çeviriyor (örneğin (1, 64, 64, 3)).
  • Normalizasyon: Piksel değerleri 0-255 arasındadır. Bu değerlerin 0-1 arasına çekilmesi için tüm pikseller 255.0’e bölünür. Bu işlem, modelin daha verimli öğrenmesine ve daha iyi sonuçlar vermesine yardımcı olur.

Tahmin Yapma

input_image = preprocess_image(img_path)
prediction = model.predict(input_image)
predicted_class = np.argmax(prediction)
  • Modelin tahmin yapması için işlenen görüntü modele veriliyor.
  • model.predict fonksiyonu, görüntünün hangi sınıfa ait olduğunu belirten bir olasılık dizisi döndürüyor.
  • Örneğin: [0.1, 0.8, 0.1]
  • np.argmax fonksiyonu, bu dizideki en yüksek olasılığa sahip olan sınıfın indeksini döndürür. Bu indeks, modelin görüntüyü hangi sınıfa atadığını belirtir.

Sınıf İsimleri ve Sonucun Gösterimi

class_names = ['beyblade', 'kapak', 'yoyo']  # Modelin eğitildiği sınıflar
predicted_label = class_names[predicted_class]

print(f"Tahmin Edilen Sınıf: {predicted_label}")
  • class_names listesi, modelin eğitildiği sınıfları içerir.
  • predicted_class ile dönen indeks, bu listede karşılık gelen sınıfın adı olarak yazdırılır.

Örnek Çıktı:

Tahmin Edilen Sınıf: kapak

1046 ve 1045 ile biten fotoğraflar sırasıyla kapak ve beyblade idi. Kodun çıktısı ise aşağıdaki gibi:

(tf_env) kuday@Beren-Mac-mini dataset % python test2.py 
2025-01-04 03:32:48.869768: I metal_plugin/src/device/metal_device.cc:1154] Metal device set to: Apple M1
2025-01-04 03:32:48.869797: I metal_plugin/src/device/metal_device.cc:296] systemMemory: 16.00 GB
2025-01-04 03:32:48.869803: I metal_plugin/src/device/metal_device.cc:313] maxCacheSize: 5.33 GB
2025-01-04 03:32:48.869829: I tensorflow/core/common_runtime/pluggable_device/pluggable_device_factory.cc:306] Could not identify NUMA node of platform GPU ID 0, defaulting to 0. Your kernel may not have been built with NUMA support.
2025-01-04 03:32:48.869843: I tensorflow/core/common_runtime/pluggable_device/pluggable_device_factory.cc:272] Created TensorFlow device (/job:localhost/replica:0/task:0/device:GPU:0 with 0 MB memory) -> physical PluggableDevice (device: 0, name: METAL, pci bus id: <undefined>)
Model başarıyla yüklendi!
2025-01-04 03:32:49.394923: I tensorflow/core/grappler/optimizers/custom_graph_optimizer_registry.cc:117] Plugin optimizer for device_type GPU is enabled.
1/1 [==============================] - 1s 666ms/step
Tahmin Edilen Sınıf: kapak
(tf_env) kuday@Beren-Mac-mini dataset % 

Bir sonraki Derin öğrenme yazımızda artık işin birazdaha matematik kısmına değinmeye başlayacağım, artık somut bir örneği gördük ve hatta kendimiz hazrladık olası sonuçları anlayabiliyoruz artık pratikten teoriye doğru geçmeye hazırız.

Kategori:Derin Öğrenme

İlk Yorumu Siz Yapın

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir