Yapay Sinir Aglarina Giris

ABDULLAH ATCILI
Machine Learning Turkiye
7 min readJan 12, 2022

Bu yazıda Yapay Sinir agları hakkında giriş bilgisine sahip olmayı hedefliyoruz. Sinir ağlarını, insan vüducunda bulunan sinir ağları ile benzeştirerek yola çıkmak, en doğru yaklaşım tarzı olacaktır.

Örneğin, elimiz yandığında, o bölgede bulunan sinir uçları uyarılarak, merkezi kontrol sistemi beyin tarafından bir önlem mekanizması olarak elimizi çekmekteyiz. Veya bir şey yediğimizde ağzımızda bulunan sinir hücreleri ile tat almaktayız veya görmekteyiz veya duymaktayız vs.

Peki vücumuz için düşündüğümüz şeyleri, kaleme almak gerekirse, dışarıdan bir girdi oluyor, eğer bu girdilerin toplamı bir eşik değeri geçiyorsa, benim sinirlerim uyarılıyor ve ona göre aksiyon alıyorum. Şimdi bu durumu yapay sinir ağlarına uygulayalım.

Yapay Sinir Ağlarının temel şeması

Evet Yapay Sinir Ağlarının temel şemasında görüldüğü üzere, girdilerimiz ile bir çıktı oluşturuluyor. Bu girdilerden hangisinin daha ağırlıklı olduğunu weights diye tabir edilen ağırlık parametreleri ile tanımlıyoruz.

Şimdi bu aşamada Perceptron hakkında konuşmakta fayda var.

Perceptron Nedir

Perceptron, tek katmanlı bir yapay sinir ağının temel birimidir. Eğitilebilecek tek bir yapay sinir hücresinden oluşmaktadır. Denetimli bir öğrenme algoritmasıdır. Bir perceptron giriş değerleri, ağırlıklar ve sapma, ağırlıklı toplam ve aktivasyon işlevi olmak üzere dört bölümden oluşmaktadır.

Perceptron

Yukarıda görülen Perceptron hücresinde; X1, X2 ve X3 girdileri w1, w2 ve w3 ağırlıkları ile çarpılıp toplanarak, mor hücrede bulunuyor. Mor hücre daha sonra bir aktivasyon fonsiyonundan geçerek, y değerini üretiyor. Formüle dökmemiz gerekirse, Mor hücreye kadar olan toplam işlemi :

z = X1* w1 + X2*w2 + X3*w3 olarak tanımlanmaktadır. Akabinde bulunan z değeri aktivasyon fonksiyonundan geçirilmektedir.

a = g(z) # g fonksiyonu aktivasyon işlemini simgeler

dolayısıyla, a değeri bizim y_pred değerimizi tanımlamaktadır.

AND Gate ile Örnekleme

Şimdi bu aşamada örnekler ile yola devam etmemiz, konunun anlaşılması açısından önem arz etmektedir. İlk örnek olarak, Matematik’te, mantık derslerinden sıklıkla karşımıza çıkan AND kapısını örnekleyelim.

AND kapısında, girdilerin her ikisinin 1 olması durumunda sonuç 1, diğer durumlarda sonuç 0 olmaktadır.

AND kapısına ait Perceptron Modeli

Yukarıdaki AND kapısına ait Perceptron modelinde, en üstte tanımlanan hücre bias girdisi olarak tanımlanmaktadır. Modelin performansını artırmak için eklenen ek bir girdi olarak değerlendirilebilir. z değerini hesaplayarak başlayalım.

X1=X2= 0 durumu için z = 1 * -30 + X1*20 + X2*20 buradan z = -30

X1=0 ve X2= 1 durumu için z = 1 * -30 + X1*20 + X2*20 buradan z = -10

X1=1 ve X2= 0 durumu için z = 1 * -30 + X1*20 + X2*20 buradan z = -10

X1=X2= 1durumu için z = 1 * -30 + X1*20 + X2*20 buradan z = 10

olarak bulunur.

Şimdi burada kullanacağımız aktivasyon fonksiyonu ile z değerinin a değerine yani y_pred değerine dönüştürelim. Peki aktivasyon fonksiyonu olarak ne kullanıcaz? Şimdilik bu konunun detaylarına girmeden Step fonksiyonu ile devam ediyorum

