Son Haberler
Anasayfa / C# / XOR (Yapay Sinir Ağı) Örneği (C#)

XOR (Yapay Sinir Ağı) Örneği (C#)

Yapay sinir ağları (YSA), canlıların beyninin bilgi işleme tekniğinden esinlenerek geliştirilmektedir. YSA ile basit biyolojik sinir sisteminin çalışma şekli simüle edilir (benzetilir). Simüle edilen sinir hücreleri nöronlar içerirler ve bu nöronlar çeşitli şekillerde birbirlerine bağlanarak ağı oluştururlar. Bu ağlar öğrenme, hafızaya alma ve veriler arasındaki ilişkiyi ortaya çıkarma kapasitesine sahiptirler. Diğer bir ifadeyle, YSA’lar, normalde bir insanın düşünme ve gözlemlemeye yönelik doğal yeteneklerini gerektiren problemlere çözüm üretmektedir. Bir insanın, düşünme ve gözlemleme yeteneklerini gerektiren problemlere yönelik çözümler üretebilmesinin temel sebebi ise insan beyninin ve dolayısıyla insanın sahip olduğu yaşayarak veya deneyerek öğrenme yeteneğidir.( wikipedia)

Adaline

1959’da, Stanford Üniversitesinden Bernard Widrow, basit nöron benzeri elemanlara dayanan ve “Adaline” (Adaptive Linear Nöron) olarak adlandırılan bir adaptif lineer elemanı geliştirmiştir. Adaline yapısı tüm sinir ağlarının en basitidir ve öğrenme için danışmanlı öğrenmeyi kullanır. Adaline ve iki tabakalı biçimi olan “madaline” (Multiple Adaline); ses tanıma, karakter tanıma, hava tahmini ve adaptif kontrol gibi çok çeşitli uygulamalar için kullanılmıştır. Daha sonraları adaline, ayrık bir çıkış yerine sürekli bir çıkış üretmek için geliştirilmiştir. Widrow, telefon hatları üzerindeki ekoları elimine etmeye yarayan adaptif filtreleri geliştirmede, adaptif lineer eleman algoritmasını kullanmıştır. Bununla ilk defa YSA’lar gerçek bir probleme uygulanmıştır. Adaline bir çok uygulama için oldukça iyi çalışmasına rağmen lineer problem uzayıyla sınırlıdır. Lineer transfer fonksiyonu kullanırlar. Giriş ve istenilen çıkış desenlerinin tekrar tekrar ağa uygulanmasıyla eğitim gerçekleştirilir. Desenlerin doğru sınıflara ayrılmasıyla, hatalar minimize edilerek öğrenme gerçekleştirilir. Eğitimden sonra adaline, yeni girişleri kazandığı deneyime göre sınıflandırabilir.

Adaline Ünitesinin Öğrenme Kuralı

Adaline ünitesinin öğrenme kuralı, YSA’lardaki geneler öğrenme prensibine göre çalışmaktadır. Girdilerden çıktılar hesaplanır ve ağırlıklar çıktıya göre değiştirilir. ADALİNE ünitesinin net girdisi Net ve çıktısı (Ç) aşağıdaki formül ile hesaplanmaktadır.

NET = ∑w i x i+f

Eğer NET >= 0 çıktı (Ç)=1
Eğer NET < 0 çıktı (Ç)=-1
Çıktı hesaplandıktan sonra, ADALİNE ünitesinin hatası aşağıdaki formül ile hesaplanır.
E=B-Ç Olacaktır.

Amaç, bu hatayı en aza indirecek ağırlıkları bulmaktır. Bunun için ağa her seferinde farklı örnekler gösterilerek hatalar hesaplanmakta ve ağırlıklar hatayı azaltacak şekilde değiştirilmektedir. Zaman içinde hata, olması gereken en küçük değere düşmektedir. Bu hatayı azaltmak için kullanılan kural şu formül ile gösterilmektedir.

 

Wy = We + a*E*Xi
Her hangi bir t a anında,
Wi (t) = Wi (t-1) + a * E* Xi olacaktır.

Wi (t) : Ağırlıkların t zamanındaki değerleri
Wi (t-1) : Ağırlıkların t zamanındaki değerleri
a : Öğrenme katsayısı
B: Beklenen Çıktı
E: Beklenen değer ile çıktı arasındaki hata
X: Girdiler

Benzer şekilde, eşik değerinin zaman içindeki değeri de

fy= fe + a (B-Ç)

formülü ile hesaplanır.

işlem Adımları

  • -0.5 ile 0.5 arasında ağırlık değerlerinin rastgele atanması(Biz kendimiz belirliyoruz);
  • Hedef çıktı ve girdi değerlerinin seçimi,
  • Hata oranının hesaplanması,
  • Ağırlıkların düzenlenmesi,
  • Hata değeri sıfır olana kadar işlemin devamı,
  • Yeni girdilerin verilecek işlemin devam

Örnek;

 

        double[] wg1h1 = new double[4], wg1h2 = new double[4], wg2h1 = new double[4], wg2h2 = new double[4], wh1ç1 = new double[4], wh2ç1 = new double[4], qh1 = new double[4], qh2 = new double[4], qç1 = new double[4];
        double[] g1 = new double[4], g2 = new double[4], h1 = new double[4], h2 = new double[4], ç1 = new double[4], Hataç1 = new double[4], Hatah1 = new double[4], Hatah2 = new double[4];
        double alfa;
        double [] X1=new double[4],X2=new double[4],Y=new double[4];
//başlangıc değerlerinin atanması
            X1[0] = Convert.ToDouble(X1L0.Text); X2[0] = Convert.ToDouble(X2L0.Text); Y[0] = Convert.ToDouble(Y1txt.Text);
            X1[1] = Convert.ToDouble(X1L1.Text); X2[1] = Convert.ToDouble(X2L1.Text); Y[1] = Convert.ToDouble(Y2txt.Text);
            X1[2] = Convert.ToDouble(X1L2.Text); X2[2] = Convert.ToDouble(X2L2.Text); Y[2] = Convert.ToDouble(Y3txt.Text);
            X1[3] = Convert.ToDouble(X1L3.Text); X2[3] = Convert.ToDouble(X2L3.Text); Y[3] = Convert.ToDouble(Y4txt.Text);
            alfa=Convert.ToDouble(OgrenmeKatsayiText.Text);
           
            wg1h1[0] = Convert.ToDouble(WG1H1txt.Text); wg1h2[0] = Convert.ToDouble(WG1H2txt.Text);
            wg2h1[0] = Convert.ToDouble(WG2H1txt.Text); wg2h2[0] = Convert.ToDouble(WG2H2txt.Text);
            wh1c1[0] = Convert.ToDouble(WH1c1txt.Text); wh2c1[0] = Convert.ToDouble(WH2c1txt.Text);
            qh1[0] = Convert.ToDouble(QH2txt.Text); qh2[0] = Convert.ToDouble(QH1txt.Text);   qc1[0] = Convert.ToDouble(qc1txt.Text);
            
             wg1h1[1] = Convert.ToDouble(WG1H1txt.Text); wg1h2[1] = Convert.ToDouble(WG1H2txt.Text);
            wg2h1[1] = Convert.ToDouble(WG2H1txt.Text); wg2h2[1] = Convert.ToDouble(WG2H2txt.Text);
            wh1c1[1] = Convert.ToDouble(WH1c1txt.Text); wh2c1[1] = Convert.ToDouble(WH2c1txt.Text);
            qh1[1] = Convert.ToDouble(QH2txt.Text); qh2[1] = Convert.ToDouble(QH1txt.Text);   qc1[1] = Convert.ToDouble(qc1txt.Text);
            
             wg1h1[2] = Convert.ToDouble(WG1H1txt.Text); wg1h2[2] = Convert.ToDouble(WG1H2txt.Text);
            wg2h1[2] = Convert.ToDouble(WG2H1txt.Text); wg2h2[2] = Convert.ToDouble(WG2H2txt.Text);
            wh1c1[2] = Convert.ToDouble(WH1c1txt.Text); wh2c1[2] = Convert.ToDouble(WH2c1txt.Text);
            qh1[2] = Convert.ToDouble(QH2txt.Text); qh2[2] = Convert.ToDouble(QH1txt.Text); qc1[2] = Convert.ToDouble(qc1txt.Text);
            
             wg1h1[3] = Convert.ToDouble(WG1H1txt.Text); wg1h2[3] = Convert.ToDouble(WG1H2txt.Text);
            wg2h1[3] = Convert.ToDouble(WG2H1txt.Text); wg2h2[3] = Convert.ToDouble(WG2H2txt.Text);
            wh1c1[3] = Convert.ToDouble(WH1c1txt.Text); wh2c1[3] = Convert.ToDouble(WH2c1txt.Text);
            qh1[3] = Convert.ToDouble(QH2txt.Text); qh2[3] = Convert.ToDouble(QH1txt.Text); qc1[3] = Convert.ToDouble(qc1txt.Text);
            
            richTextBox1.Text = "";

            int a, i;
            for ( a = 0; a < Convert.ToDouble(iterasyonsayisitxt.Text); a++)
            {
                richTextBox1.AppendText("iterasyon :"+a+"");

                for ( i = 0; i < 4; i++)
                {
                    h1[i] = X1[i] * (wg1h1[i]) + X2[i] * (wg2h1[i]) + qh1[i];
                    h1[i] = 1 / (1 + (System.Math.Exp(-h1[i])));
                    h2[i] = g1[i] * (wg2h1[i]) + g2[i] * (wg2h2[i]) + qh2[i];
                    h2[i] = 1 / (1 + (System.Math.Exp(-h2[i])));
                    c1[i] = (h1[i] * (wh1c1[i])) + h2[i] * (wh2c1[i]) + qc1[i];
                    c1[i] = 1 / (1 + (System.Math.Exp(-c1[i])));


                    Hatac1[i] = c1[i] * (1 - c1[i]) * ((Y[i] - c1[i]));
                    // ((Y[0] - c1) + (coklu cıkış))  Birden fazla cıkış carsa işlemleri yapılıp toplanır
                    Hatah1[i] = h1[i] * (1 - h1[i]) * ((Hatac1[i] * wh1c1[i])+0);
                    Hatah2[i] = h2[i] * (1 - h2[i]) * ((Hatac1[i] * wh2c1[i])+0);
                
                    //Yeni Ağırlık  ve bias değerleri
                    wh1c1[i] = wh1c1[i] + (alfa * Hatac1[i] * h1[i]);
                    wh2c1[i] = wh2c1[i] + (alfa * Hatac1[i] * h2[i]);
                    wg1h1[i] = wh1c1[i] + (alfa * Hatah1[i] * X1[i]);
                    wg1h2[i] = wg1h2[i] + (alfa * Hatah2[i] * X1[i]);
                    wg2h1[i] = wg2h1[i] + (alfa * Hatah1[i] * X2[i]);
                    wg2h2[i] = wg2h2[i] + (alfa * Hatah2[i] * X2[i]);
                    qc1[i] = qc1[i] + (alfa * Hatac1[i]);
                    qh1[i] = qh1[i] + (alfa * Hatah1[i]);
                    qh2[i] = qh2[i] + (alfa * Hatah2[i]);

                    X1[i] = qh1[i]; X2[i] = qh2[i];

                    richTextBox1.AppendText(" \nwh1c1 :" + wh1c1[i] + "\n wh2c1 :" + wh2c1[i] + " \n wg1h1 : " + wg1h1[i] + "\n\n");
                    richTextBox1.AppendText(" \n wg1h2 :" + wg1h2[i] + "\n wg2h1 :" + wg2h1[i] + " \n  wg2h2 : " + wg2h2[i] + "\n\n");
                    richTextBox1.AppendText(" \n qc1 :" + qc1[i] + "\n qh1 :" + qh1[i] + " \n qh2 : " + qh2[i] + "\n\n");
                richTextBox1.AppendText("\nAdım: "+i+" \nG1 :"+X1[i]+"\n G2 :"+X2[i]+" \nSonuc : "+Y[i]+"\n\n");
                }

                             
            }