🚀 ResNet: Derin Öğrenmede Bir Devrim 🧠💡

Mustafa Serdar Konca
7 min readMay 7, 2024

--

Photo by Mika Baumeister on Unsplash

Giriş: ResNet Nedir ve Neden Bu Kadar Önemli?

Teknoloji dünyasının en çığır açan gelişmelerinden biri olan Residual Networks, ya da daha çok bilinen adıyla ResNet, yapay zeka araştırmalarında adeta bir dönüm noktası oluşturmuştur. 2015 yılında Microsoft tarafından geliştirilen bu model, derin öğrenme modellerinin karşılaştığı en büyük zorluklardan birini — aşırı derin ağlarda eğitim zorluğunu — “vanishing gradient” (kaybolan gradyan) problemini çözerek yapay zeka literatürüne yeni bir soluk getirmiştir.

ResNet’in getirmiş olduğu bu yeni soluk, ona ImageNet gibi büyük ölçekli görsel tanıma yarışmalarında bir rekortmen yapmakla kalmamış, aynı zamanda otomatik sürüş sistemleri ve tıbbi görüntüleme gibi hayati öneme sahip uygulamalarda da vazgeçilmez kılmıştır. Bu giriş bölümüyle, ResNet’in temel özelliklerini ve neden bu kadar revaçta olduğunu ortaya koymaya çalıştık, şimdi yazımıza devam edelim ve ResNet’in mimarisine değinelim.

ResNet Mimarisi: Temel Kavramlar, Kalan Bağlantılar ve Blok Yapıları

ResNet’in en çarpıcı yeniliklerinden biri, kuşkusuz “kalan bağlantılar(residual connections) konseptidir. Peki, bu kalan bağlantılar neden bu kadar önemli?

(a) Genel CNN modellerinde, girdi verisi x’in artık bağlantılar olmadan ağırlık katmanlarına nasıl aktarıldığını açıklar. (b) x’in hem ağırlık katmanlarına hem de ResNet’teki artık bağlantılara nasıl aktarıldığını gösterir.

Derin öğrenme modelleri, katman sayısı arttıkça eğitim sırasında verimliliği artırmakta zorlanır; çünkü sinyaller, ağın derinliklerine doğru ilerledikçe zayıflayabilir veya değişebilir. ResNet, bu problemi kalan bağlantılar aracılığıyla çözer. Bu bağlantılar, her bir katmanın çıkışını bir sonraki katmanın girişine eklemenin yanı sıra, önceki katmanların çıkışlarını da bir sonraki katmana direkt olarak aktarır. Bu sayede, ağın daha derin katmanlarına bilgi akışı daha sağlıklı bir şekilde gerçekleşir ve modelin öğrenme kapasitesi artar.

ResNet mimarisinin bir diğer önemli özelliği ise blok yapılarıdır (residual_block). ResNet, birden fazla residual blok kullanarak derin ağlar oluşturur. Her bir blok, birkaç katmandan oluşan küçük bir ağ görevi görür ve bu küçük ağlar, üst üste eklenerek ResNet’in derin yapısını oluşturur. Bu bloklar, modelin karmaşık özellikleri daha etkin bir şekilde öğrenmesini sağlar ve ağın daha derinlemesine eğitilmesine olanak tanır.

ResNet modelinin bu yapısal özellikleri sayesinde, çok derin ağlar bile verimli bir şekilde eğitilebilmekte ve bu da onu görsel tanıma gibi zorlu görevlerde oldukça başarılı kılar. Örneğin, ResNet-50 ve ResNet-101 modelleri, 50 ve 101 katmanlı yapılarıyla, çok katmanlı ağların karmaşasını yönetebilir ve üst düzey görevlerde yüksek doğruluk oranlarına ulaşabilir.

Bu mimari yaklaşım, ResNet’i sadece akademik araştırmalarda değil, gerçek dünya uygulamalarında da popüler bir seçenek haline getirmiş ve yapay zeka teknolojilerinin gelişiminde önemli bir yer tutmasını sağlamıştır.