Step Aktivasyon Fonksiyonu

Yukarıdaki Step Aktivasyon Fonksiyonu grafiğinden görüldüğü üzere, girdi 0'dan küçük ise cevap 0, 0'dan büyük ise cevap 1 olmaktadır.

Dolayısıyla yukarıda hesapladığımız z değerlerinin negatif veya pozitif değer almasına göre tahminimiz şekillenecektir. Şimdi z değerleri ile tahminlerimizi hesaplayapalım :

X1=X2= 0 durumu için z = -30 dolayısıyla a(-30) = 0

X1=0 ve X2= 1 durumu için z = -10 dolayısıyla a(-10) = 0

X1=1 ve X2= 0 durumu için z = -10 dolayısıyla a(-10) = 0

X1=X2= 1durumu için z = 10 dolayısıyla a(10) = 1

Görüldüğü üzere, X1 ve X2 girdileri ile bir AND gate oluşturuldu ve sonuçlar doğru şekilde tahmin edildi.

OR Gate ile Örnekleme

Şimdi daha anlaşılır olması açısından OR gate içinde aynı örneği tekrar edelim isterseniz. OR kapısında sadece girdiler 0 olduğunda sonuç 0, diğer durumlarda sonuç 1 olur.

OR kapısına ait Perceptron Modeli

X1=X2= 0 durumu için z = 1 * -10 + X1*20 + X2*20 buradan z = -10

X1=0 ve X2= 1 durumu için z = 1 * -10 + X1*20 + X2*20 buradan z = 10

X1=1 ve X2= 0 durumu için z = 1 * -10 + X1*20 + X2*20 buradan z = 10

X1=X2= 1durumu için z = 1 * -10 + X1*20 + X2*20 buradan z = 30

olarak bulunur.

Yine bulduğumuz z değerlerini step aktivasyon fonskiyonunda geçirelim.

X1=X2= 0 durumu için z = -10 dolayısıyla a(-30) = 0

X1=0 ve X2= 1 durumu için z = 10 dolayısıyla a(-10) = 1

X1=1 ve X2= 0 durumu için z = 10 dolayısıyla a(-10) = 1

X1=X2= 1durumu için z = 30 dolayısıyla a(10) = 1

olarak tahminlerimizi yaptık ve görüldüğü üzere OR kapısının sonucuna ulaştık. Yani sadece girdiler 0 olduğunda sonuç 0, diğer durumlarda sonuç 1 oluyor.

Peki buraya kadar dikkatimizi çeken bir şey oldu mu? Perceptron sadece lineer ayrım olan çözümler sunmakta, yani non-lineer sorunlar ile başa çıkamamaktadır.

Çok Katmanlı Sinir Ağları

O yüzden şimdi isterseniz Non-lineer çözümleri sağlayacak sinir ağları üzerinde konuşalım biraz.

Çok Katmanlı Yapay Sinir Ağı Modeli

Perceptron modelinde sadece girdi ve çıktı katmanı bulunmakta idi. Şimdi gördüğümüz modelde ise, girdi katmanı (input layer), arada bulunan gizli katmanlar (hidden layers) ve çıktı katmanı (output layer) bulunmaktadır. Yukarıdaki gösterimde çıktı katmanı binary çıktı içermektedir. Normalde daha fazla çıktılarıda içerebilir.

İleri Besleme Nedir

Şimdi Perceptron modelinde yaptığımız gibi, girdiler ile ağırlıkları çarparak, y_pred değerini hesaplayalım. Daha önce Perceptron modelinde sadece a ve z tanımlamaları yapmıştık ama şimdi çok katman var. Dolayısıyla a ve z değerlerini farklı numaralar ile tanımlamak gerekecek.

z1 = X * W1

a1 = g(z1) # ikinci katmanın girdisi artık a1 değerleri oluyor.

z2 = a1 * W2

a2 = g(z2) # üçüncü katmanın girdisi artık a2 değerleri oluyor.

Bu şekilde, gizli katmanlar boyunca, girdiler ile ağırlıklar çarpılıp, aktivasyon fonskiyonundan geçiriliyor. İşte burada, girdiler ile ağırlıkların çarpılarak ileri doğru ilerlenmesi işlemine Feed forward denir.

