Backpropagation Algoritması ile Python’da Sinir Ağları Eğitimi

Giriş: Backpropagation Algoritmasının Temelleri

Backpropagation algoritması, yapay sinir ağlarının öğrenme süreçlerinde kritik bir öneme sahiptir. Bu algoritma, bir sinir ağı modelinin, tahminleri ve gerçek sonuçlar arasındaki hatayı minimize etmesine yardımcı olur. Backpropagation, temel olarak iki aşamadan oluşur: ileri yayılım ve geri yayılım. İleri yayılımda, girdiler sinir ağına sokulur ve çıktılar hesaplanır. Geri yayılım aşamasında ise, hesaplanan çıktı ile beklenen sonuç arasındaki hata, ağırlıkların güncellenmesi için kullanılır.

Sinir ağlarının öğrenebilmesi için, genellikle büyük miktarda verilere ihtiyaç vardır. Bu verilere dayalı olarak sinir ağı, belirli bir görevi yerine getirmek için gerekli ağırlıkları öğrenir. Backpropagation algoritması, bu ağırlıkların güncellenmesinin matematiksel temellerini sağlar. Sinir ağları, karmaşık fonksiyonları modelleme yeteneği ile öne çıkar ve bu algoritmanın uygulanışı sayesinde derin öğrenme modelleri de güçlenmektedir.

Bu yazıda, Python dilinde backpropagation algoritmasının uygulanmasını adım adım inceleyecek ve sinir ağı modelimizi nasıl oluşturacağımızı öğreneceğiz. Açıklamalarımız sırasında, algoritmanın temel bileşenlerini anlamak için gerekli matematiksel kavramlara da yer vereceğiz.

Sinir Ağı Modelinin Oluşturulması

Backpropagation algoritmasını kullanmadan önce, bir sinir ağı modelinin nasıl oluşturulacağını anlamamız gerekiyor. Python’da basit bir sinir ağı oluşturmak için NumPy kütüphanesini kullanacağız. İlk olarak, gerekli kütüphaneleri ve veri setimizi tanımlayarak başlayalım. Örneğimizde, basit bir sınıflandırma problemi üzerinde çalışacağız.

Örneğin, girdi olarak 2 özellik kullanan basit bir veri seti oluşturabiliriz. İşte bu veri setini tanımlayan bir Python kodu örneği:

import numpy as np

# Veri seti oluşturma (2 giriş değişkeni)
in X = np.array([[0, 0], [0, 1], [1, 0], [1, 1]])
# Çıkış etiketleri (XOR problemi)
y = np.array([[0], [1], [1], [0]])

Bu veri seti, temel bir XOR problemi içermektedir. İki girdi kullanarak, çıktının 1 veya 0 olup olmadığını belirlemeye çalışacağız. Şimdi sinir ağımızı kurmak için bir yapı oluşturalım.

Sinir ağımızda bir giriş katmanı, bir gizli katman ve bir çıkış katmanı olacaktır. Gizli katmanda, sinir hücrelerinin sayısını tanımlayacağız. Örneğin, 2 girdi ve 1 çıkış kullanarak basit bir yapı oluşturabiliriz:

class SimpleNeuralNetwork:
    def __init__(self):
        # Ağırlıkları rastgele başlat
        self.input_layer_size = 2  # Giriş katmanı boyutu
        self.hidden_layer_size = 2  # Gizli katman boyutu
        self.output_layer_size = 1  # Çıkış katmanı boyutu

        # Ağırlıkların rastgele başlatılması
        self.weights_input_hidden = np.random.rand(self.input_layer_size, self.hidden_layer_size)
        self.weights_hidden_output = np.random.rand(self.hidden_layer_size, self.output_layer_size)

Bu kod, giriş katmanından gizli katmana ve oradan çıkış katmanına geçen ağırlıkları tanımlar. Şimdi, ileri yayılım fonksiyonunu yazalım.

İleri Yayılım: Modelin Çıktısını Hesaplama

Sinir ağımızın ileri yayılım aşaması, girdilerin ağırlıklar ile çarpılıp bir aktivasyon fonksiyonu aracılığıyla çıktı ürettiği bir aşamadır. Bu örnekte, sigmoid aktivasyon fonksiyonunu kullanacağız. Sigmoid fonksiyonu, çıktının 0 ile 1 arasında olmasını sağlar ve matematiksel olarak şöyle tanımlanır:

def sigmoid(x):
    return 1 / (1 + np.exp(-x))

İleri yayılım fonksiyonumuzu tanımlayalım. Bu fonksiyon, girdileri alacak, ağırlıklarla çarpacak ve sonra aktivasyon fonksiyonunu uygulayarak çıktıyı döndürecektir:

def forward_pass(self, X):
    self.hidden_layer_activation = np.dot(X, self.weights_input_hidden)
    self.hidden_layer_output = sigmoid(self.hidden_layer_activation)
    self.output_layer_activation = np.dot(self.hidden_layer_output, self.weights_hidden_output)
    return sigmoid(self.output_layer_activation)

Bu fonksiyon, girdi verisini alan ve son çıktıyı döndüren basit bir ileri yayılım işlemi gerçekleştirir. Artık modelimizi eğitmek için geri yayılım aşamasına geçebiliriz.

Geri Yayılım: Hataların Hesaplanması ve Ağırlıkların Güncellenmesi

