Uygulamalı Evrişimsel Sinir Ağları (Convolutional Neural Network)

Original article was published on Artificial Intelligence on Medium

Uygulamalı Evrişimsel Sinir Ağları (Convolutional Neural Network)

Türkçeye Evrişimsel Sinir Ağları olarak çevrilen Convolutional Neural Network yani kısaca CNN özellikle görüntü tanıma ve işleme problemlerinde kullanılan bir tür yapay sinir ağıdır. Resim ve video formatındaki yapılarda gösterdiği başarı sebebiyle dünyada yaygın olarak kullanılmaktadır. Bu çalışmada ayrıntılı olarak CNN yapısı, nasıl çalıştığı ve bu yapıyı içeren örnek bir python uygulaması yer almaktadır.

Öncelikle yapay sinir ağlarından genel olarak bahsedecek olursak yapay sinir ağları, insan beyninin işleyişini baz alarak oluşturulmuş modellerdir. Bu yapıda öğrenme işleminin gerçekleştirilmesi, bu öğretilerin yorumlanması ve bu yorum sonucunda sistemin otonom bir şekilde karar vermesi amaçlanmıştır. Bu yapı temelde 3 katmandan meydana gelir.

  • Input Layer
  • Hidden Layer
  • Output Layer

İlk katman olan input layer’ da gözlemler sisteme aktarılır. Bu katmandaki düğüm sayısı, gözlemi en iyi şekilde temsil edecek olan öznitelik sayısına eşittir. Giriş katmanında değerler kopyalanarak birden fazla katmana gönderilebilir. Aktarım aşamasında değerlere herhangi bir işlem uygulanmaz. Hidden layer(gizli katman), giriş katmanından gelen değerleri belirli katsayılarla çarparak bu değerlere dönüşüm işlemleri uygular. Bu katmanda birden fazla düğüm olabilir. Bu düğümlerde belirli threshold koşulları uygulanarak output sayısı kadar değer elde edilebilir. Gizli katmandan sonra output layer(çıkış katmanı) bulunur. Elde edilen bu değere göre sistem prediction yapar.

Yapay sinir ağları tarihsel bakımdan incelendiğinde ilk olarak Warren S. McCulloch ve Walter Pitts tarafından 1943 yılında yayınlanmıştır [1]. Ancak o dönemde bilgisayar gücünün sınırları çok dar olduğu için modellerin gücü yeterince anlaşılamamıştır. 2000’li yıllara gelindiği ise bilgisayar gücündeki ciddi artış, yapay sinir ağlarındaki başarının ve popülerliğin artmasına sebep olmuştur. Buna rağmen modelin çıkış noktasını oluşturan insan beyninde, yaklaşık olarak 100 milyar adet nöron bulunmaktadır. Günümüzdeki sistemlerle bu yapının tam olarak modellenmesi mümkün değildir. Ancak zamanla gelişen teknolojiyle birlikte bu modeller de sürekli olarak gelişmektedir.

Convolutional Neural Network

Convolutional Neural Network (Evrişimsel Sinir Ağları) görüntü tanıma problemlerinde kullanılan bir deep neural network sınıfıdır [2]. Google ve Facebook gibi şirketler başta olmak üzere bir çok büyük şirket tarafından sıkça kullanılmaktadır. CNN’in nasıl çalıştığına gelecek olursak, input olarak verilen resimlerin bilgisayarlar tarafından tanınması ve işlenebilir bir formata getirilmesi gerekir. Bu sebeple ilk olarak resimler matris formatına çevrilir.

Şekil 1. Mona Lisa [3]