Şimdi isterseniz Python kodları ile bu işlemi hep beraber yaparak ilerleyelim.

X = np.array([[0,0], [0,1],[1,0],[1,1]])
y = np.array([0,0,0,1]).reshape(-1,1)
weights1 = np.random.random((2,4))
weights2 = np.random.random((4,1))

X, y ve ağırlıklar üretildi. Şimdi feed forward işlemini yapalım. Aktivasyon fonksiyonu olarak Sigmoid fonksiyonunu kulllanıyorum.

#feed forwarddef sigmoid(x):
return (1/(1+np.exp(-x)))
z1 = np.dot(X,weights1)
a1 = sigmoid(z1)
z2 = np.dot(a1,weights2)
a2 = sigmoid(z2)
ypred = a2

Feed forward işlemi ile bir tahminde bulunan modelimizin, artık gerçek diğer ile karşılaştırılarak, farkın tespit edilmesi gerekmektedir. Burada Cost function konusu gündeme gelmektedir. Aslında cost function(maliyet fonksiyonu), Logistik Regresyon modelinde olduğu gibidir. Gerçek değer ile tahmin değer arasındaki farklılık tespit edilmeye çalışılır, tabiiki amacımız maliyet fonksiyonunun minumum değer almasıdır. Maliyet fonksiyonu hakkında detaylı bilgiye buradan erişebilirsiniz.

#losshata = y * (-np.log(ypred)) + (1-y) * (-np.log(1-ypred))

Geri yayılım nedir

Maliyetler de bulunduktan sonra, sırada artık ağırlıkların güncellenerek optimize edilmesi var. Bu işleme ise back propagation adı verilmektedir. Back propagation işleminde, yapılan tahminden geriye doğru gidilerek, ağırlıklara göre türev alma işlemi vardır. Türev ile ağırlık değerlerinin optimize edilmesi amaçlanmaktadır.

# back propagationdef turev(x):
return x*(1-x)
dl = (-y / ypred) + ((1-y) / (1-ypred))
dz2 = dl * turev(a2) # ypred’in a2'ye göre türevi
dw2 = a1.T @ dz2 #de/dw2 =(de/dz2)*(dz2/dw2) ağırlık güncellemesi
da1 = dz2 @ weights2.T # (4,1)
dz1 = da1 * turev(a1)
dw1 = X.T @ dz1 # ağırlık güncellemesi

Artık son olarak türevleri bulunan ağırlıkların güncellenme işlemi kalmıştır.

#updating weights
lr = 0.1
weights2 -= lr * dw2
weights1 -= lr * dw1

Bu aşamaya kadar, ağırlık güncellemesinin bir turunda neler yaşandığından bahsettik. Genel olarak hatırlamak gerekirse,

  • Girdiler ile ağırlıklar çarpılarak ileri besleme yaptık (feed forward)
  • Tahmin ile gerçek değer arasındaki maliyet bulundu (Cost)
  • Bulunan maliyet ile geri yayılım yapıldı (back propagation)
  • Back propagation ile bulunan ağırlık türevleri ile ağırlıklar optimize edildi.

Yukarıda yazılan sıralama sadece 1 turda (epoch) yapılan işlemleri anlatmaktadır. Aslında bir turda random olarak başlatılan ağırlıkların yeteri kadar optimize edilemeyeciğini sanırım sizlerde şu an düşünüyorsunuz. O halde bu işlemi belki 10, belki 100, belkide binlerce kez tekrarlayarak ağırlıkları optimize etmeyi, dolayısıyla da maliyeti minimize etmeyi amaçlamaktayız.

Şu ana kadar anlatılan işlemlerin tamamını burada bulunan scriptte bulabilirsiniz. Örnek scriptte, OR kapısına ait kod bloğu mevcuttur. Siz y değerini değiştirerek, isterseniz AND ve OR gibi lineer sorulara çözüm bulabilir veya isterseniz XOR, XNOR gibi lineer olmayan sorunlara da çözüm bulabilirsiniz.

Sinir ağlarına giriş kapsamında söylemek istediklerim bu kadardı. Umarım faydalı olmuştur…

--

--