Zephyrnet Logosu

ConvNet'lerde Aşırı Uyumu Anlamak

Tarih:

Giriş

ConvNet'lerde aşırı uyum, derin öğrenme ve sinir ağlarında bir modelin eğitim verilerinden çok fazla şey öğrendiği ve yeni verilerde düşük performansa yol açtığı bir zorluktur. Bu fenomen özellikle karmaşık ilişkileri modelleyebilen karmaşık sinir mimarilerinde yaygındır. Convnet'teki aşırı uyumun ele alınması, güvenilir sinir ağı modelleri oluşturmak için çok önemlidir. Bu makale, model karmaşıklığı, sınırlı eğitim verileri ve gürültülü özellikler gibi temel nedenleri inceleyerek aşırı uyumu anlama ve azaltma konusunda bir kılavuz sağlar. Ayrıca veri artırma stratejileri ve düzenlileştirme yöntemleri gibi aşırı uyumu önlemeye yönelik teknikler de tartışılmaktadır.

Temel anlayış için bu makaleleri okumanızı tavsiye ederim. aşırı uyum, yetersiz uyum ve önyargı varyansı değiş tokuşu.

Hedefleri Öğrenin

  • Aşırı uyumun nedenlerini, sonuçlarını ve senaryolarını anlayın Dönüşüm Ağları.
  • Sinir ağı modellerinde aşırı uyumu ve yetersiz uyumu tespit etmek için öğrenme eğrilerini yorumlayın.
  • Aşırı uyumu azaltmak için erken durdurma, bırakma, toplu normalleştirme, düzenlileştirme ve veri artırma gibi çeşitli teknikleri öğrenin.
  • Bu teknikleri kullanarak uygulayın TensorFlow ve Keras, ConvNet'leri CIFAR-10 veri kümesi üzerinde eğitecek.
  • Farklı tekniklerin model performansı ve genelleme üzerindeki etkisini analiz edin.

İçindekiler

ConvNet'te Aşırı Uyuma İlişkin Yaygın Senaryolar

ConvNet'te aşırı uyumla ilgili bazı yaygın senaryolara bakalım:

Senaryo 1: Yetersiz Veriye Sahip Oldukça Karmaşık Model

Küçük bir veri kümesinde derin sinir ağı gibi çok karmaşık bir modelin kullanılması, aşırı uyuma yol açabilir. Model, genel modeli öğrenmek yerine eğitim örneklerini ezberleyebilir. Örneğin, derin bir sinir ağını, görüntü tanıma gibi karmaşık bir görev için yalnızca birkaç yüz görüntüyle eğitmek, aşırı uyum sağlamaya yol açabilir.

Sonuç

Model, eğitim verileri üzerinde çok iyi performans gösterebilir ancak yeni, görünmeyen verilere genelleme yapamayabilir ve bu da gerçek dünya uygulamalarında performansın düşmesine neden olabilir.

Bu sorun nasıl çözülebilir?

Daha fazla eğitim verisi alın, veri kümemizi genelleştirmek için görüntü büyütme yapın. Daha az karmaşık bir modelle başlayın ve kapasite daha azsa karmaşıklığı artırın. 

Senaryo2: Aşırı Eğitim

Bir modeli sürekli olarak çok fazla dönem için eğitmek, fazla uyum sağlamaya yol açabilir. Model, eğitim verilerini tekrar tekrar gördükçe, temel kalıpları öğrenmek yerine verileri ezberlemeye başlayabilir.

Sonuç

Modelin performansı, eğitim seti için giderek daha fazla uzmanlaştıkça, görünmeyen veriler üzerinde durağanlaşabilir veya hatta düşebilir.

Bu sorun nasıl çözülebilir?

Modelin gereğinden fazla takılmasını ve en iyi modeli kaydetmesini önlemek için erken durdurmayı kullanın. 

Senaryo3: Düzenlileştirmenin göz ardı edilmesi

L1 veya L2 düzenlileştirmesi gibi düzenlileştirme teknikleri, karmaşık modelleri cezalandırarak aşırı uyumu önlemek için kullanılır. Düzenleme parametrelerinin göz ardı edilmesi veya yanlış ayarlanması, aşırı uyum sağlamaya neden olabilir.

Sonuç

Model aşırı derecede karmaşık hale gelebilir ve yeni verilere iyi bir şekilde genelleme yapamayabilir, bu da eğitim seti dışında performansın düşmesine neden olabilir.

Bu sorun nasıl çözülebilir?

Düzenlemeyi, Çapraz doğrulamayı, Hiper parametre ayarlamayı uygulayın. 

Modelin Kapasitesi Nedir?

Bir modelin kapasitesi, öğrenebildiği kalıpların boyutunu ve karmaşıklığını ifade eder. Sinir ağları için bu, büyük ölçüde kaç nörona sahip olduğu ve bunların birbirine nasıl bağlandığına göre belirlenecektir. Ağınızın verilere yetersiz uyum sağladığı görülüyorsa kapasitesini artırmayı denemelisiniz.

Bir ağın kapasitesini, onu genişleterek (mevcut katmanlara daha fazla birim) veya derinleştirerek (daha fazla katman ekleyerek) artırabilirsiniz. Daha geniş ağlar daha fazla doğrusal ilişkiyi daha kolay öğrenirken, daha derin ağlar daha fazla doğrusal olmayan ilişkileri tercih eder. Hangisinin daha iyi olduğu yalnızca veri kümesine bağlıdır.