Şekil 1′ de 2 adet Mona Lisa tablosu görünmektedir. Bu tablolara bakıldığında ilk bakışta anlaşılması güç bir farklılık vardır. Ancak biz makinalara bu yapıyı matris olarak verdiğimizde en ufak bir ayrıntıyı bile yakalamasını sağlarız. Eğitim ve tahmin aşamalarının temelinde aynı mantık mevcuttur. Resimlerdeki, dolayısıyla matrislerdeki farklılıkları baz alarak sistem hangi resmin hangi etikete ait olduğunu saptar. Bu farklılıkların etiket üzerindeki etkilerini eğtim aşamasında öğrenir ve sonrasında bunları kullanarak yeni resimler için tahminlerde bulunur. Convolutional Neural Network bu işlemleri etkili bir şekilde gerçekleştirebilmek için bazı katmanlara katmanlara sahiptir. Aşağıda bu katmanlar sırayla incelenmiştir.

Bu katmanda girdi olarak gelen resim bir filtreden geçirilir. Filtreden geçirilme sonucu oluşan değerler öznitelik haritasını oluşturur.

Şekil 2. Convolutional Layer[4]

Bu aşama Şekil 2’de aşama aşama görülebilir. Input olarak elimizde 4×4 lük matris vardır. Belirlenen filtre ise 2×2 boyutundadır. (Tabi gerçek resimlerde kullanılan filtreler genellikle 3×3, 5×5 boyutlarında olabilir. AlexNet gibi ünlü modellerden bazıları ise 7x7lik filtreler kullanmaktadır.) Burada input olarak gelen matrisin tamamında bu filtre gezdirilerek, input üzerinde oluşan her 2×2 matris ile filtre matrisi çarpılırak öznitelik matrisi oluşturulur. Birden fazla filtre olması durumunda bu işlemler her bir filtre için uygulanır. Şekil 2’deki durum için 2×2 lik toplamda 4 adet farklı filtre kullanılmış olsaydı sonuç olarak ortaya 4x3x3 lük öznitelik matrisi oluşurdu. Görüntü işleme problemlerinde genel olarak resimler siyah-beyaz yapılarak modele input olarak verilir. Ancak bazı durumlarda renklerin etiket üzerindeki etkiler çok büyüktür (Bir meyve veya sebzenin kalitesinin rengiyle doğrudan alakalı olduğu durumlar gibi). Bu gibi durumlarda resimleri renkli şekilde işlemek zorunludur. Eğer modele renkli bir input verilirse yukarıdaki işlemler her bir renk katmanı için ayrı ayrı yapılır (RGB).

Convolutional layer kullanılmadan resimlerdeki her bir piksel için modele bir input katmanı eklenebilir. Her bir input için gereken bağlantılar sağlanabilir. Ancak çok fazla bağlantı ve işlem gücü gerektirdiği için bu işlemi doğrudan yapmak yerine öznitelik haritası çıkartarak daha az sayıda bağlantı ile bu işlem gerçekleştirilebilir. Örnek olarak elimizde insan yüzlerinden oluşan bir veri tabanı olduğunu düşünelim. Bu yüzleri mutlu ve mutsuz insanlar olarak da sınıflandırmak istiyoruz.

Şekil 3. Somurtan — Gülen yüz[5]

Bu noktada elimizde şekil 3’de olduğu gibi farklı yüz ifadelerine sahip insan resimleri olacaktır. Burada model ağız, göz ve kaş çevrelerindeki matris farklılıklarının, etiket üzerinde büyük etkisinin olduğunu öğrenerek eğitimini buna göre tamamlayacaktır. Ancak yine Şekil 3’de görüldüğü üzere alın ve kulak bölgelerinde her iki resimde aynı gözükmektedir. Haliyle bu değerlerin eğitim ve tahmin üzerindeki etkileri çok az olacak veya tamamen etkisiz olacaklardır. CNN’in gücü burada ortaya çıkarak Convolutional katmanı ile resimlerdeki sadece gerekli ve önemli olan öznitelikler belirlenir. Farklılık oluşturmayan öznitelikler ise hesaba dahil edilmez.

Convolutional layerdan sonraki ikinci katman Pooling layerdır (havuzlama katmanı).