ResNet’in Çeşitleri ve Uygulamaları: Derinlemesine Bir Bakış

ResNet modeli, farklı derinliklerde çeşitlere sahip olup, her biri belirli türdeki görevler için optimize edilmiştir. ResNet-34, ResNet-50, ResNet-101 ve ResNet-152, bu model ailesinin en popüler üyeleridir. ResNet-34, 34 katmanlı yapısı ile daha hafif görevler için idealdir, oysa ResNet-152, 152 katmanı ile çok daha zorlu görsel tanıma görevlerinde dahi olağanüstü performans sergiler.

Her bir ResNet modeli, “kalan bağlantılar” kullanarak derin ağların karşılaştığı kaybolan gradyan problemine çözüm getirir. Bu sayede, modelin derinliği arttıkça performansının düşmesi engellenmiş olur. ResNet-50 ve ResNet-101 gibi modeller, daha fazla katman sayısıyla daha karmaşık özellikleri modelleyebilir ve bu, onları büyük ve çeşitli veri kümeleri üzerinde eğitim yaparken daha etkili kılar.

Uygulamalar

ResNet’in etki alanı, akademik çalışmalardan endüstriyel uygulamalara kadar geniştir. Görüntü tanıma, en bilinen uygulama alanlarından biridir. ResNet, özellikle büyük ölçekli görsel tanıma yarışmalarında gösterdiği başarılı performanslarla tanınır. Bu modeller, nesne tanıma, yüz tanıma ve otomatik plaka tanıma gibi çeşitli görevlerde kullanılmaktadır.

Ayrıca, ResNet; otomatik sürüş sistemleri, tıbbi görüntü analizi ve video izleme sistemleri gibi alanlarda da etkili çözümler sunar. Özellikle tıbbi görüntülemede, kanser tespiti gibi hayati öneme sahip uygulamalarda ResNet modelleri, yüksek doğruluk oranları ve güvenilirlikleri ile öne çıkmaktadır.

Son olarak, ResNet’in sağladığı derin öğrenme kapasitesi sayesinde, yapay zeka destekli sistemlerin daha hızlı ve doğru karar vermesine olanak tanınır, bu da onu pek çok sektörde vazgeçilmez bir araç haline getirir.

ResNet’i Daha İyi Anlayabilmemiz İçin Cifar10 Veri Seti Üzerinde Uygulama

# Gerekli kütüphanelerin ve modüllerin import edilmesi
import tensorflow as tf
from tensorflow.keras.datasets import cifar10
from tensorflow.keras.layers import Input, Conv2D, BatchNormalization, ReLU, Add, AveragePooling2D, Flatten, Dense
from tensorflow.keras.models import Model

# CIFAR-10 veri setini yükleme
(x_train, y_train), (x_test, y_test) = cifar10.load_data()

# Verilerin normalizasyonu
x_train, x_test = x_train / 255.0, x_test / 255.0 # Görüntü piksel değerlerini 0-1 aralığına ölçeklendirme
y_train, y_test = tf.keras.utils.to_categorical(y_train), tf.keras.utils.to_categorical(y_test) # Etiketleri one-hot vektöre dönüştürme

# Residual blok fonksiyonunun tanımlanması
def residual_block(x, filters, reduce=False):
stride = 2 if reduce else 1 # Eğer reduce True ise stride değeri 2 olur, boyutu yarıya indirir
y = Conv2D(filters, 3, strides=stride, padding='same')(x) # Evrişim katmanı, girdi boyutunu azaltabilir
y = BatchNormalization()(y) # Batch normalizasyon, modelin daha hızlı ve stabil öğrenmesini sağlar
y = ReLU()(y) # ReLU aktivasyon fonksiyonu
y = Conv2D(filters, 3, padding='same')(y) # Başka bir evrişim katmanı
y = BatchNormalization()(y) # Yine batch normalizasyon

if reduce:
x = Conv2D(filters, 1, strides=2, padding='same')(x) # Girdi boyutunu küçültmek için 1x1 evrişim