Öğrenme Eğrilerinin Yorumlanması

Keras, bir eğitim sırasında geri aramaları kaydetme yeteneği sağlar derin öğrenme modeli. Tüm derin öğrenme modellerini eğitirken kaydedilen varsayılan geri aramalardan biri Geçmiş geri aramasıdır. Her dönem için eğitim ölçümlerini kaydeder. Buna kayıp ve doğruluk (sınıflandırma sorunları için) ile doğrulama veri kümesi ayarlanmışsa kayıp ve doğruluk dahildir.

Geçmiş nesnesi, modeli eğitmek için kullanılan fit() işlevine yapılan çağrılardan döndürülür. Metrikler, döndürülen nesnenin geçmiş üyesindeki bir sözlükte saklanır.

Örneğin, bir model eğitildikten sonra aşağıdaki kod parçasını kullanarak bir geçmiş nesnesinde toplanan metrikleri listeleyebilirsiniz:

# list all data in history
print(history.history.keys())

Çıktı:

['doğruluk', 'kayıp', 'val_accuracy', 'val_loss']

Bilgi Türü

Eğitim verilerindeki bilgilerin iki tür olduğunu düşünebilirsiniz:

  • Sinyal: Sinyal, genelleme yapan, modelimizin yeni verilerden tahminler yapmasına yardımcı olabilecek kısımdır.
  • Gürültü: Gürültü, yalnızca eğitim verileri için geçerli olan kısımdır; gürültü, gerçek dünyadaki verilerden gelen rastgele dalgalanmaların tamamıdır veya modelin tahmin yapmasına aslında yardımcı olamayan tesadüfi, bilgilendirici olmayan kalıpların tamamıdır. Gürültü, parçanın yararlı görünebileceği, ancak gerçekte olmadığıdır.

Bir modeli eğittiğimizde, eğitim seti üzerindeki kaybı dönem dönem çiziyoruz. Buna doğrulama verilerinin bir grafiğini de ekleyeceğiz. Bu grafiklere öğrenme eğrileri diyoruz. Derin öğrenme modellerini etkili bir şekilde eğitmek için onları yorumlayabilmemiz gerekir.

Öğrenme eğrileri

Yukarıdaki şekilde, çağlar arttıkça eğitim kaybının azaldığını, ancak doğrulama kaybının ilk başta azaldığını ve model, veri kümesinde mevcut gürültüyü yakalamaya başladıkça arttığını görebiliriz. Şimdi ConvNet'lerde aşırı uyumun çeşitli tekniklerle nasıl önleneceğini göreceğiz. 

Aşırı Uyumdan Kaçınma Yöntemleri

Artık bazı senaryoları ve aşırı uyumu tespit etmek için öğrenme eğrilerinin nasıl yorumlanacağını gördük. Bir sinir ağında aşırı uyumu önlemek için bazı yöntemlere göz atalım:

Yöntem1: Daha fazla veri kullanın

Veri kümenizin boyutunu artırmak, öğrenilecek daha çeşitli örneklere sahip olduğundan modelin daha iyi genelleştirilmesine yardımcı olabilir. Model, veri kümesinde mevcut olan önemli kalıpları bulacak ve model, bu belirli kalıpların (gürültü) tüm veri setinde mevcut olmadığını fark ettiğinden gürültüyü göz ardı edecektir.

Yöntem2: Erken Durdurma

Erken durdurma, eğitim sırasında modelin doğrulama seti üzerindeki performansını izleyerek aşırı uyumu önlemek için kullanılan bir tekniktir. Doğrulama kümesindeki performans düşmeye başladığında, modelin aşırı uyum sağlamaya başladığını gösteren eğitim durdurulur. Tipik olarak performansı izlemek için ayrı bir doğrulama seti kullanılır ve performans belirli sayıda dönem boyunca gelişmediğinde eğitim durdurulur.

Yetersiz uyum ve aşırı uyum

Yöntem3: Bırakma

Aşırı uyumun, eğitim verilerindeki ağın sahte kalıpları (gürültü) öğrenmesinden kaynaklandığını biliyoruz. Bu sahte kalıpları tanımak için bir ağ genellikle çok spesifik ağırlık kombinasyonlarına, bir tür ağırlık “komplosuna” güvenecektir. Çok spesifik oldukları için kırılgan olma eğilimindedirler: Birini çıkarırsanız komplo dağılır.

İşten ayrılmanın ardındaki fikir budur. Bu komploları ortadan kaldırmak için, eğitimin her adımında bir katmanın girdi birimlerinin bir kısmını rastgele atıyoruz, bu da ağın eğitim verilerindeki sahte kalıpları öğrenmesini çok daha zorlaştırıyor. Bunun yerine, ağırlık kalıpları daha sağlam olma eğiliminde olan geniş, genel kalıpları aramak zorundadır. 

