Perceptron (Yapay sinir ağları)

Yapay sinir ağları, yapay zeka sayesinde bir süredir yine oldukça popüler konulardan biri oldu. Yaklaşık çeyrek asır önce üniversitede bu dersi almıştım ve hoşuma gitmişti. Sanki yeterince hobim yokmuş gibi bu alandaki yeniliklere göz atmaya karar verdim. Yapay zeka uygulamalarını programlamak için olası en kolay yolların matlab ya da tensorflow tabanlı kütüphaneler olduğunu gördüm. Bu arada biraz python da öğrenebilirim belki dedim ve tensorflow kendimi akımına bıraktım.

Bu ikinci öğrenme aşamasında yaptıklarım üzerine yazılar yazmayı düşünüyorum. Sistem olarak Ubuntu 19.04 altında python 3.7 ve pip3 kullanıyorum. Editör olarak eclipse ve PyDev eklentisini (7.3 versiyonu) kullanıyorum. Bu sistemlerin kurulumu için internette bir sürü kaynak olduğundan bunlara şimdi girmeyeceğim.

İlk yazımda yapay sinir ağlarının temel taşlarından olan perceptron modeli üzerine bir animasyon göstermek istedim. Animasyonları mümkün olduğunca HTML 5 ile programlamak istiyorum. İlk animasyonda perceptron modelinin en basit halini programladım. Sadece bir girdisi ve tek bir ağırlık değeri var. Dolayısıyla hesaplamaları da oldukça kolay. Umarım anlaşılması da kolaydır. Bir sonraki animasyonda birden fazla girdisi olan perceptron programlayacağım.

Perceptron için basit bir blok diyagram

Perceptron kabaca birden fazla girdisi ve bir çıktısı olan bir nöron modelidir. Perceptrona gelen girdiler önce her girdiye ait olan ağırlık değerleriyle çarpılır ve sonra bu çarpımlar toplanır. Bu toplamlar belli bir değerin üzerindeyse bu perceptron aktifleşir, değilse aktifleşmez.

Şimdi animasyonla biraz oynayalım. Girdi değeri bu animasyon için -1 ile 1 aralığında seçilebiliyor. Ağırlık değeri de -10 ile 10 arasında seçilebiliyor. Ardından başlat düğmesine basıldığında yapılan hesaplamalar ekranda gösteriliyor. En sonunda perceptron etkinleşmişse yeşil, etkinleşmemişse kırmızı oluyor. Etkinleşme için bu animasyonda signum fonksiyonunu kullandım. Yani toplamın sonucu sıfırdan büyükse bu fonksiyon 1 değerini veriyor. Diğer her durumda da 0 değerini.

Animasyonun altında bir sayı doğrusu üzerinde seçilmiş ağırlık değeri için hangi girdilerde perceptronun etkinleşeceğini (yeşil renkli kısım) ve hangi girdi değerleri için etkinleşmeyeceğini (kırmızı renkli bölge) çizdirdim. Bu gösterim için JSXGraph kütüphanesini kullandım. Bu şekilden de anlaşıldığı gibi eğer ağırlık değeri pozitif ise, pozitif girdiler için etkinleşme olacak, negatif değerlerde perceptronun çıktısı 0 olacak. Eğer ağırlık değeri negatif ise bu sefer perceptron negatif girdiler için etkinleşecek ve pozitif girdiler için 0 çıktısını verecek. Bunu matematiksel olarak da görmek kolay. Yukarıdaki diyagramda sadece bir tek girdi ve tek ağırlık olduğunu var sayalım. Animasyonda kullandığım f fonksiyonu şu şekildedir.

math-sgn-function-in-cpp How to Implement The Sgn Function in C++? c / c++ math programming languages

O zaman çıktı fonksiyonunu şu şekilde yazabiliriz:

\(o = sign(i\cdot{w}) \)

Eğer girdi (i) sıfırsa ya da ağırlık (w) sıfırsa, çıktı 0 olacaktır ( o = sign(0) ). Bunun dışındaki durumlar için ise aşağıdaki şekilde olacaktır.

\(o = sign((w > 0) \cdot{( i < 0)}) = sign(< 0) = -1 \)

\(o = sign((w > 0) \cdot{( i > 0)}) = sign(> 0) = 1 \)

\(o = sign((w < 0) \cdot{( i < 0)}) = sign(> 0) = 1 \)

\(o = sign((w < 0) \cdot{( i > 0)}) = sign(< 0) = -1 \)

Yukarıda w > 0, pozitif ağırlık değerleri, i > 0 da pozitif girdi değerleri anlamına geliyor. sign(>0) da sign fonksiyonunun girdisinin pozitif olduğu anlamına geliyor. Aynı şekilde < işaretini de bu değerlerin negatif olduğu durumlar için kullandım.

Yani bu basit perceptron ağırlığın sıfır olmadığı durumda sayı doğrusunu hep sıfır noktasında ikiye bölüyor. Sıfırın bir tarafı için -1 değerini üretirken, diğer tarafı için de 1 çıktısını üretiyor. Bu şekliyle oldukça sıkıcı bir zeka birimine benziyor ama ileride bu aksaklıkların üstesinden gelmenin yollarına bakacağız.