CNN Mimarileri
An Interactive Node-Link Visualization of Convolutional Neural Networks
CNN Mimarileri
CNN mimarileri, genel amaçlı CNN yapılarına kıyasla belirli görevler için optimize edilmiş veya özelleştirilmiş mimarilerdir.
Bu özel mimariler, belirli bir uygulama veya endüstri gereksinimlerini karşılamak üzere geliştirilmiştir.
CNN mimarilerinin geliştirilmesinin temel nedenleri:
- Performansın Artırılması: Belirli bir görev için optimize edilmiş mimariler, genel amaçlı mimarilere göre daha iyi performans sağlayabilir. Örneğin, nesne tespiti veya yüz tanıma gibi belirli görevler için tasarlanmış mimariler, bu görevlerde daha yüksek doğruluk ve verimlilik sağlayabilir.
- Hesaplama ve Bellek Verimliliği: CNN mimarileri, belirli bir görev için gereksiz hesaplama ve bellek kullanımını azaltarak, işlem verimliliğini artırabilir. Özellikle yerel işlemciler veya sınırlı belleğe sahip cihazlar için optimize edilmiş mimariler, bu cihazlarda daha verimli bir şekilde çalışabilir.
- Donanım Kısıtlamalarını Karşılama: Gömülü sistemler, akıllı telefonlar veya diğer cihazlar gibi donanım kısıtlamalarına sahip ortamlar için CNN mimarileri geliştirilebilir. Bu mimariler, donanımın sınırlı kaynaklarını daha verimli bir şekilde kullanarak, düşük güç tüketimi veya hızlı işleme sağlayabilir.
- Özellik Çıkarımı ve Aktarım Öğrenimi: Belirli bir uygulama veya endüstri için önemli olan özelliklerin daha etkin bir şekilde çıkarılmasını sağlayabilirler. Örneğin, tıbbi görüntüleme veya otomotiv endüstrisi için geliştirilmiş CNN mimarileri, belirli anatomik veya nesne özelliklerini daha doğru bir şekilde tanımlayabilir.
- Ölçeklenebilirlik ve Dağıtılmış Uygulamalar: Büyük ölçekli veri işleme veya dağıtılmış uygulamalar için optimize edilmiş CNN mimarileri, daha hızlı ve ölçeklenebilir çözümler sunabilir. Özellikle bulut tabanlı veya paralel hesaplama ortamları için geliştirilmiş mimariler, büyük veri kümeleri üzerinde daha etkili bir şekilde çalışabilir.
Bu noktada, ünlü CNN mimarilerinden dördünün ayrıntılarını ve N4'lerini (Ne Zaman, Neden, Ne ve Nasıl) açıklayarak birbirlerinden nasıl farklı olduklarını inceleyeceğiz.
* AlexNet
* VGGNet
* ResNet
* Inception
AlexNet
Ne zaman?
- AlexNet, 2012 ImageNet (https://www.image-net.org) yarışmasının galibi Hinton ve öğrencisi Alex Krizhevsky tarafından tasarlanmıştır. Ayrıca o yıldan sonra mükemmel vgg, GoogleLeNet gibi daha fazla ve daha derin sinir ağları önerilmiştir. Resmi veri modeli %57,1 doğruluk oranına sahiptir ve en iyi 1-5 %80,2'ye ulaşmaktadır. Bu, geleneksel makine öğrenimi sınıflandırma algoritmaları için zaten oldukça olağanüstü.
Neden?
- AlexNet, ImageNet yarışmasının sonuçlarını iyileştirme ihtiyacından doğmuştur. Bu ağ, 2012 ImageNet LSVRC-2012 yarışmasında %73,8'lik doğruluk oranıyla en iyi ikinci ağa kıyasla %84,7'lik doğruluk oranıyla kayda değer bir doğruluk elde eden ilk Derin evrişimli ağlardan biriydi. Bir görüntü karesindeki uzamsal korelasyon fikri, konvolüsyonel katmanlar ve alıcı alanlar kullanılarak araştırılmıştır.
Ne?
- Ağ, 5 Konvolüsyonel (CONV) katman ve 3 Tam Bağlı (FC) katmandan oluşmaktadır. Kullanılan aktivasyon fonksiyonu Rectified Linear Unit'tir (ReLU).
- Nasıl?
- Ağın girdisi 227x227x3 boyutunda bir RGB görüntü grubudur ve her bir sınıfa karşılık gelen 1000x1 olasılık vektörü çıkarır.
VGGNet
Ne zaman?
- 2014
Neden?
- VGGNet, CONV katmanlarındaki parametre sayısını azaltma ve eğitim süresini iyileştirme ihtiyacından doğmuştur.
Ne?
- VGGNet'in sadece ağdaki toplam katman sayısında farklılık gösteren birden fazla çeşidi (VGG16, VGG19, vb.) vardır. Bir VGG16 ağının yapısal detayları aşağıda gösterilmiştir.
- Ağdaki her bir katmanın yapısal detayları aşağıdaki tabloda bulunabilir.
- Nasıl?
- Sabit boyutlu çekirdeklere sahip olmanın ardındaki fikir, Alexnet'te kullanılan tüm değişken boyutlu evrişimli çekirdeklerin (11x11, 5x5, 3x3) yapı taşı olarak birden fazla 3x3 çekirdek kullanılarak çoğaltılabilmesidir. Çoğaltma, çekirdekler tarafından kapsanan alıcı alan açısından yapılır.
ResNet
Ne zaman?
- 2015
Neden?
Sinir Ağları, var olduğunda daha basit bir eşleme bulamamakla ünlüdür.
- Örneğin, tam bağlantılı çok katmanlı bir perceptron ağımız olduğunu ve bunu girdinin çıktıya eşit olduğu bir veri seti üzerinde eğitmek istediğimizi varsayalım. Bu sorunun en basit çözümü, tüm ağırlıkların bire eşit olması ve tüm gizli katmanlar için tüm önyargıların sıfır olmasıdır. Ancak böyle bir ağ geri yayılım kullanılarak eğitildiğinde, ağırlıkların ve önyargıların geniş bir değer aralığına sahip olduğu oldukça karmaşık bir eşleme öğrenilir.
- Bir başka örnek de mevcut bir sinir ağına daha fazla katman eklemektir. Diyelim ki bir veri seti üzerinde %n doğruluk oranına ulaşmış bir f(x) ağımız var. Şimdi bu ağa daha fazla katman eklendiğinde g(f(x)) en az %n doğruluğa sahip olmalıdır, yani en kötü durumda g(.) daha fazla olmasa da f(x) ile aynı doğruluğu sağlayan özdeş bir eşleme olmalıdır. Ancak ne yazık ki durum böyle değildir. Deneyler, ağa daha fazla katman eklendiğinde doğruluğun azaldığını göstermiştir.
- Yukarıda bahsedilen sorunlar, kaybolan gradyan problemi nedeniyle meydana gelmektedir. CNN'i derinleştirdikçe, ilk katmanlara geri yayılma sırasında türevin değeri neredeyse önemsiz hale gelir.
- ResNet bu ağı iki tür 'kısayol bağlantısı' sunarak ele almaktadır: Özdeşlik kısayolu ve Projeksiyon kısayolu.
Ne?
- ResNetXX mimarilerinin birden fazla versiyonu vardır, burada 'XX' katman sayısını belirtir. En yaygın kullanılanları ResNet50 ve ResNet101'dir. Kaybolan gradyan sorunu halledildiğinden beri (Nasıl bölümünde daha fazla bilgi), CNN daha da derinleşmeye başladı. Aşağıda ResNet18'in yapısal detaylarını sunuyoruz
ResNet18'e ait blok diyagram.
- Ağdaki her bir katmanın yapısal detayları aşağıdaki tabloda bulunabilir.
- Nasıl?
- Daha önce de belirtildiği gibi, ResNet mimarisi kaybolan gradyan problemini çözmek için kısayol bağlantılarını kullanır. ResNet'in temel yapı taşı, ağ boyunca tekrarlanan bir Rezidüel bloktur.
Inception
Ne zaman?
- 2014
Neden?
- Bir görüntü sınıflandırma görevinde, göze çarpan özelliğin boyutu görüntü karesi içinde önemli ölçüde değişebilir. Bu nedenle, sabit bir çekirdek boyutuna karar vermek oldukça zordur. Görüntünün geniş bir alanına dağılmış daha global özellikler için daha büyük çekirdekler tercih edilirken, diğer yandan daha küçük çekirdekler görüntü karesi boyunca dağılmış alana özgü özelliklerin tespitinde iyi sonuçlar sağlar. Bu tür değişken boyutlu özelliklerin etkili bir şekilde tanınması için farklı boyutlarda çekirdeklere ihtiyacımız vardır. Inception'ın yaptığı da budur. Katman sayısı açısından daha derine inmek yerine, daha geniş bir alana yayılır. Aynı katman içinde farklı boyutlarda birden fazla çekirdek uygulanmaktadır.
Ne?
- Inception ağ mimarisi, aşağıdaki yapıya sahip çeşitli başlangıç modüllerinden oluşur.
Her bir başlangıç modülü paralel olarak dört işlemden oluşur
- 1x1 konv katman
- 3x3 konv katman
- 5x5 conv katmanı
- maksimum havuzlama
Sarı renkle gösterilen 1x1 conv blokları derinlik azaltma için kullanılır. Dört paralel işlemden elde edilen sonuçlar daha sonra Filtre Birleştirme bloğunu (yeşil renkte) oluşturmak için derinlemesine birleştirilir. En basiti GoogLeNet olmak üzere Inception'ın birden fazla versiyonu bulunmaktadır.
Ağdaki her bir katmanın yapısal detayları aşağıdaki tabloda bulunabilir.
- Nasıl?
- Başlangıç, eğitim yoluyla en iyi ağın seçileceği ağ uzayını artırır. Her bir başlangıç modülü farklı seviyelerde göze çarpan özellikleri yakalayabilir. Küresel özellikler 5x5 conv katmanı tarafından yakalanırken, 3x3 conv katmanı dağıtılmış özellikleri yakalamaya eğilimlidir. Maksimum havuzlama işlemi, bir komşulukta öne çıkan düşük seviyeli özellikleri yakalamaktan sorumludur. Belirli bir seviyede, tüm bu özellikler çıkarılır ve bir sonraki katmana beslenmeden önce birleştirilir. Hangi özelliklerin en fazla değere sahip olduğuna karar vermeyi ve buna göre ağırlıklandırmayı ağa/eğitime bırakıyoruz. Diyelim ki veri setindeki görüntüler çok fazla düşük seviyeli özellik içermeyen global özellikler bakımından zenginse, eğitilen Inception ağı 5x5 conv çekirdeğe kıyasla 3x3 conv çekirdeğe karşılık gelen çok küçük ağırlıklara sahip olacaktır.
CNN Mimarileri ile Uygulamalar
import os
import cv2 #opencv image processing
import time # Runtime calculation
import shutil
import itertools
import tensorflow # Deep Learning Frameworks
import numpy as np # Mathematical and Array Operations
import pandas as pd# Data Frame Operations
from PIL import Image # Python Imaging Library
import seaborn as sns # Visualization library
import matplotlib.pyplot as plt # Visualization library
# Deep Learning API functionalities
from tensorflow.keras.models import Model
from sklearn.metrics import confusion_matrix # Confusion matrix for model evaluation
from tensorflow.keras.models import Sequential # Sequential model initialization
from sklearn.model_selection import train_test_split # function to split sample data to train and test
from tensorflow.keras.optimizers import Adam, Nadam, Ftrl, SGD # Optimizer algorithms
from tensorflow.keras.metrics import categorical_crossentropy # Loss functions
from tensorflow.keras.preprocessing.image import ImageDataGenerator # For data pipeline building
# Neural network layers
from tensorflow.keras.layers import Dense,BatchNormalization,Dropout
from tensorflow.keras.layers import Conv2D, MaxPooling2D, Flatten,AveragePooling2D
# To prevent Over-fitting
from tensorflow.keras.callbacks import EarlyStopping,ReduceLROnPlateau,ModelCheckpoint
class_names = os.listdir('C:\\Users\\Mücahit CİHAN\\Desktop\\AI KAMP\\2024-Konya\\2-CNN\\skin-cancer-malignant-vs-benign\\train')
class_types = len(os.listdir('C:\\Users\\Mücahit CİHAN\\Desktop\\AI KAMP\\2024-Konya\\2-CNN\\skin-cancer-malignant-vs-benign\\train'))
print('Number of classes for Classification: ', class_types)
print(f'The class names are {class_names[0]} and {class_names[1]}')
print('-- Count of Train Images --')
for i in class_names:
print(i + ':' + str(len(os.listdir('C:\\Users\\Mücahit CİHAN\\Desktop\\AI KAMP\\2024-Konya\\2-CNN\\skin-cancer-malignant-vs-benign\\train\\' + i))))
print('-- Count of Test Images --')
for i in class_names:
print(i + ':' + str(len(os.listdir('C:\\Users\\Mücahit CİHAN\\Desktop\\AI KAMP\\2024-Konya\\2-CNN\\skin-cancer-malignant-vs-benign\\test\\' + i))))
Number of classes for Classification: 2
The class names are benign and malignant
-- Count of Train Images --
benign:1440
malignant:1197
-- Count of Test Images --
benign:1440
malignant:1197
train_datagen = ImageDataGenerator(rescale=1./255,shear_range=0.2,zoom_range=0.2,horizontal_flip=True)
test_datagen = ImageDataGenerator(rescale=1./255)
train_generator = train_datagen.flow_from_directory(
'C:\\Users\\Mücahit CİHAN\\Desktop\\AI KAMP\\2024-Konya\\2-CNN\\skin-cancer-malignant-vs-benign\\train',
target_size=(224,224),
batch_size=16,
class_mode='binary')
validation_generator = test_datagen.flow_from_directory(
'C:\\Users\\Mücahit CİHAN\\Desktop\\AI KAMP\\2024-Konya\\2-CNN\\skin-cancer-malignant-vs-benign\\test',
target_size=(224,224),
batch_size=8,
class_mode='binary')
#model.fit(train_generator,epochs=10,validation_data=validation_generator)
Found 2637 images belonging to 2 classes.
Found 660 images belonging to 2 classes.
skin-cancer-malignant-vs-benign verisetini kullanarak AlexNet mimarisi ile uygulama
# AlexNet mimarisini oluşturma
model = Sequential([
Conv2D(96, kernel_size=(11,11), strides=(4,4), activation='relu', input_shape=(224,224,3)),
MaxPooling2D(pool_size=(3,3), strides=(2,2)),
Conv2D(256, kernel_size=(5,5), padding='same', activation='relu'),
MaxPooling2D(pool_size=(3,3), strides=(2,2)),
Conv2D(384, kernel_size=(3,3), padding='same', activation='relu'),
Conv2D(384, kernel_size=(3,3), padding='same', activation='relu'),
Conv2D(256, kernel_size=(3,3), padding='same', activation='relu'),
MaxPooling2D(pool_size=(3,3), strides=(2,2)),
Flatten(),
Dense(4096, activation='relu'),
Dropout(0.5),
Dense(4096, activation='relu'),
Dropout(0.5),
Dense(1, activation='softmax')
])
model.summary()
# SGD optimizer
sgd = SGD(lr=0.01, decay=1e-6, momentum=0.9, nesterov=True)
# Modeli derleme
model.compile(optimizer=sgd, loss='binary_crossentropy', metrics=['accuracy'])
# Modeli eğitme
model.fit(train_generator,epochs=2,validation_data=validation_generator,verbose=1)
Epoch 1/2
WARNING:tensorflow:From C:\ProgramData\Anaconda3\lib\site-packages\tensorflow_core\python\ops\math_grad.py:1424: where (from tensorflow.python.ops.array_ops) is deprecated and will be removed in a future version.
Instructions for updating:
Use tf.where in 2.0, which has the same broadcast rule as np.where
164/165 [============================>.] - ETA: 1s - loss: 8.3903 - acc: 0.4529Epoch 1/2
165/165 [==============================] - 191s 1s/step - loss: 8.3743 - acc: 0.4539 - val_loss: 8.3136 - val_acc: 0.4545
Epoch 2/2
164/165 [============================>.] - ETA: 1s - loss: 8.3687 - acc: 0.4540Epoch 1/2
165/165 [==============================] - 179s 1s/step - loss: 8.3703 - acc: 0.4539 - val_loss: 8.2906 - val_acc: 0.4545
# Test seti üzerinde değerlendirme
test_loss, test_acc = model.evaluate(validation_generator)
print(f"Test doğruluğu: {test_acc}")
83/83 [==============================] - 16s 193ms/step - loss: 8.3366 - acc: 0.4545
Test doğruluğu: 0.4545454680919647
MNIST verisetini kullanarak VGG mimarisi ile uygulama
import numpy as np
from keras.datasets import mnist ## keras içerisinde birçok veriseti mevcut
from keras.utils import to_categorical
from keras.models import Sequential
from keras.layers import Dense, Flatten, Conv2D, MaxPooling2D
from keras.optimizers import SGD
# Veri kümesini yükleme ve önişleme
(train_images, train_labels), (test_images, test_labels) = mnist.load_data()
train_images = np.expand_dims(train_images, axis=-1) / 255.0
test_images = np.expand_dims(test_images, axis=-1) / 255.0
train_labels = to_categorical(train_labels, num_classes=10)
test_labels = to_categorical(test_labels, num_classes=10)
print("x_train shape",train_images.shape)
print("x_test shape",test_images.shape)
print("y_train shape",train_labels.shape)
print("y_test shape",test_labels.shape)
x_train shape (60000, 28, 28, 1)
x_test shape (10000, 28, 28, 1)
y_train shape (60000, 10)
y_test shape (10000, 10)
# VGG mimarisini oluşturma
model = Sequential([
Conv2D(64, (3, 3), activation='relu', padding='same', input_shape=(28, 28, 1)),
Conv2D(64, (3, 3), activation='relu', padding='same'),
MaxPooling2D(pool_size=(2, 2), strides=(2, 2)),
Conv2D(128, (3, 3), activation='relu', padding='same'),
Conv2D(128, (3, 3), activation='relu', padding='same'),
MaxPooling2D(pool_size=(2, 2), strides=(2, 2)),
Conv2D(256, (3, 3), activation='relu', padding='same'),
Conv2D(256, (3, 3), activation='relu', padding='same'),
Conv2D(256, (3, 3), activation='relu', padding='same'),
MaxPooling2D(pool_size=(2, 2), strides=(2, 2)),
Conv2D(512, (3, 3), activation='relu', padding='same'),
Conv2D(512, (3, 3), activation='relu', padding='same'),
Conv2D(512, (3, 3), activation='relu', padding='same'),
Conv2D(512, (3, 3), activation='relu', padding='same'),
Conv2D(512, (3, 3), activation='relu', padding='same'),
Conv2D(512, (3, 3), activation='relu', padding='same'),
MaxPooling2D(pool_size=(2, 2), strides=(2, 2)),
Flatten(),
Dense(4096, activation='relu'),
Dense(4096, activation='relu'),
Dense(10, activation='softmax')
])
# SGD optimizer
sgd = SGD(lr=0.01, decay=1e-6, momentum=0.9, nesterov=True)
# Modeli derleme
model.compile(optimizer=sgd, loss='categorical_crossentropy', metrics=['accuracy'])
# Modeli eğitme
model.fit(train_images, train_labels, batch_size=1024, epochs=1, validation_split=0.2)
# Test seti üzerinde değerlendirme
test_loss, test_acc = model.evaluate(test_images, test_labels)
print(f"Test doğruluğu: {test_acc}")