Ayrıca okulu bırakmayı bir tür ağlar bütünü oluşturmak olarak da düşünebilirsiniz. Tahminler artık büyük bir ağ tarafından değil, daha küçük ağlardan oluşan bir komite tarafından yapılacak. Komitedeki bireyler farklı türde hatalar yapma eğilimindedir ancak aynı zamanda haklıdırlar; bu da komiteyi bir bütün olarak herhangi bir kişiden daha iyi kılar. (Eğer karar ağaçlarından oluşan bir topluluk olarak rastgele ormanlara aşina iseniz, bu da aynı fikirdir.)

ConvNet'lerde aşırı uyum

Yöntem4: Toplu Normalleştirme

İnceleyeceğimiz bir sonraki özel yöntem, yavaş veya dengesiz eğitimin düzeltilmesine yardımcı olabilecek "toplu normalizasyon" (veya "toplu norm") gerçekleştirir.

Sinir ağlarında, tüm verilerinizi ortak bir ölçeğe koymak, belki de scikit-learn'in StandardScaler'ı veya MinMaxScaler'ı gibi bir şeyle genellikle iyi bir fikirdir. Bunun nedeni, SGD'nin, verinin ürettiği aktivasyonun büyüklüğüyle orantılı olarak ağ ağırlıklarını kaydırmasıdır. Çok farklı boyutlarda aktivasyonlar üretme eğiliminde olan özellikler, kararsız eğitim davranışına neden olabilir.

Şimdi, verileri ağa gitmeden önce normalleştirmek iyiyse, belki ağ içinde de normalleştirmek daha iyi olabilir! Aslında bunu yapabilen özel bir tür katmanımız var: toplu normalizasyon katmanı. Bir toplu normalleştirme katmanı, her bir toplu işi geldiği gibi inceler, önce toplu işi kendi ortalaması ve standart sapması ile normalleştirir ve ardından verileri iki eğitilebilir yeniden ölçeklendirme parametresi ile yeni bir ölçeğe koyar. Batchnorm aslında girdilerinin bir tür koordineli yeniden ölçeklendirilmesini gerçekleştirir.

Çoğu zaman toplu norm, optimizasyon sürecine yardımcı olarak eklenir (ancak bazen tahmin performansına da yardımcı olabilir). Toplu normlu modeller, eğitimi tamamlamak için daha az döneme ihtiyaç duyma eğilimindedir. Üstelik Batchnorm, eğitimin "takılıp kalmasına" neden olabilecek çeşitli sorunları da çözebilir. Özellikle eğitim sırasında sorun yaşıyorsanız modellerinize toplu normalleştirme eklemeyi düşünün.

Yöntem5: L1 ve L2 Düzenlemesi

L1 ve L2 düzenlemesi, sinir ağındaki büyük ağırlıkları cezalandırarak aşırı uyumu önlemek için kullanılan tekniklerdir. L1 düzenlemesi, ağırlıkların mutlak değeriyle orantılı olarak kayıp fonksiyonuna bir ceza terimi ekler. Ağırlıklarda seyrekliği teşvik eder ve özellik seçimine yol açabilir. Ağırlık azalması olarak da bilinen L2 düzenlemesi, kayıp fonksiyonuna ağırlıkların karesiyle orantılı bir ceza terimi ekler. Ağırlıkların çok büyük olmasını engeller ve ağırlıkların dağılımının daha eşit dağılmasını teşvik eder.

L1 ve L2 düzenlemesi arasındaki seçim genellikle spesifik soruna ve modelin istenen özelliklerine bağlıdır.

L1/L2 düzenlemesi için büyük değerlere sahip olmak, modelin hızlı öğrenmemesine ve öğrenmede bir platoya ulaşmasına neden olacak ve modelin yetersiz uyum sağlamasına neden olacaktır. 

Yöntem6: Veri Arttırma

Bir makine öğrenimi modelinin performansını artırmanın en iyi yolu, onu daha fazla veri üzerinde eğitmektir. Modelin öğrenmesi gereken örnek sayısı arttıkça, görüntülerdeki hangi farklılıkların önemli, hangilerinin önemsiz olduğunu daha iyi fark edebilecektir. Daha fazla veri, modelin daha iyi genelleştirilmesine yardımcı olur.

Daha fazla veri elde etmenin kolay bir yolu, halihazırda sahip olduğunuz verileri kullanmaktır. Veri setimizdeki görüntüleri sınıfı koruyacak şekilde dönüştürebilirsek (örneğin: MNIST Rakam sınıflandırması, 6'yı artırmayı denersek 6 ile 9'u ayırt etmek zor olacaktır), sınıflandırıcımıza bu tür dönüşümleri göz ardı etmeyi öğretebiliriz. Örneğin bir fotoğrafta bir arabanın sağa ya da sola dönük olması onun Kamyon değil de Araba olduğu gerçeğini değiştirmez. Dolayısıyla, eğitim verilerimizi ters çevrilmiş görüntülerle genişletirsek, sınıflandırıcımız "sol veya sağ"ın göz ardı edilmesi gereken bir fark olduğunu öğrenecektir.

Veri artırmanın arkasındaki fikir de budur: gerçek verilere oldukça benzeyen bazı ekstra sahte veriler ekleyin ve sınıflandırıcınız gelişecektir. 

Aşırı uyumdan kaçınmanın anahtarının modelinizin iyi genellendiğinden emin olmak olduğunu unutmayın. Modelinizin performansını yalnızca eğitim setinde değil, her zaman bir doğrulama setinde kontrol edin.