out = Add()([x, y]) # Girdi x ve evrişim sonrası y'nin toplanması
out = ReLU()(out) # Toplamın aktivasyon fonksiyonuyla geçirilmesi
return out

# Modelin oluşturulması
inputs = Input(shape=(32, 32, 3)) # Giriş katmanı, 32x32 boyutunda 3 kanallı görüntüler için
x = Conv2D(32, 3, padding='same')(inputs) # İlk evrişim katmanı
x = BatchNormalization()(x) # Batch normalizasyon
x = ReLU()(x) # ReLU aktivasyon fonksiyonu
x = residual_block(x, 32) # İlk residual blok
x = residual_block(x, 64, reduce=True) # Boyutu azaltan ikinci residual blok
x = residual_block(x, 64) # Üçüncü residual blok
x = AveragePooling2D(4)(x) # Ortalama havuzlama
x = Flatten()(x) # Düzleştirme katmanı
outputs = Dense(10, activation='softmax')(x) # Çıkış katmanı, 10 sınıf için softmax aktivasyonu

model = Model(inputs, outputs) # Modelin oluşturulması

# Modelin derlenmesi
model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy']) # Optimizasyon algoritması, kayıp fonksiyonu ve başarı metriği

# Modelin eğitilmesi
model.fit(x_train, y_train, epochs=10, validation_data=(x_test, y_test)) # Model eğitimi ve validasyon verisi ile test

# Model özetinin yazdırılması
model.summary() # Modelin özetinin gösterilmesi
1563/1563 [==============================] - 39s 21ms/step - loss: 1.1912 - accuracy: 0.5758 - val_loss: 1.0824 - val_accuracy: 0.6198
Epoch 2/10
1563/1563 [==============================] - 34s 22ms/step - loss: 0.7931 - accuracy: 0.7219 - val_loss: 0.8252 - val_accuracy: 0.7171
Epoch 3/10
1563/1563 [==============================] - 34s 21ms/step - loss: 0.6536 - accuracy: 0.7709 - val_loss: 0.8743 - val_accuracy: 0.7092
Epoch 4/10
1563/1563 [==============================] - 33s 21ms/step - loss: 0.5607 - accuracy: 0.8053 - val_loss: 0.8572 - val_accuracy: 0.7232
Epoch 5/10
1563/1563 [==============================] - 33s 21ms/step - loss: 0.4945 - accuracy: 0.8305 - val_loss: 0.6950 - val_accuracy: 0.7613
Epoch 6/10
1563/1563 [==============================] - 32s 21ms/step - loss: 0.4351 - accuracy: 0.8507 - val_loss: 0.5744 - val_accuracy: 0.8035
Epoch 7/10
1563/1563 [==============================] - 31s 20ms/step - loss: 0.3840 - accuracy: 0.8664 - val_loss: 0.6757 - val_accuracy: 0.7790
Epoch 8/10
1563/1563 [==============================] - 32s 21ms/step - loss: 0.3413 - accuracy: 0.8810 - val_loss: 0.6414 - val_accuracy: 0.7888
Epoch 9/10
1563/1563 [==============================] - 32s 20ms/step - loss: 0.2975 - accuracy: 0.8974 - val_loss: 0.8002 - val_accuracy: 0.7614
Epoch 10/10
1563/1563 [==============================] - 32s 20ms/step - loss: 0.2634 - accuracy: 0.9087 - val_loss: 0.6575 - val_accuracy: 0.7993
Model: "model"
__________________________________________________________________________________________________
Layer (type) Output Shape Param # Connected to
==================================================================================================
input_1 (InputLayer) [(None, 32, 32, 3)] 0 []

conv2d (Conv2D) (None, 32, 32, 32) 896 ['input_1[0][0]']

batch_normalization (Batch (None, 32, 32, 32) 128 ['conv2d[0][0]']
Normalization)

re_lu (ReLU) (None, 32, 32, 32) 0 ['batch_normalization[0][0]']

conv2d_1 (Conv2D) (None, 32, 32, 32) 9248 ['re_lu[0][0]']