Şekil 4. Pooling Layer

Pooling layer genellikle oluşturulan öznitelik matrislerine uygulanır. Şekil 4’de 4×4 lük bir Öznitelik matrisi matrisi görülmektedir. Burada 2×2 lik bir max. pooling uygulanırsa sağdaki 2×2 lik matris oluşur. Öznitelik matrisinde pooling için belirlenen boyutlarda (Şekil 4 için 2×2) matrisler oluşturularak, o matris içerisindeki en büyük değer alınır. Turuncu olarak gösterilen ilk matriste 6, yeşil olarak belirlenen matriste ise bu değer 8 dir. Genellikle kullanılan yöntem max. pooling olsa da mean pooling ve min.pooling gibi yöntemler de mevcuttur. Mean pooling yönteminde ortalama alınırken, min. pooling yönteminde ise en düşük değer alınarak işlem gerçekleştirilir.

Yukarıda açıklamaları yapılan Convolutional layer ve Pooling layerdan sonra flattening (düzleştirme) bölümü gelir.

Şekil 5. Flattening

Yukarıdaki katmanlar modelde birden fazla kez kullanılabilir. Bu işlemler tamamlandıktan sonra elde edilen matris Fully Connected katmanında kullanılabilmesi için düzleştirilmesi gerekir. Bu sebepten ötürü Şekil 5’de örnek olarak görülebilecek flattening işlemi gerçekleştirilir. Bu aşamadan sonra Fully Connected Layer’ın inputları hazırlanmış olur.

Şekil.6 Basic Connected Layer

Şekil 6’da basit bir neural networks yapısı görülmektedir. Bu yapı fully connected layer yapısının daha basitleşmiş hali olarak da görülebilir. Haliyle bu yapıyı anlamak fully connected layer’ın çalışma prensibini anlamımıza yardımcı olacaktır. Öncelikle x1 ve x2 ile flattening yaparak elde ettiğimiz input layer kısmı oluşturulur. Sonrasında input katmanından gelen değerler h1 ve h2 ile hidden layer dediğimiz gizli katmanlarda, model tarafından belirlenen katsayılarla (çoğu zaman fonksiyon) işleme girer. Bu işlem sonucunda belirlenen aktivasyon fonksiyonuna göre y, yani output değeri üretilir.

Convolutional Neural Network ile Python Uygulaması

Bu başlık altında python’da yukarıda anlatılan başlıkları kullanarak, trafik işaretlerinin sınıflandırılması yapılmıştır. Öncelikle veri seti https://bitbucket.org/jadslim/german-traffic-signs adresinden indirililir.

def get_data(train_path, val_path, test_path):
with open(train_path,"rb",) as f:
train_data = pickle.load(f)
with open(val_path,"rb") as f:
val_data = pickle.load(f)
with open(test_path,"rb") as f:
test_data = pickle.load(f)

X_train, y_train = train_data["features"],train_data["labels"]
X_val, y_val = val_data["features"],val_data["labels"]
X_test, y_test = test_data["features"],test_data["labels"]

return X_train, y_train, X_val, y_val, X_test, y_test
train_path = "train.p"
val_path = "valid.p"
test_path = "test.p"
X_train, y_train, X_val, y_val, X_test, y_test = get_data(train_path, val_path, test_path)

Yukarıda kodları kullanarak indirilen veriler X_train, y_train, X_val, y_val, X_test, y_test değişkenleri olarak bölünür.

print(X_train.shape)>>>(34799, 32, 32, 3)
print(X_val.shape)
>>>(4410, 32, 32, 3)
print(X_test.shape)
>>>(12630, 32, 32, 3)
print(y_test.shape)
>>>(12630,)