Yukarıdaki Yöntemlerin Verilerle Uygulanması

Yukarıdaki yöntemlerin uygulama adımlarını inceleyelim:

Adım 1: Gerekli Kütüphanelerin Yüklenmesi

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import tensorflow as tf
from tensorflow.keras import datasets, layers, models
from tensorflow.keras.preprocessing.image import ImageDataGenerator
from tensorflow.keras.callbacks import ModelCheckpoint
import keras
from keras.preprocessing import image
from keras import models, layers, regularizers
from tqdm import tqdm
import warnings
warnings.filterwarnings(action='ignore')

Adım 2: Veri Kümesini Yükleme ve Ön İşleme

#Here all the images are in the form of a numpy array
cifar10 = tf.keras.datasets.cifar10
(x_train, y_train), (x_test, y_test) = cifar10.load_data()
x_train = x_train / 255.0
x_test = x_test / 255.0

Adım 3: Veri Kümesini Öğrenme

x_train.shape, y_train.shape, x_test.shape, y_test.shape 

Çıktı:

Çıktı
np.unique(y_train)

Çıktı:

Çıktı
#These labels are in the order and taken from the documentaion
class_names = ['airplane', 'automobile', 'bird', 'cat', 'deer',
               'dog', 'frog', 'horse', 'ship', 'truck']

Adım 4: Veri Kümesinden Görüntünün Görselleştirilmesi

def show_image(IMG_INDEX):
    plt.imshow(x_train[20] ,cmap=plt.cm.binary)
    plt.xlabel(class_names[y_train[IMG_INDEX][0]])
    plt.show()
show_image(20)
ConvNet'lerde aşırı uyum
model = models.Sequential()
model.add(layers.Conv2D(32, (3, 3), activation='relu', input_shape=(32, 32, 3)))
model.add(layers.AveragePooling2D((2, 2)))
model.add(layers.Conv2D(64, (3, 3), activation='relu'))
model.add(layers.AveragePooling2D((2, 2)))
model.add(layers.Conv2D(64, (3, 3), activation='relu'))
model.add(layers.Flatten())
model.add(layers.Dense(64, activation='relu'))
model.add(layers.Dense(10))
model.summary()

Şimdi hiper parametreleri başlatalım ve modeli optimizer, kayıp fonksiyonu ve değerlendirme metriği ile derleyelim.


train_hyperparameters_config={'optim':keras.optimizers.Adam(learning_rate=0.001),
                             'epochs':20,
                              'batch_size':16
                             }
model.compile(optimizer=train_hyperparameters_config['optim'],
                  loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
                  metrics=['accuracy'])

Adım 6: Eğitim Modeli

history = model.fit(x_train, y_train, 
                        epochs=train_hyperparameters_config['epochs'], 
                        batch_size=train_hyperparameters_config['batch_size'], 
                        verbose=1,
                        validation_data=(x_test, y_test))

Adım 7: Modeli Değerlendirin

Bunlar bize tarih nesnesinin içerdiği bilgileri söyleyecektir ve bunları bilgi eğrilerimizi oluşturmak için kullanırız.

print(history.history.keys()) 
def learning_curves(history):
# Plotting Accuracy
    plt.figure(figsize=(14, 5))  # Adjust the figure size as needed
    plt.subplot(1, 2, 1)  # Subplot with 1 row, 2 columns, and index 1
    plt.plot(history.history['accuracy'], label='train_accuracy', marker='s', markersize=4)
    plt.plot(history.history['val_accuracy'], label='val_accuracy', marker='*', markersize=4)
    plt.xlabel('Epoch')
    plt.ylabel('Accuracy')
    plt.legend(loc='lower right')

    # Plotting Loss
    plt.subplot(1, 2, 2)  # Subplot with 1 row, 2 columns, and index 2
    plt.plot(history.history['loss'], label='train_loss', marker='s', markersize=4)
    plt.plot(history.history['val_loss'], label='val_loss', marker='*', markersize=4)
    plt.xlabel('Epoch')
    plt.ylabel('Loss')
    plt.legend(loc='lower right')

    plt.show()
learning_curves(history)
ConvNet'lerde aşırı uyum

Eğrilerden doğrulama doğruluğunun 4. dönemden sonra bir platoya ulaştığını ve modelin gürültüyü yakalamaya başladığını görebiliriz. Bu nedenle, modelin aşırı takılmasını önlemek ve val_loss'a dayalı olarak en iyi ağırlıkları geri yüklemek için erken durdurma uygulayacağız. Sinir ağımız optimize edicileri kullanarak kaybı azaltmaya çalışırken erken durmayı izlemek için val_loss'u kullanacağız. Doğruluk ve Doğrulama doğruluğu eşiğe bağlıdır (Sınıfları ayırma olasılığı - ikili sınıflandırma için genellikle 0.5), dolayısıyla veri kümemiz dengesizse çoğu durumda endişelenmemiz gereken kayıp olacaktır. 

Adım 8: Erken Durdurmanın Uygulanması

Erken durma modelimizin gerçekleşmesini önleyeceği için modelimizin gereğinden fazla sığması konusunda endişelenmiyoruz. Daha fazla sayıda dönem ve uygun bir sabır seçmek iyi bir seçimdir. Artık aynı model mimariyi kullanacağız ve geri aramayı erken durdurarak eğiteceğiz. 