batch_normalization_1 (Bat (None, 32, 32, 32) 128 ['conv2d_1[0][0]']
chNormalization)

re_lu_1 (ReLU) (None, 32, 32, 32) 0 ['batch_normalization_1[0][0]'
]

conv2d_2 (Conv2D) (None, 32, 32, 32) 9248 ['re_lu_1[0][0]']

batch_normalization_2 (Bat (None, 32, 32, 32) 128 ['conv2d_2[0][0]']
chNormalization)

add (Add) (None, 32, 32, 32) 0 ['re_lu[0][0]',
'batch_normalization_2[0][0]'
]

re_lu_2 (ReLU) (None, 32, 32, 32) 0 ['add[0][0]']

conv2d_3 (Conv2D) (None, 16, 16, 64) 18496 ['re_lu_2[0][0]']

batch_normalization_3 (Bat (None, 16, 16, 64) 256 ['conv2d_3[0][0]']
chNormalization)

re_lu_3 (ReLU) (None, 16, 16, 64) 0 ['batch_normalization_3[0][0]'
]

conv2d_4 (Conv2D) (None, 16, 16, 64) 36928 ['re_lu_3[0][0]']

conv2d_5 (Conv2D) (None, 16, 16, 64) 2112 ['re_lu_2[0][0]']

batch_normalization_4 (Bat (None, 16, 16, 64) 256 ['conv2d_4[0][0]']
chNormalization)

add_1 (Add) (None, 16, 16, 64) 0 ['conv2d_5[0][0]',
'batch_normalization_4[0][0]'
]

re_lu_4 (ReLU) (None, 16, 16, 64) 0 ['add_1[0][0]']

conv2d_6 (Conv2D) (None, 16, 16, 64) 36928 ['re_lu_4[0][0]']

batch_normalization_5 (Bat (None, 16, 16, 64) 256 ['conv2d_6[0][0]']
chNormalization)

re_lu_5 (ReLU) (None, 16, 16, 64) 0 ['batch_normalization_5[0][0]'
]

conv2d_7 (Conv2D) (None, 16, 16, 64) 36928 ['re_lu_5[0][0]']

batch_normalization_6 (Bat (None, 16, 16, 64) 256 ['conv2d_7[0][0]']
chNormalization)

add_2 (Add) (None, 16, 16, 64) 0 ['re_lu_4[0][0]',
'batch_normalization_6[0][0]'
]

re_lu_6 (ReLU) (None, 16, 16, 64) 0 ['add_2[0][0]']

average_pooling2d (Average (None, 4, 4, 64) 0 ['re_lu_6[0][0]']
Pooling2D)

flatten (Flatten) (None, 1024) 0 ['average_pooling2d[0][0]']

dense (Dense) (None, 10) 10250 ['flatten[0][0]']

==================================================================================================
Total params: 162442 (634.54 KB)
Trainable params: 161738 (631.79 KB)
Non-trainable params: 704 (2.75 KB)

Kaynakça

  1. He, K., Zhang, X., Ren, S., & Sun, J. (2016). Deep Residual Learning for Image Recognition. Proceedings of the IEEE Conference on Computer Vision and Pattern Recognition (CVPR), 770–778. doi:10.1109/CVPR.2016.90
  2. Szegedy, C., Ioffe, S., Vanhoucke, V., & Alemi, A. A. (2017). Inception-v4, Inception-ResNet and the Impact of Residual Connections on Learning. Proceedings of the Thirty-First AAAI Conference on Artificial Intelligence.
  3. Çilek, Ş. (2021). ResNet (Residual Network) Nedir? [Blog post]. Alındığı yer: https://suhedacilek.medium.com/resnet-residual-network-nedir-49105e642566
  4. d2l.ai. (2022). ResNet. Alındığı yer: d2l.ai ResNet Sayfası
  5. Shervine Amidi. (2022). Convolutional Neural Networks Cheatsheet. Stanford University. Alındığı yer: Stanford University CNN Cheatsheet

--

--