Elde edilen değişkenlerin boyutları incelendiğinde açıkça görülüyor ki X_train setinde 34799 adet, X_test setinde 12630 adet ve X_val setinde de 4410 adet resim mevcuttur. 32×32 olarak gösterilen boyutlar resmin piksel değerini ve en sonda 3 değeri ise bu resmin renkli olduğunu (RGB değeri) göstermektedir. y_test setine bakıldığında ise beklendiği gibi X_test sayısı kadar olduğu görülebilir. Burada X_train setinde bulunan her bir resim için, bu resmin hangi sınıfa ait olduğunu belirten bir y_train değeri vardır. İlk olarak X_train setine ait bir resmi matplotlib kütüphanesi yardımıyla açılır.

plt.imshow(X_train[3344])

>>>

Şekil 6. İşlenmemiş Trafik İşareti

Bu resmin hangi sınıfa ait olduğunu görmek istersek,

y_train[3344]>>> 1

Böylelikle bu resmin ait olduğu sınıfın 1 numaralı sınıf olduğu görülür. Veri setinde ayrıca bu sınıfların hangi anlama geldikleri de “signnames.csv” isimli dosyada yer almaktadır.

sign_names = pd.read_csv("signnames.csv")
print(sign_names)
>>>
ClassId SignName
0 0 Speed limit (20km/h)
1 1 Speed limit (30km/h)
2 2 Speed limit (50km/h)
3 3 Speed limit (60km/h)
4 4 Speed limit (70km/h)
5 5 Speed limit (80km/h)
6 6 End of speed limit (80km/h)
7 7 Speed limit (100km/h)
8 8 Speed limit (120km/h)
9 9 No passing
10 10 No passing for vechiles over 3.5 metric tons
11 11 Right-of-way at the next intersection
12 12 Priority road
13 13 Yield
14 14 Stop
15 15 No vechiles
16 16 Vechiles over 3.5 metric tons prohibited
17 17 No entry
18 18 General caution
19 19 Dangerous curve to the left
20 20 Dangerous curve to the right
21 21 Double curve
22 22 Bumpy road
23 23 Slippery road
24 24 Road narrows on the right
25 25 Road work
26 26 Traffic signals
27 27 Pedestrians
28 28 Children crossing
29 29 Bicycles crossing
30 30 Beware of ice/snow
31 31 Wild animals crossing
32 32 End of all speed and passing limits
33 33 Turn right ahead
34 34 Turn left ahead
35 35 Ahead only
36 36 Go straight or right
37 37 Go straight or left
38 38 Keep right
39 39 Keep left
40 40 Roundabout mandatory
41 41 End of no passing
42 42 End of no passing by vechiles over 3.5 metric ...

Verilerin yapılarının anlaşılmasının ardında bu yapılar siyah-beyaz hale getirilir. Burada unutulmaması gereken unsur bu işlem her veri setinde yapılamaz. Renklerin önem arz ettiği durumlarda resimler renkli şekilde işlenmelidir. Ancak bu projede resimlerin renkli olmalarının eğitim üzerinde herhangi bir etkisi bulunmamaktadır.

def image_process(img):
gray_img = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
equalized_img = cv2.equalizeHist(gray_img)
final_image = equalized_img/255
return final_image
X_train = np.array(list(map(image_process, X_train)))
X_test = np.array(list(map(image_process, X_test)))
X_val = np.array(list(map(image_process, X_val)))

Yukarıdaki fonksiyonda bazı image process aşamaları mevcuttur. Bu kısım ile ilgili bilgisi olmayan kişiler, ilerleyen zamanlarda hazırlayacağım OpenCV kütüphanesiyle ilgili yazıyı takip edebilirler. Ancak burada da en basit şekilde anlatmak gerekirse ilk olarak resim siyah-beyaz formata çevrilir (cvtColor). Sonrasında resmin histogram değeri üzerinde bir düzenleme yapılır (equalizeHist). Histogram değerlerinin bir bölgede toplanması yerine bu değerlerin yapıda homojen şekilde olması eğitimdeki başarının artmasına sebep olmaktadır. Sonra elde edilen matris değerlerine normalizasyon uygulanarak (equalized_img/255) X_train, X_test ve X_val setlerindeki her bir resim güncellenir.