model = models.Sequential()
model.add(layers.Conv2D(32, (3, 3), activation='relu', input_shape=(32, 32, 3)))
model.add(layers.AveragePooling2D((2, 2)))
model.add(layers.Conv2D(64, (3, 3), activation='relu'))
model.add(layers.AveragePooling2D((2, 2)))
model.add(layers.Conv2D(64, (3, 3), activation='relu'))
model.add(layers.Flatten())
model.add(layers.Dense(128, activation='relu'))
model.add(layers.Dense(64, activation='relu'))
model.add(layers.Dense(10))
model.summary()

# Here we have used more epochs than needed since we use patience parameter which we stop the model from overfitting
train_hyperparameters_config = {
    'optim': keras.optimizers.Adam(learning_rate=0.001),
    'patience': 5,
    'epochs': 50,
    'batch_size': 32, 
}
print('Setting the callback and early stopping configurations...')
callback = tf.keras.callbacks.EarlyStopping(
    monitor='val_loss', 
    min_delta=0.001, # minimium amount of change to count as an improvement
    patience=train_hyperparameters_config['patience'], 
    restore_best_weights=True)

def model_train(model, x_train, y_train, x_test, y_test, train_hyperparameters_config):
    model.compile(optimizer=train_hyperparameters_config['optim'],
                      loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
                      metrics=['accuracy'])
    ht = model.fit(x_train, y_train, 
                            epochs=train_hyperparameters_config['epochs'], 
                            batch_size=train_hyperparameters_config['batch_size'],
                            callbacks=[callback],
                            verbose=1,
                            validation_data=(x_test, y_test))
    return ht

ht=model_train(model, x_train, y_train, x_test, y_test, train_hyperparameters_config)
learning_curves(ht)
ConvNet'lerde aşırı uyum

Modelin aldığı en iyi ağırlıklarımızı bilmek. 

print('Testing ..................')
test_loss, test_acc = model.evaluate(x_test,  y_test, verbose=2)
print('test_loss : ', test_loss, 'test_accuracy : ', test_acc)

Adım 9: Model Karmaşıklığını Artırma

Çünkü modelimiz iyi performans göstermiyor ve yeterli veriyi yakalayamadığı için yetersiz kalıyor. Model karmaşıklığımızı arttırıp değerlendirmeliyiz. 

model = models.Sequential()

model.add(layers.Conv2D(128, (3, 3), activation='relu', input_shape=(32, 32, 3)))
model.add(layers.MaxPooling2D((2, 2)))

model.add(layers.Conv2D(256, (3, 3), activation='relu'))
model.add(layers.MaxPooling2D((2, 2)))

model.add(layers.Conv2D(256, (3, 3), activation='relu'))
model.add(layers.MaxPooling2D((2, 2)))

model.add(layers.Conv2D(512, (3, 3), activation='relu', padding='same'))
model.add(layers.MaxPooling2D((2, 2)))

model.add(layers.Flatten())
model.add(layers.Dense(256, activation='relu'))
model.add(layers.Dense(128, activation='relu'))
model.add(layers.Dense(10, activation='softmax'))
model.summary()
Çıktı

Toplam parametrelerde artış olduğunu görüyoruz. Bu, modelimizde daha karmaşık ilişkilerin bulunmasına yardımcı olacaktır. Not: Veri setimiz 32X32 görsellerden oluşmaktadır; bunlar nispeten küçük resimlerdir. Dolayısıyla başlangıçta daha karmaşık modeller kullanmak kesinlikle modele fazla uyum sağlayacaktır, dolayısıyla model karmaşıklığımızı yavaş yavaş artırma eğilimindeyiz.

# Here we have used more epochs than needed since we use patience parameter which we stop the model from overfitting
train_hyperparameters_config = {
    'optim': keras.optimizers.Adam(learning_rate=0.001),
    'patience': 5,
    'epochs': 50,
    'batch_size': 32, 
}
print('Setting the callback and early stopping configurations...')
callback = tf.keras.callbacks.EarlyStopping(
    monitor='val_loss', 
    min_delta=0.001, # minimium amount of change to count as an improvement
    patience=train_hyperparameters_config['patience'], 
    restore_best_weights=True)
ht=model_train(model, x_train, y_train, x_test, y_test, train_hyperparameters_config)

learning_curves(ht)
ConvNet'lerde aşırı uyum
print('Testing ..................')
test_loss, test_acc = model.evaluate(x_test,  y_test, verbose=2)
print('test_loss : ', test_loss, 'test_accuracy : ', test_acc)

Yukarıdaki grafiklerden modelin aşırı uyumlu olduğunu açıkça söyleyebiliriz, bu nedenle Bırakma normalizasyonu ve Toplu normalizasyon adı verilen başka bir yöntem kullanacağız.

Adım 10: Bırakma Katmanlarını ve Toplu Normalleştirme Katmanlarını Kullanma

model = models.Sequential()

model.add(layers.Conv2D(128, (3, 3), activation='relu', input_shape=(32, 32, 3)))
model.add(layers.BatchNormalization())
model.add(layers.MaxPooling2D((2, 2)))

model.add(layers.Conv2D(256, (3, 3), activation='relu'))
model.add(layers.BatchNormalization())
model.add(layers.MaxPooling2D((2, 2)))