Backpropagation algoritmasının geri yayılım aşamasında, modelin tahmin ettiği değerler ile gerçek değerler arasındaki hata hesaplanır. Bu hata, ağırlıkların güncellenmesi için kullanılır. Hatanın hesaplanması için genellikle MSE (Mean Squared Error) kaybı kullanılır:

def calculate_loss(self, y_true, y_pred):
    return np.mean((y_true - y_pred) ** 2)

Bu kayıptan elde edilen hata değeri, ağırlıkları güncelleyebilmek için kullanılacaktır. Ağırlıkların güncellenmesi için gradyan iniş yöntemini kullanacağız. Geri yayılım işlemi, her katmandaki ağırlıkları güncelleyerek başlar.

Geri yayılım fonksiyonunu tanımlayalım:

def backpropagation(self, X, y, learning_rate=0.1):
    # Kayıp hesapla
    y_pred = self.forward_pass(X)
    loss = self.calculate_loss(y, y_pred)

    # Gradyanları hesapla
    output_error = y - y_pred  # Çıkış hatası
    output_delta = output_error * (y_pred * (1 - y_pred))  # Çıkış katmanındaki delta

    hidden_error = output_delta.dot(self.weights_hidden_output.T)  # Gizli katmandaki hata
    hidden_delta = hidden_error * (self.hidden_layer_output * (1 - self.hidden_layer_output))  # Gizli katmandaki delta

    # Ağırlıkları güncelle
    self.weights_hidden_output += self.hidden_layer_output.T.dot(output_delta) * learning_rate
    self.weights_input_hidden += X.T.dot(hidden_delta) * learning_rate
    return loss

Bu geri yayılım fonksiyonu, her dönemde ağırlıkları güncelleyerek modeli eğitecektir. Şimdi modelimizi eğitmek için döngü oluşturalım.

Modelin Eğitilmesi

Modelimizi eğitmek için, bir döngü içerisinde verimizi belirli sayıda epokta geçireceğiz. Her döngüde ileri ve geri yayılım fonksiyonlarını çağırarak ağırlıkları güncelleyeceğiz. İşte model eğitimi için kullanılacak bir kod yapısı:

def train(self, X, y, epochs=10000):
    for epoch in range(epochs):
        loss = self.backpropagation(X, y)
        if epoch % 1000 == 0:
            print(f'Epoch {epoch} - Loss: {loss}')

Bu fonksiyon, belirtilen epok sayısı kadar modelimizi eğitecektir. Her 1000 epokta bir kaybı yazdırarak eğitim sürecini izleyebiliriz.

Şimdi, yukarıda tanımladığımız sinir ağı sınıfını ve bu fonksiyonları kullanarak modelimizi oluşturabiliriz. Aşağıdaki kod parçasında, sınıfı örneklendirip modelimizi eğitiyoruz:

nn = SimpleNeuralNetwork()
nn.train(X, y)

Tüm kodu çalıştırdığınızda, modelinizin öğrenme süreci ve kayıp değeri hakkında bilgi sahibi olacaksınız. Model eğitimi tamamlandıktan sonra, modelimizin çıktılarını değerlendirme şansımız olacaktır.

Sonuçların Değerlendirilmesi

Modelimizi eğittikten sonra, çıktıları değerlendirerek modelimizin ne kadar iyi çalıştığını kontrol edebiliriz. Girdi değerlerini kullanarak modelin tahmin ettiği çıktılar ile gerçek etiketler arasında bir karşılaştırma yapacağız:

predictions = nn.forward_pass(X)
print('Tahminler:', predictions)
print('Gerçek Etiketler:', y)

Bu işlem, modelimizin performansını değerlendirmeye yardımcı olacaktır. Eğer sonuçlar başarılıysa, model iyi bir öğrenme gerçekleştirmiş demektir. Herhangi bir hatada, modelin ağırlıklarının güncellenmesi sürecini geliştirmek için daha fazla eğitim yapabilir veya farklı aktivasyon fonksiyonları deneyebilirsiniz.

Backpropagation algoritması, sinir ağlarının merkezinde bulunan güçlü bir öğrenme mekanizmasıdır. Bu yazıda Python ile basit bir sinir ağı modeli oluşturarak algoritmanın nasıl çalıştığını inceledik. Öğrenme sürecini gözlemleyerek, modelimizdeki zayıflıkları belirleyip geliştirmeye yönelik adımlar atabiliriz.

Sonuç

Backpropagation algoritması sayesinde, sinir ağları karmaşık verileri anlamlandırma ve öğrenme yeteneğine sahip olurlar. Python, bu gibi yapay zeka uygulamaları için güçlü bir araçtır ve yukarıda tanımlanan süreç, öğrenmeye başlamak için sağlam bir temeldir. Bu sayede, veri bilimi ve makine öğrenimi alanlarında daha derinlemesine çalışmalar yapabiliriz.

Elde ettiğimiz bilgiler ve öğrendiklerimizle, Python’da sinir ağı oluşturma ve geri yayılım algoritmasını uygulama konusunda önemli bir başlangıç noktası oluşturmuş olduk. Daha karmaşık modeller ve farklı veri setleri ile deneyler yaparak bilgi birikimimizi sürekli artırabiliriz.

Umarım bu yazı, backpropagation algoritmasını ve Python’daki uygulamalarını anlamanızda faydalı olmuştur. Şimdi, öğrendiğiniz bu bilgileri kendi projelerinize entegre ederek denemeler yapma zamanı!

Scroll to Top