plt.imshow(X_train[3344])

>>>

Şekil 7. İşlenmiş Trafik İşareti
print(X_train.shape)>>>(34799, 32, 32)

Bu işlemler sonucunda Şekil 6 da görülen resim Şekil 7’deki duruma gelmiştir. Yeni oluşan X_train setinin boyutlarına bakıldığında ise (34799, 32, 32) olduğu yani renk katmanlarının silindiği görülebilir. Bu resimlerin eğitime girebilmesi için boyutlarının ayarlanması gerekir. Oluşturacağımız model her bir resim için 3 boyutlu bir matrise ihtiyaç duymaktadır. Ayrıca etiket değerlerine içeren y_train, y_test ve y_val setleri de kategorik vektör olacak şekilde düzenlenir (One Hot Encoding olarak yapılandırılır).

X_train = X_train.reshape(34799,32,32,1)
X_test = X_test.reshape(12630,32,32,1)
X_val = X_val.reshape(4410,32,32,1)
y_train = to_categorical(y_train,43)
y_test = to_categorical(y_test,43)
y_val = to_categorical(y_val,43)

Bu işlemlerden sonra model tasarımına geçilir.

def model_1():
model = Sequential()
model.add(Conv2D(60, (5,5), input_shape = (32,32,1), activation = "relu"))
model.add(Conv2D(60, (5,5), activation = "relu"))
model.add(MaxPooling2D(pool_size = (2,2)))
model.add(Conv2D(30, (3,3), activation = "relu"))
model.add(Conv2D(30, (3,3), activation = "relu"))
model.add(MaxPooling2D(pool_size = (2,2)))
#model.add(Dropout(0.5))
model.add(Flatten())
model.add(Dense(500, activation = "relu"))
model.add(Dropout(0.5))
model.add(Dense(num_classes, activation ="softmax"))
model.compile(Adam(lr= 0.01), loss = "categorical_crossentropy", metrics =[ "accuracy"])
return model
model = model_1()
print(model.summary())
>>>
Layer (type) Output Shape Param #
=================================================================
conv2d_11 (Conv2D) (None, 28, 28, 60) 1560
_________________________________________________________________
conv2d_12 (Conv2D) (None, 24, 24, 60) 90060
_________________________________________________________________
max_pooling2d_7 (MaxPooling2 (None, 12, 12, 60) 0
_________________________________________________________________
conv2d_13 (Conv2D) (None, 10, 10, 30) 16230
_________________________________________________________________
conv2d_14 (Conv2D) (None, 8, 8, 30) 8130
_________________________________________________________________
max_pooling2d_8 (MaxPooling2 (None, 4, 4, 30) 0
_________________________________________________________________
flatten_4 (Flatten) (None, 480) 0
_________________________________________________________________
dense_7 (Dense) (None, 500) 240500
_________________________________________________________________
dropout_4 (Dropout) (None, 500) 0
_________________________________________________________________
dense_8 (Dense) (None, 43) 21543
=================================================================
Total params: 378,023
Trainable params: 378,023
Non-trainable params: 0
_________________________________________________________________
None

İlk olarak Conv.layer ile modele başlanmıştır. Burada 60 adet 5×5 lik filtreler kullanılmıştır. Eğitimde kullanılacak resimlerin boyutu 32×32 olduğu için input shape olarak 32x32x1 olarak belirlenir.

Şekil 8. Relu Fonksiyonu

Modelimizde Relu ve Softmax olmak üzere iki farklı aktivasyon fonksiyonu kullanılmıştır. Aktivasyon fonksiyonlarının kullanım sebebi, sinir ağlarında oluşan değerin doğrudan döndürülmesini engellemektedir. Oluşan değer doğrudan çıkış sinyali olarak gönderilirse sistem doğrusal bir yapı haline gelir. Ancak bir çok durumda yapının doğrusal olmayan pozisyonlarını da öğrenmesini bekleriz. İşte bu gibi durumlarda aktivasyon fonksiyonları kullanılır. Şekil 8’de modelde de kullanılan Relu fonksiyonu görülmektedir. Relu günümüzde derin öğrenme modellerinde sıkça kullanılmaktadır. Görüldüğü üzere Relu fonksiyonu, aldığı negatif değerlere herhangi bir işlem uygulamadan doğrudan 0 olarak döndürmektedir. Bu sebeple negatif değerlerle Relu aktivasyon fonksiyonunu kullanmak doğru bir tercih olmayacaktır.

Şekil 9. Sigmoid Fonksiyonu

Son katmanda Relu fonksiyonu yerine Sigmoid fonksiyonu kullanılmıştır. Şekil 9’da görüldüğü gibi Sigmoid 0 ile 1 arasında değerler alır. Son katmana gelen değerler bu fonksiyon ile işleme girer. Fonksiyondaki işlem sonucunda herhangi bir sınıfa ait olma durumu 0 ile 1 arasında değerler ile elde edilir. Bu durum özellikle sınıflandırma problemleri için çok kullanışlıdır.

Bunun dışında kullanılan bir diğer katman Max. Pooling katmanıdır. Modelde 2 adet 2×2’lik max. pooling katmanı mevcuttur. DropOut katmanı ise olası overfitting problemlerini önlemek için eklenmiştir. Bu katmandaki 0.5 değeri, DropOut’dan önceki katman ile sonraki katman arasındaki bağlantıları %50 azaltmasını sağlar.

history = model.fit(X_train, y_train, epochs = 10, validation_data = (X_val,y_val), batch_size = 400, verbose = 1, shuffle = 1)>>>
Train on 34799 samples, validate on 4410 samples
Epoch 1/10
34799/34799 [==============================] - 79s 2ms/step - loss: 3.5100 - accuracy: 0.0615 - val_loss: 3.3427 - val_accuracy: 0.1336
Epoch 2/10
34799/34799 [==============================] - 80s 2ms/step - loss: 1.4738 - accuracy: 0.5724 - val_loss: 0.5085 - val_accuracy: 0.8424
Epoch 3/10
34799/34799 [==============================] - 73s 2ms/step - loss: 0.4226 - accuracy: 0.8638 - val_loss: 0.3142 - val_accuracy: 0.9036
Epoch 4/10
34799/34799 [==============================] - 75s 2ms/step - loss: 0.2608 - accuracy: 0.9165 - val_loss: 0.2340 - val_accuracy: 0.9347
Epoch 5/10
34799/34799 [==============================] - 78s 2ms/step - loss: 0.2093 - accuracy: 0.9338 - val_loss: 0.2507 - val_accuracy: 0.9236
Epoch 6/10
34799/34799 [==============================] - 77s 2ms/step - loss: 0.1580 - accuracy: 0.9500 - val_loss: 0.2538 - val_accuracy: 0.9395
Epoch 7/10
34799/34799 [==============================] - 78s 2ms/step - loss: 0.1508 - accuracy: 0.9519 - val_loss: 0.2101 - val_accuracy: 0.9417
Epoch 8/10
34799/34799 [==============================] - 76s 2ms/step - loss: 0.1505 - accuracy: 0.9524 - val_loss: 0.2687 - val_accuracy: 0.9422
Epoch 9/10
34799/34799 [==============================] - 75s 2ms/step - loss: 0.1106 - accuracy: 0.9645 - val_loss: 0.1705 - val_accuracy: 0.9558
Epoch 10/10
34799/34799 [==============================] - 74s 2ms/step - loss: 0.1113 - accuracy: 0.9645 - val_loss: 0.1675 - val_accuracy: 0.9526

İlk modelde accuracy değeri : 0.9645 ve val_accuracy değeri : 0.9526 olarak belirlenmiştir. Burada başarı değerini artımak için izlenecek bazı yollar mevcuttur. Model yapısı değiştirilebilir, katman sayısı artırılabilir, öğrenme derecesi (learning_rate) düşürülerek epoch sayısı artırılabilir ve son olarak augmentation teknikleri (veri artırımı) yapılabilir [6]. Bunlardan bazılarını yapıya uygulacayacak olursak,

def data_aug():
data_generator= ImageDataGenerator(height_shift_range = 0.1, width_shift_range = 0.1, shear_range=0.1, zoom_range =0.1,rotation_range=10)
data_generator.fit(X_train)
return data_generator

Veri artırım işlemi için ImageDataGenerator kullanılmıştır [7]. Buradaki width_shift_range ile 0.1 oranında resim genişliği kayar, height_shift_range ile 0.1 oranında resim yükseliği kayar, zoom_range ile 0.1 oranında resim üzerine zoom yapılır, shear_range ile resim üzerinde eğiklik meydana getirilir. Son olarak da rotation_range ile resim 10 derece açı oluşturacak şekilde döndürülür. Burada sayılan işlemlerden yalnızca bir tanesi rastgele bir şekilde resimlere uygulanacaktır. Bu işlemler tamamlandıktan sonra yeni model oluşturulur.

def model_2():
model = Sequential()
model.add(Conv2D(80, (5,5), input_shape = (32,32,1), activation = "relu"))
model.add(Conv2D(80, (5,5), activation = "relu"))
model.add(MaxPooling2D(pool_size = (2,2)))
model.add(Conv2D(40, (3,3), activation = "relu"))
model.add(Conv2D(40, (3,3), activation = "relu"))
model.add(MaxPooling2D(pool_size = (2,2)))
#model.add(Dropout(0.5))
model.add(Flatten())
model.add(Dense(500, activation = "relu"))
model.add(Dropout(0.5))
model.add(Dense(num_classes, activation ="softmax"))
model.compile(Adam(lr= 0.001), loss = "categorical_crossentropy", metrics =[ "accuracy"])
return model
model = model_2()
print(model.summary())
>>>
______________________________________________________________
Layer (type) Output Shape Param #
=================================================================
conv2d_15 (Conv2D) (None, 28, 28, 80) 2080
_________________________________________________________________
conv2d_16 (Conv2D) (None, 24, 24, 80) 160080
_________________________________________________________________
max_pooling2d_9 (MaxPooling2 (None, 12, 12, 80) 0
_________________________________________________________________
conv2d_17 (Conv2D) (None, 10, 10, 40) 28840
_________________________________________________________________
conv2d_18 (Conv2D) (None, 8, 8, 40) 14440
_________________________________________________________________
max_pooling2d_10 (MaxPooling (None, 4, 4, 40) 0
_________________________________________________________________
flatten_5 (Flatten) (None, 640) 0
_________________________________________________________________
dense_9 (Dense) (None, 500) 320500
_________________________________________________________________
dropout_5 (Dropout) (None, 500) 0
_________________________________________________________________
dense_10 (Dense) (None, 43) 21543
=================================================================
Total params: 547,483
Trainable params: 547,483
Non-trainable params: 0
_________________________________________________________________
None

Modelde filtre sayılarında artışa gidilmiştir. Bunun yanı sıra learning_rate değeri de düşürülmüştür (0.01 → 0.001).

history = model.fit_generator(datagen.flow(X_train, y_train, batch_size=50), steps_per_epoch = 2000, epochs = 10,validation_data = (X_val,y_val), shuffle = 1)>>>
Epoch 1/10
2000/2000 [==============================] - 347s 173ms/step - loss: 0.4858 - accuracy: 0.8498 - val_loss: 0.0693 - val_accuracy: 0.9812
Epoch 2/10
2000/2000 [==============================] - 346s 173ms/step - loss: 0.1632 - accuracy: 0.9498 - val_loss: 0.0758 - val_accuracy: 0.9789
Epoch 3/10
2000/2000 [==============================] - 347s 173ms/step - loss: 0.1162 - accuracy: 0.9643 - val_loss: 0.0508 - val_accuracy: 0.9846
Epoch 4/10
2000/2000 [==============================] - 351s 176ms/step - loss: 0.0927 - accuracy: 0.9715 - val_loss: 0.0330 - val_accuracy: 0.9893
Epoch 5/10
2000/2000 [==============================] - 350s 175ms/step - loss: 0.0800 - accuracy: 0.9753 - val_loss: 0.0249 - val_accuracy: 0.9923
Epoch 6/10
2000/2000 [==============================] - 352s 176ms/step - loss: 0.0656 - accuracy: 0.9802 - val_loss: 0.0333 - val_accuracy: 0.9887
Epoch 7/10
2000/2000 [==============================] - 348s 174ms/step - loss: 0.0598 - accuracy: 0.9822 - val_loss: 0.0176 - val_accuracy: 0.9941
Epoch 8/10
2000/2000 [==============================] - 351s 176ms/step - loss: 0.0562 - accuracy: 0.9827 - val_loss: 0.0342 - val_accuracy: 0.9891
Epoch 9/10
2000/2000 [==============================] - 348s 174ms/step - loss: 0.0525 - accuracy: 0.9843 - val_loss: 0.0215 - val_accuracy: 0.9934
Epoch 10/10
2000/2000 [==============================] - 346s 173ms/step - loss: 0.0515 - accuracy: 0.9851 - val_loss: 0.0273 - val_accuracy: 0.9932

İlk model sonuçlarına göre ( accuracy : 0.9645 ve val_accuracy : 0.9526) veri artırımı ve model optimizasyonu gibi yöntemler kullanılmasıyla birlikte ikinci model sonuçlarında (accuracy : 0.9851 ve val_accuracy: 0.9932) artış gözlenmiştir. Bunun yanı sıra ilk modeldeki overfitting durumu ikinci model ile giderilmiştir.

score = model.evaluate(X_test, y_test, verbose = 0)
print(score[1])
>>> 0.9798337316513062

Test sonuçlarına göre accuracy değer 0.98 elde edilir.

Bu proje ile Convolutional Neural Network yapısının, resim tanıma problemlerinde nasıl kullanıldığı temel olarak anlatılmıştır. Gelecek çalışmalarda, bu yapının video tanıma-işleme problemlerinde nasıl kullanıldığı işlenecektir.

“Çalışmak hayat, düşünmek ışıktır.” (Victor Hugo)

Referanslar

[1] W. S. McCulloch, W.Pitts, “A logical calculus of the ideas immanent in nervous activity”, The bulletin of mathematical biophysics, 5,115–133, December 1943.

[2] N. Jmour, S. Zayen, A. Abdelkrim, “Convolutional neural networks for image classification”, Conference: 2018 International Conference on Advanced Systems and Electric Technologies (IC_ASET), March 2018.

[3] https://www.researchgate.net/figure/Illustration-of-the-convolution-operation-to-produce-convolved-feature-pink-colour-is_fig2_334783857

[4] https://guff.com/if-you-can-spot-the-difference-in-these-8-puzzles-youre-a-genius

[5] http://ehlisanatevi.com/insan-anatomisi-temelleri-yuz-ifadelerine-ustalasma-1057/

[6] A.Mikołajczyk, M. Grochowski, “Data augmentation for improving deep learning in image classification problem”, 2018 International Interdisciplinary PhD Workshop (IIPhDW), May 2018.

[7] X. Wang, J. Huang, J. Zhu, M. Yang, “Facial expression recognition with deep learning”, ICIMCS ’18: Proceedings of the 10th International Conference on Internet Multimedia Computing and Service, August 2018.