model.add(layers.Conv2D(256, (3, 3), activation='relu'))
model.add(layers.BatchNormalization())
model.add(layers.MaxPooling2D((2, 2)))

model.add(layers.Conv2D(512, (3, 3), activation='relu', padding='same'))
model.add(layers.BatchNormalization())
model.add(layers.MaxPooling2D((2, 2)))

model.add(layers.Flatten())
model.add(layers.Dense(256, activation='relu'))
model.add(layers.BatchNormalization())
model.add(layers.Dropout(0.3))

model.add(layers.Dense(128, activation='relu'))
model.add(layers.BatchNormalization())
model.add(layers.Dropout(0.3))

model.add(layers.Dense(10, activation='softmax'))
model.summary()
Çıktı
# Here we have used more epochs than needed since we use patience parameter which we stop the model from overfitting
train_hyperparameters_config = {
    'optim': keras.optimizers.Adam(learning_rate=0.001),
    'patience': 5,
    'epochs': 50,
    'batch_size': 32, 
}
print('Setting the callback and early stopping configurations...')
callback = tf.keras.callbacks.EarlyStopping(
    monitor='val_loss', 
    min_delta=0.001, # minimium amount of change to count as an improvement
    patience=train_hyperparameters_config['patience'], 
    restore_best_weights=True)
ht=model_train(model, x_train, y_train, x_test, y_test, train_hyperparameters_config)
learning_curves(ht)
ConvNet'lerde aşırı uyum
print('Testing ..................')
test_loss, test_acc = model.evaluate(x_test,  y_test, verbose=2)
print('test_loss : ', test_loss, 'test_accuracy : ', test_acc)

Öğrenme grafiklerinden, modelin toplu normalizasyon ve bırakma katmanlarında bile aşırı uyum sağladığını görebiliriz. Bu nedenle karmaşıklığı artırmak yerine filtre sayısını artırın. Daha fazla özellik çıkarmak için daha fazla evrişim katmanı ekleyeceğiz.

Adım 11: Evrişim Katmanlarını Artırma

Eğitilebilir parametreyi azaltın ancak daha fazla özellik çıkarmak için evrişim katmanlarını artırın.

model = models.Sequential()

model.add(layers.Conv2D(32, (3, 3), activation='relu', padding='same', input_shape=(32, 32, 3)))
model.add(layers.BatchNormalization())
model.add(layers.Conv2D(32, (3, 3), activation='relu', padding='same'))
model.add(layers.BatchNormalization())
model.add(layers.MaxPool2D((2, 2)))
model.add(layers.Dropout(0.2))

model.add(layers.Conv2D(64, (3, 3), activation='relu', padding='same'))
model.add(layers.BatchNormalization())
model.add(layers.Conv2D(64, (3, 3), activation='relu', padding='same'))
model.add(layers.BatchNormalization())
model.add(layers.MaxPool2D((2, 2)))
model.add(layers.Dropout(0.3))

model.add(layers.Conv2D(128, (3, 3), activation='relu', padding='same'))
model.add(layers.BatchNormalization())
model.add(layers.Conv2D(128, (3, 3), activation='relu', padding='same'))
model.add(layers.BatchNormalization())
model.add(layers.MaxPool2D((2, 2)))
model.add(layers.Dropout(0.4))

model.add(layers.Flatten())
model.add(layers.Dense(128, activation='relu'))
model.add(layers.BatchNormalization())
model.add(layers.Dropout(0.5))

model.add(layers.Dense(10, activation='softmax'))

model.summary()
# Here we have used more epochs than needed since we use patience parameter which we stop the model from overfitting
train_hyperparameters_config = {
    'optim': keras.optimizers.Adam(learning_rate=0.001),
    'patience': 5,
    'epochs': 50,
    'batch_size': 32, 
}
print('Setting the callback and early stopping configurations...')
callback = tf.keras.callbacks.EarlyStopping(
    monitor='val_loss', 
    min_delta=0.001, # minimium amount of change to count as an improvement
    patience=train_hyperparameters_config['patience'], 
    restore_best_weights=True)
ht=model_train(model, x_train, y_train, x_test, y_test, train_hyperparameters_config)
çıktı
learning_curves(ht)
ConvNet'lerde aşırı uyum
print('Testing ..................')
test_loss, test_acc = model.evaluate(x_test,  y_test, verbose=2)
print('test_loss : ', test_loss, 'test_accuracy : ', test_acc)

Yukarıdaki çıktı ve öğrenme eğrisinden modelin çok iyi performans gösterdiğini ve aşırı uyumdan kaçındığını çıkarabiliriz. Eğitim doğruluğu ve doğrulama doğruluğu birbirine çok yakındır. Bu senaryoda aşırı uyumu azaltmak için daha fazla yönteme ihtiyacımız olmayacak. Yine de L1/L2 düzenlemesini keşfedeceğiz. 

Adım 12: L1/L2 Düzenlemesini Kullanma

from tensorflow.keras import regularizers

model = models.Sequential()

model.add(layers.Conv2D(32, (3, 3), activation='relu', padding='same', input_shape=(32, 32, 3)))
model.add(layers.BatchNormalization())
model.add(layers.Conv2D(32, (3, 3), activation='relu', padding='same', kernel_regularizer=regularizers.l1(0.0005)))
model.add(layers.BatchNormalization())
model.add(layers.MaxPool2D((2, 2)))
model.add(layers.Dropout(0.2))

model.add(layers.Conv2D(64, (3, 3), activation='relu', padding='same'))
model.add(layers.BatchNormalization())
model.add(layers.Conv2D(64, (3, 3), activation='relu', padding='same', kernel_regularizer=regularizers.l2(0.0005)))
model.add(layers.BatchNormalization())
model.add(layers.MaxPool2D((2, 2)))
model.add(layers.Dropout(0.3))

model.add(layers.Conv2D(128, (3, 3), activation='relu', padding='same'))
model.add(layers.BatchNormalization())
model.add(layers.Conv2D(128, (3, 3), activation='relu', padding='same'))
model.add(layers.BatchNormalization())
model.add(layers.MaxPool2D((2, 2)))
model.add(layers.Dropout(0.4))

model.add(layers.Flatten())
model.add(layers.Dense(128, activation='relu', kernel_regularizer=regularizers.l1_l2(0.0005, 0.0005)))
model.add(layers.BatchNormalization())
model.add(layers.Dropout(0.5))
model.add(layers.Dense(10, activation='softmax'))

model.summary()
# Here we have used more epochs than needed since we use patience parameter which we stop the model from overfitting
train_hyperparameters_config = {
    'optim': keras.optimizers.Adam(learning_rate=0.001),
    'patience': 7,
    'epochs': 70,
    'batch_size': 32, 
}
print('Setting the callback and early stopping configurations...')
callback = tf.keras.callbacks.EarlyStopping(
    monitor='val_loss', 
    min_delta=0.001, # minimium amount of change to count as an improvement
    patience=train_hyperparameters_config['patience'], 
    restore_best_weights=True)
ht=model_train(model, x_train, y_train, x_test, y_test, train_hyperparameters_config)
learning_curves(ht)
ConvNet'lerde aşırı uyum
print('Testing ..................')
test_loss, test_acc = model.evaluate(x_test,  y_test, verbose=2)
print('test_loss : ', test_loss, 'test_accuracy : ', test_acc)

Artık L1/L2 düzenlemesinin, 0.0001 gibi düşük bir ceza puanı kullandıktan sonra bile modelimizi %4 oranında yetersiz hale getirdiğini görebiliyoruz. Bu nedenle tüm yöntemlerin bir arada dikkatli bir şekilde kullanılması tavsiye edilir. Toplu Normalleştirme ve Düzenleme, modeli benzer şekilde etkilediğinden, L1/L2 düzenlemesine ihtiyacımız olmaz. 

Adım 13: Veri Arttırma

ImageDataGenerator'ı tensorflow keraslarından kullanacağız.

# creates a data generator object that transforms images
datagen = ImageDataGenerator(
rotation_range=40,
width_shift_range=0.2,
height_shift_range=0.2,
shear_range=0.2,
zoom_range=0.2,
horizontal_flip=True,
fill_mode='nearest')

# pick an image to transform
test_img = x_train[20]
img = image.img_to_array(test_img)  # convert image to numpy arry
img = img.reshape((1,) + img.shape)  # reshape image

i = 0

for batch in datagen.flow(img, save_prefix='test', save_format='jpeg'):  # this loops runs forever until we break, saving images to current directory with specified prefix
    plt.figure(i)
    plot = plt.imshow(image.img_to_array(batch[0]))
    i += 1
    if i > 4:  # show 4 images
        break

plt.show()
ConvNet'lerde aşırı uyum

Bunlar dört adet artırılmış görsel ve bir adet orijinal görseldir.

# Create an instance of the ImageDataGenerator
datagen = ImageDataGenerator(
    rotation_range=40,
    width_shift_range=0.2,
    height_shift_range=0.2,
    shear_range=0.2,
    zoom_range=0.2,
    horizontal_flip=True,
    fill_mode='nearest'
)

# Create an iterator for the data generator
data_generator = datagen.flow(x_train, y_train, batch_size=32)

# Create empty lists to store the augmented images and labels
augmented_images = []
augmented_labels = []

# Loop over the data generator and append the augmented data to the lists
num_batches = len(x_train) // 32
progress_bar = tqdm(total=num_batches, desc="Augmenting data", unit="batch")

for i in range(num_batches):
    batch_images, batch_labels = next(data_generator)
    augmented_images.append(batch_images)
    augmented_labels.append(batch_labels)
    progress_bar.update(1)

progress_bar.close()

# Convert the lists to NumPy arrays
augmented_images = np.concatenate(augmented_images, axis=0)
augmented_labels = np.concatenate(augmented_labels, axis=0)

# Combine the original and augmented data
x_train_augmented = np.concatenate((x_train, augmented_images), axis=0)
y_train_augmented = np.concatenate((y_train, augmented_labels), axis=0)
çıktı

Arttırmamızın ilerlemesini bilmek için tqdm kütüphanesini kullandık.

x_train_augmented.shape, y_train_augmented.shape
Çıktı

Bu, büyütme sonrasındaki veri setimizdir. Şimdi bu veri setini kullanalım ve modelimizi eğitelim.

model = models.Sequential()

model.add(layers.Conv2D(32, (3, 3), activation='relu', padding='same', input_shape=(32, 32, 3)))
model.add(layers.BatchNormalization())
model.add(layers.Conv2D(32, (3, 3), activation='relu', padding='same'))
model.add(layers.BatchNormalization())
model.add(layers.MaxPool2D((2, 2)))
model.add(layers.Dropout(0.2))

model.add(layers.Conv2D(64, (3, 3), activation='relu', padding='same'))
model.add(layers.BatchNormalization())
model.add(layers.Conv2D(64, (3, 3), activation='relu', padding='same'))
model.add(layers.BatchNormalization())
model.add(layers.MaxPool2D((2, 2)))
model.add(layers.Dropout(0.3))

model.add(layers.Conv2D(128, (3, 3), activation='relu', padding='same'))
model.add(layers.BatchNormalization())
model.add(layers.Conv2D(128, (3, 3), activation='relu', padding='same'))
model.add(layers.BatchNormalization())
model.add(layers.MaxPool2D((2, 2)))
model.add(layers.Dropout(0.4))

model.add(layers.Flatten())
model.add(layers.Dense(128, activation='relu'))
model.add(layers.BatchNormalization())
model.add(layers.Dropout(0.5))

model.add(layers.Dense(10, activation='softmax'))

model.summary()

# Here we have used more epochs than needed since we use patience parameter which we stop the model from overfitting
train_hyperparameters_config = {
    'optim': keras.optimizers.Adam(learning_rate=0.001),
    'patience': 10,
    'epochs': 70,
    'batch_size': 32, 
}
print('Setting the callback and early stopping configurations...')
callback = tf.keras.callbacks.EarlyStopping(
    monitor='val_loss', 
    min_delta=0.001, # minimium amount of change to count as an improvement
    patience=train_hyperparameters_config['patience'], 
    restore_best_weights=True)

ht=model_train(model, x_train_augmented, y_train_augmented, x_test, y_test, train_hyperparameters_config)


learning_curves(ht)
ConvNet'lerde aşırı uyum
print('Testing ..................')
test_loss, test_acc = model.evaluate(x_test,  y_test, verbose=2)
print('test_loss : ', test_loss, 'test_accuracy : ', test_acc)

Modelin daha genelleştirildiğini ve kayıpların azaldığını görüyoruz. Daha iyi doğrulama doğruluğuna da sahibiz. Dolayısıyla veri artırma model doğruluğumuzu artırdı. 

Sonuç

Aşırı uyum, özellikle ConvNet'ler gibi karmaşık sinir ağı mimarilerinde derin öğrenmede yaygın bir sorundur. Uygulayıcılar, ConvNet'lerde aşırı uyumun temel nedenlerini anlayarak ve meydana geldiği senaryoları tanıyarak önleyebilirler. Erken durdurma, bırakma, toplu normalleştirme, düzenlileştirme ve veri artırma gibi teknikler bu sorunun azaltılmasına yardımcı olabilir. Bu tekniklerin CIFAR-10 veri seti üzerinde uygulanması, model genellemesinde ve performansında önemli gelişmeler gösterdi. Bu tekniklere hakim olmak ve ilkelerini anlamak, sağlam ve güvenilir sinir ağı modellerine yol açabilir.

Sık Sorulan Sorular

S1. Aşırı uyum nedir ve derin öğrenmede neden bir sorundur? 

A. Aşırı uyum, bir modelin gürültü ve alakasız modeller de dahil olmak üzere eğitim verilerini çok iyi öğrenmesi durumunda ortaya çıkar ve yeni, görünmeyen verilerde düşük performansa neden olur. Bu bir sorundur çünkü gereğinden fazla takılan modeller etkili bir şekilde genelleştirilememekte ve pratik faydalarını sınırlamaktadır.

Q2. Sinir ağı modelimde aşırı uyumu nasıl tespit edebilirim?

C. Dönemler boyunca eğitim ve doğrulama ölçümlerini (örneğin, kayıp, doğruluk) gösteren öğrenme eğrilerini yorumlayarak ConvNet'lerdeki aşırı uyumu tespit edebilirsiniz. Eğitim metrikleri gelişmeye devam ederken doğrulama metrikleri gelişmeyi bırakırsa veya düşmeye başlarsa, bu aşırı uyumun bir işaretidir.

S3. Erken durdurma nedir ve aşırı uyumun önlenmesine nasıl yardımcı olur?

C. Erken durdurma, eğitim sırasında bir doğrulama kümesindeki modelin performansını izleyen ve doğrulama kümesindeki performans aşırı uyumun göstergesi olarak düşmeye başladığında eğitim sürecini durduran bir tekniktir. Eğitimi doğru zamanda durdurarak modelin aşırı takılmasının önlenmesine yardımcı olur.

S4. Veri artırma aşırı uyumun azaltılmasına nasıl yardımcı olur? 

A. Veri artırma, mevcut verilere dönüşümler (örn. ters çevirme, döndürme, ölçeklendirme) uygulayarak yeni, sentetik eğitim verileri oluşturma işlemidir. Modelin daha çeşitli örneklere maruz bırakılmasıyla daha iyi genelleştirilmesine yardımcı olur ve ConvNet'lerde sınırlı eğitim verilerine fazla uyum sağlama riskini azaltır.

spot_img

En Son İstihbarat

spot_img