Takip et

Kısıtlı Boltzmann Makinelerine Pratik Bir Giriş: Minimal NumPy Uygulamasıyla

Kısıtlı Boltzmann Makinelerine Pratik Bir Giriş: Minimal NumPy Uygulamasıyla Kısıtlı Boltzmann Makineleri (RBM’ler), makine öğrenimi ve derin öğ…

Kısıtlı Boltzmann Makinelerine Pratik Bir Giriş: Minimal NumPy Uygulamasıyla

Kısıtlı Boltzmann Makineleri (RBM’ler), makine öğrenimi ve derin öğrenme alanında önemli bir yere sahip, olasılıksal, üretken yapay sinir ağlarıdır. Özellikle veri dağılımlarını öğrenme ve karmaşık örüntüleri keşfetme yetenekleriyle öne çıkarlar. Bu makalede, RBM’lerin temel prensiplerini, mimarisini, çalışma mekanizmasını ve eğitim algoritmasını derinlemesine inceleyecek, ardından bu güçlü modelin minimal bir NumPy uygulamasıyla nasıl hayata geçirilebileceğini adım adım göstereceğiz. Amacımız, hem teorik temeli sağlamak hem de pratik bir bakış açısı sunarak konuyu anlaşılır kılmaktır.

RBM Nedir ve Neden Önemlidir?

Kısıtlı Boltzmann Makineleri (RBM), Geoffrey Hinton tarafından geliştirilen, iki katmanlı, stokastik bir yapay sinir ağıdır. Üretken bir model olarak, eğitim verilerinin olasılık dağılımını öğrenmeyi amaçlar. Bu yeteneği sayesinde, eksik verileri tamamlayabilir, yeni veriler üretebilir ve veri setindeki gizli özellikleri keşfedebilir.

Üretken Modellerin Yeri

Makine öğreniminde iki ana model türü bulunur: ayırt edici (discriminative) ve üretken (generative). Ayırt edici modeller, belirli bir girdinin hangi sınıfa ait olduğunu tahmin etmeye odaklanırken (örneğin, bir resimde kedi mi köpek mi var), üretken modeller verinin kendisinin nasıl oluştuğunu öğrenir. RBM’ler, verinin altında yatan karmaşık olasılık dağılımını modelleyerek, gerçekçi yeni örnekler oluşturma veya eksik verileri tahmin etme gibi görevlerde kullanılabilir. Bu, onları veri sentezi, özellik öğrenimi ve anomali tespiti gibi alanlarda değerli kılar.

Derin Öğrenmedeki Rolü

RBM’ler, derin öğrenmenin ilk dönemlerinde büyük bir atılım sağlamıştır. Özellikle “Derin İnanç Ağları” (Deep Belief Networks – DBN) ve “Derin Boltzmann Makineleri” (Deep Boltzmann Machines – DBM) gibi daha karmaşık derin öğrenme mimarilerinin temel yapı taşı olarak kullanılmışlardır. Bir DBN, birden fazla RBM katmanının üst üste istiflenmesiyle oluşturulur ve her RBM katmanı, bir önceki katmandan gelen girdinin daha soyut bir temsilini öğrenir. Bu katmanlı öğrenme yaklaşımı, o dönemde derin ağların eğitimindeki zorlukların aşılmasına yardımcı olmuştur.

Temel Özellikler

RBM’lerin “kısıtlı” olmasının nedeni, aynı katman içindeki birimler arasında hiçbir bağlantının bulunmamasıdır. Yani, görünür birimler kendi aralarında veya gizli birimler kendi aralarında doğrudan bağlantıya sahip değildir. Sadece görünür katman ile gizli katman arasında iki yönlü bağlantılar mevcuttur. Bu kısıtlama, modelin matematiksel olarak daha yönetilebilir olmasını sağlar ve eğitim süreçlerini basitleştirir. Her birim, diğer birimlerin durumuna bağlı olarak ikili (binary) bir durum alır, ancak Gaussian RBM’ler gibi sürekli değerleri işleyebilen varyantları da mevcuttur.

RBM’in Temel Mimarisi

Bir Kısıtlı Boltzmann Makinesi, adından da anlaşılacağı gibi, belirli kısıtlamalara sahip basit ama güçlü bir ağ yapısına sahiptir. Bu yapı, iki ana katmandan oluşur ve bu katmanlar arasındaki etkileşimler modelin öğrenme yeteneğinin temelini oluşturur.

Görünür Katman (Visible Layer)

Görünür katman, RBM’in dış dünya ile etkileşim kurduğu katmandır. Bu katmandaki birimler (nöronlar), doğrudan giriş verilerini temsil eder. Örneğin, bir görüntüdeki pikseller, bir tavsiye sistemindeki kullanıcı derecelendirmeleri veya bir metindeki kelime varlığı gibi özellikler görünür birimler tarafından temsil edilebilir. Görünür birimler genellikle ikili (0 veya 1) değerler alır, ancak sürekli değerler için Gaussian RBM’ler gibi farklı varyantlar da mevcuttur. Görünür katmandaki birim sayısı, giriş verisinin boyutuna eşittir.

Gizli Katman (Hidden Layer)

Gizli katman, RBM’in verideki soyut, daha yüksek seviyeli özellikleri veya desenleri öğrendiği yerdir. Bu katmandaki birimler, doğrudan dış dünyadan girdi almaz; bunun yerine, görünür katmandaki birimlerin kombinasyonlarından çıkarılan özellikleri temsil eder. Gizli birimler de genellikle ikili değerler alır ve bu birimlerin sayısı, öğrenilmek istenen özelliklerin karmaşıklığına ve veri setinin yapısına göre belirlenir. Gizli katman, verinin daha kompakt ve anlamlı bir temsilini oluşturarak boyut indirgeme veya özellik çıkarımı gibi görevlerde kullanılabilir.

Bağlantılar ve Ağırlıklar (W)

RBM’deki tüm bağlantılar, görünür katmandaki bir birim ile gizli katmandaki bir birim arasındadır. Aynı katman içindeki birimler arasında hiçbir bağlantı yoktur. Her bir görünür-gizli bağlantısının bir ağırlığı (weight) vardır. Bu ağırlıklar, görünür ve gizli birimler arasındaki ilişkinin gücünü ve yönünü belirler. Eğitim süreci boyunca, bu ağırlıklar, RBM’in veri dağılımını en iyi şekilde temsil etmesini sağlayacak şekilde ayarlanır. Ağırlık matrisi W, görünür katmandaki m birim ile gizli katmandaki n birim arasındaki m x n boyutlu bağlantıları içerir.

Bias Terimleri (a, b)

Her bir görünür ve gizli birimin kendine ait bir bias terimi vardır.
* Görünür Bias’lar (a): Görünür katmandaki her bir birimin kendi başına aktif olma eğilimini belirler.
* Gizli Bias’lar (b): Gizli katmandaki her bir birimin kendi başına aktif olma eğilimini belirler.
Bu bias terimleri, ağın belirli bir birimi, diğer birimlerden bağımsız olarak ne kadar kolay aktive edebileceğini kontrol eder. Ağırlıklar gibi, bias terimleri de eğitim sırasında optimize edilir.

RBM Nasıl Çalışır?

RBM’ler, enerji tabanlı modellerdir. Sistemin bir “enerji” fonksiyonu vardır ve modelin amacı, düşük enerjiye sahip konfigürasyonlara daha yüksek olasılık atamaktır. Bu enerji fonksiyonu üzerinden olasılık dağılımını modellemek için Gibbs örneklemesi ve ileri/geri besleme mekanizmaları kullanılır.

Enerji Fonksiyonu

Bir RBM’in belirli bir görünür katman durumu v ve gizli katman durumu h için enerji E(v, h) aşağıdaki gibi tanımlanır:

E(v, h) = - Σᵢ bᵢvᵢ - Σⱼ cⱼhⱼ - ΣᵢΣⱼ vᵢWᵢⱼhⱼ

Burada:
* vᵢ ve hⱼ, sırasıyla i-inci görünür ve j-inci gizli birimin durumlarıdır (genellikle 0 veya 1).
* bᵢ ve cⱼ, sırasıyla i-inci görünür ve j-inci gizli birimin bias terimleridir.
* Wᵢⱼ, i-inci görünür birim ile j-inci gizli birim arasındaki ağırlıktır.

Bu enerji fonksiyonu, sistemin belirli bir konfigürasyonunun ne kadar “olası” olduğunu gösterir. Daha düşük enerji, daha yüksek olasılık anlamına gelir.

İleri Besleme (Visible to Hidden)

Görünür katmandan gizli katmana bilgi akışı, ileri besleme olarak adlandırılır. Bir görünür vektör v verildiğinde, her bir gizli birimin hⱼ aktivasyon olasılığı aşağıdaki formülle hesaplanır:

P(hⱼ=1 | v) = sigmoid(cⱼ + Σᵢ Wᵢⱼvᵢ)

Burada sigmoid(x) = 1 / (1 + e⁻ˣ) aktivasyon fonksiyonudur. Her bir gizli birim, bu olasılığa göre ikili bir değer (0 veya 1) alacak şekilde örneklenir. Bu süreç, giriş verisinden özelliklerin çıkarılmasını temsil eder.

Geri Besleme (Hidden to Visible)

Gizli katmandan görünür katmana bilgi akışı, geri besleme veya rekonstrüksiyon olarak adlandırılır. Gizli bir vektör h verildiğinde, her bir görünür birimin vᵢ aktivasyon olasılığı aşağıdaki formülle hesaplanır:

P(vᵢ=1 | h) = sigmoid(bᵢ + Σⱼ Wᵢⱼhⱼ)

Yine, her bir görünür birim bu olasılığa göre ikili bir değer (0 veya 1) alacak şekilde örneklenir. Bu süreç, öğrenilen özelliklerden orijinal giriş verisinin yeniden oluşturulmasını temsil eder.

Gibbs Örneklemesi

RBM’ler, enerji fonksiyonu üzerinden olasılık dağılımını modellemek için Gibbs örneklemesi adı verilen bir Markov Zinciri Monte Carlo (MCMC) tekniği kullanır. Gibbs örneklemesi, görünür ve gizli katmanlar arasında alternatif olarak örnekleme yaparak çalışır:
1. Görünür katman v verildiğinde, gizli katman h‘yi P(h|v) olasılığına göre örnekle.
2. Örneklenen h verildiğinde, görünür katman v‘yi P(v|h) olasılığına göre örnekle.
Bu adımlar art arda tekrarlanır. Yeterince adım sonra, sistem denge durumuna ulaşır ve örneklenen (v, h) çiftleri RBM’in öğrendiği dağılımdan geliyormuş gibi kabul edilebilir. Bu örnekleme süreci, özellikle eğitim algoritması olan Zıtlık Diverjansı’nda (Contrastive Divergence) kritik bir rol oynar.

Eğitim Algoritması: Zıtlık Diverjansı (CD)

RBM’leri eğitmek, modelin enerji fonksiyonunu optimize ederek veri dağılımını en iyi şekilde temsil eden ağırlık ve bias değerlerini bulmak anlamına gelir. Bu genellikle maksimum olabilirlik (maximum likelihood) ilkesiyle yapılır. Ancak, RBM’lerin olasılık fonksiyonunun doğrudan gradyanını hesaplamak, tüm olası görünür ve gizli durumların toplamını gerektirdiğinden hesaplama açısından çok maliyetlidir. Bu sorunu aşmak için Geoffrey Hinton, Zıtlık Diverjansı (Contrastive Divergence – CD) algoritmasını geliştirmiştir.

Amaç

CD algoritmasının temel amacı, modelin öğrendiği dağılım P_model(v) ile gerçek veri dağılımı P_data(v) arasındaki farkı (Kullback-Leibler Diverjansı) minimize etmektir. Bu, modelin eğitim verilerini daha iyi temsil etmesini sağlar. Algoritma, gradyan inişi prensibine dayanır ve ağırlıkları ve bias’ları bu farkı azaltacak yönde günceller.

CD-k Algoritması

CD algoritması, Gibbs örneklemesinin kısaltılmış bir versiyonunu kullanır. k terimi, Gibbs örneklemesinin kaç adım atılacağını ifade eder. Genellikle k=1 (CD-1) kullanılır çünkü pratik uygulamalarda şaşırtıcı derecede iyi sonuçlar verir ve hesaplama açısından çok daha verimlidir.

CD-1 algoritması şu adımları izler:
1. Pozitif Faz (Veri Fazı):
* Eğitim veri setinden bir giriş vektörü v⁰ alınır.
* v⁰‘dan gizli birimlerin aktivasyon olasılıkları P(h|v⁰) hesaplanır ve bu olasılıklara göre gizli birimler h⁰ örneklenir.
* Bu faz, veri dağılımından gelen örnekleri temsil eder.
2. Negatif Faz (Model Fazı):
* Örneklenen h⁰‘dan görünür birimlerin aktivasyon olasılıkları P(v|h⁰) hesaplanır ve bu olasılıklara göre görünür birimler v¹ örneklenir (rekonstrüksiyon).
* v¹‘den gizli birimlerin aktivasyon olasılıkları P(h|v¹) hesaplanır ve bu olasılıklara göre gizli birimler h¹ örneklenir.
* Bu faz, modelin mevcut durumundan üretilen örnekleri temsil eder.

Gradyan İnişi

Ağırlıklar ve bias’lar, pozitif ve negatif fazlardaki korelasyon farklarına göre güncellenir. Ağırlık Wᵢⱼ için güncelleme kuralı genellikle şu şekildedir:

ΔWᵢⱼ = η * ( _data - _model )

Burada:
* η (eta), öğrenme oranıdır.
* _data, pozitif fazdaki vᵢhⱼ ürününün beklenen değeridir (yani v⁰ ve h⁰ arasındaki korelasyon).
* _model, negatif fazdaki vᵢhⱼ ürününün beklenen değeridir (yani v¹ ve h¹ arasındaki korelasyon).

Benzer şekilde, bias’lar için güncellemeler:
Δbᵢ = η * ( _data - _model )
Δcⱼ = η * ( _data - _model )

Bu güncellemeler, modelin veri dağılımına daha yakın hale gelmesini sağlar. Pozitif faz, modelin veri örneklerine benzer konfigürasyonları tercih etmesini teşvik ederken, negatif faz, modelin kendi “hayal ettiği” konfigürasyonları gerçek veriden uzaklaştırmamasını sağlar.

Minimal NumPy Uygulaması

Şimdiye kadar öğrendiğimiz teorik bilgileri, Python’da NumPy kütüphanesi kullanarak basit bir RBM uygulamasında bir araya getirelim. Bu uygulama, ikili giriş verileriyle çalışacak minimal bir RBM sınıfı içerecektir.

Gerekli Kütüphaneler ve Veri Hazırlığı

Öncelikle, numpy kütüphanesini import etmemiz gerekiyor. Veri seti olarak, basit bir ikili veri seti oluşturacağız. Gerçek dünya uygulamalarında MNIST gibi veri setlerinin ikili versiyonları kullanılabilir.

import numpy as np

# Basit bir ikili veri seti oluşturalım (örneğin, 4x5 boyutunda)
# Her satır bir veri örneğini, her sütun bir özelliği temsil eder.
# Bu veriler genellikle 0 veya 1 olmalıdır.
data = np.array([
    [1, 0, 1, 0, 1],
    [1, 1, 0, 0, 1],
    [0, 1, 0, 1, 0],
    [0, 0, 1, 1, 0],
    [1, 0, 1, 0, 1],
    [0, 1, 0, 1, 0]
], dtype=float)

RBM Sınıfının Oluşturulması

RBM'in temel bileşenlerini (ağırlıklar, bias'lar) ve fonksiyonlarını (ileri/geri besleme, eğitim) içeren bir sınıf tanımlayacağız.

class RBM:
    def __init__(self, num_visible, num_hidden):
        self.num_visible = num_visible
        self.num_hidden = num_hidden

        # Ağırlıkları küçük rastgele değerlerle başlat
        self.weights = np.random.randn(self.num_visible, self.num_hidden) * 0.1
        # Görünür ve gizli bias'ları sıfırla başlat
        self.visible_bias = np.zeros(self.num_visible)
        self.hidden_bias = np.zeros(self.num_hidden)

    def _sigmoid(self, x):
        return 1 / (1 + np.exp(-x))

    # Görünür katmandan gizli katmana aktivasyon olasılıklarını hesapla
    def _propagate_hidden(self, visible_units):
        # v * W + c (gizli bias)
        h_activations = np.dot(visible_units, self.weights) + self.hidden_bias
        h_probs = self._sigmoid(h_activations)
        return h_probs

    # Gizli katmandan görünür katmana aktivasyon olasılıklarını hesapla
    def _propagate_visible(self, hidden_units):
        # h * W^T + b (görünür bias)
        v_activations = np.dot(hidden_units, self.weights.T) + self.visible_bias
        v_probs = self._sigmoid(v_activations)
        return v_probs

    # Gizli birimleri olasılıklara göre örnekle (0 veya 1)
    def _sample_hidden(self, h_probs):
        return (h_probs >= np.random.rand(*h_probs.shape)).astype(float)

    # Görünür birimleri olasılıklara göre örnekle (0 veya 1)
    def _sample_visible(self, v_probs):
        return (v_probs >= np.random.rand(*v_probs.shape)).astype(float)

Eğitim Fonksiyonu

Zıtlık Diverjansı (CD-1) algoritmasını kullanarak RBM'i eğitecek train metodunu ekleyelim.

def train(self, data, epochs, learning_rate, batch_size=1):
        num_samples = data.shape[0]

        for epoch in range(epochs):
            # Veri setini karıştır
            np.random.shuffle(data)
            
            for i in range(0, num_samples, batch_size):
                batch = data[i:i + batch_size]

                # Pozitif faz (Veri Fazı)
                # v0 -> h0
                h0_probs = self._propagate_hidden(batch)
                h0_states = self._sample_hidden(h0_probs) # h0_states yerine h0_probs da kullanılabilir
                                                          # ancak örnekleme daha stokastik yapar.
                
                # Negatif faz (Model Fazı - CD-1)
                # h0 -> v1 -> h1
                v1_probs = self._propagate_visible(h0_states)
                v1_states = self._sample_visible(v1_probs)
                h1_probs = self._propagate_hidden(v1_states)
                # h1_states = self._sample_hidden(h1_probs) # Genellikle h1_probs kullanılır

                # Gradyan hesaplamaları ve ağırlık/bias güncellemeleri
                # Ağırlık güncellemesi
                positive_gradient_W = np.dot(batch.T, h0_probs) # veya h0_states
                negative_gradient_W = np.dot(v1_states.T, h1_probs) # veya h1_states
                self.weights += learning_rate * (positive_gradient_W - negative_gradient_W) / batch_size

                # Görünür bias güncellemesi
                positive_gradient_vb = np.sum(batch - v1_states, axis=0)
                self.visible_bias += learning_rate * positive_gradient_vb / batch_size

                # Gizli bias güncellemesi
                positive_gradient_hb = np.sum(h0_probs - h1_probs, axis=0) # veya h0_states - h1_states
                self.hidden_bias += learning_rate * positive_gradient_hb / batch_size
            
            # Rekonstrüksiyon hatasını hesapla (isteğe bağlı)
            # Bu, modelin ne kadar iyi öğrendiğini gösteren bir metrik olabilir.
            reconstruction_error = np.mean(np.sum((data - self._propagate_visible(self._propagate_hidden(data)))**2, axis=1))
            print(f"Epoch {epoch+1}/{epochs}, Reconstruction error: {reconstruction_error:.4f}")

Örnekleme ve Rekonstrüksiyon

Eğitilmiş RBM'i kullanarak yeni veriler örnekleyebilir veya mevcut verileri yeniden oluşturabiliriz.

# Bir giriş verisini yeniden oluştur
    def reconstruct(self, visible_data):
        h_probs = self._propagate_hidden(visible_data)
        h_states = self._sample_hidden(h_probs)
        v_probs = self._propagate_visible(h_states)
        return v_probs # Olasılıkları veya örneklenmiş durumları döndürebiliriz

    # RBM'den yeni bir veri örneği üret
    def generate(self, num_samples=1):
        # Rastgele bir gizli durumla başla
        h_states = (np.random.rand(num_samples, self.num_hidden) >= 0.5).astype(float)
        
        # Gibbs örneklemesi ile birkaç adım ilerle
        for _ in range(100): # Yeterince adım dengeye ulaşmak için
            v_probs = self._propagate_visible(h_states)
            v_states = self._sample_visible(v_probs)
            h_probs = self._propagate_hidden(v_states)
            h_states = self._sample_hidden(h_probs)
        
        return v_states # Üretilen görünür durumları döndür

Uygulama ve Test

Şimdi RBM sınıfımızı kullanarak eğitim ve test yapalım:

# RBM modelini başlat
num_visible_units = data.shape[1]
num_hidden_units = 3 # Gizli birim sayısını deneyerek ayarlayabilirsiniz
rbm = RBM(num_visible_units, num_hidden_units)

# Modeli eğit
print("RBM Eğitimi Başlıyor...")
rbm.train(data, epochs=500, learning_rate=0.1, batch_size=len(data)) # Tam batch eğitimi
print("RBM Eğitimi Tamamlandı.")

# Bir örnek veriyi yeniden oluşturma
sample_to_reconstruct = data[0]
reconstructed_sample_probs = rbm.reconstruct(sample_to_reconstruct)
reconstructed_sample = (reconstructed_sample_probs >= 0.5).astype(int) # Olasılıkları ikiliye çevir

print("\nOrijinal örnek:", sample_to_reconstruct)
print("Yeniden oluşturulan (olasılık):", np.round(reconstructed_sample_probs, 2))
print("Yeniden oluşturulan (ikili):", reconstructed_sample)

# Yeni bir veri örneği üretme
generated_sample = rbm.generate(num_samples=1)
print("\nÜretilen yeni örnek:", generated_sample[0])

Bu minimal NumPy uygulaması, RBM'in temel çalışma prensiplerini ve CD-1 eğitimini net bir şekilde göstermektedir. Gerçek dünya uygulamaları için daha gelişmiş optimizasyon teknikleri, farklı aktivasyon fonksiyonları ve daha büyük veri setleri gerekebilir.

RBM'in Uygulama Alanları

Kısıtlı Boltzmann Makineleri, basit mimarilerine rağmen çeşitli makine öğrenimi görevlerinde etkili bir şekilde kullanılmıştır. Üretken doğaları ve özellik öğrenme yetenekleri, onları farklı alanlarda değerli kılar.

Boyut İndirgeme ve Özellik Çıkarımı

RBM'ler, yüksek boyutlu verileri daha düşük boyutlu, ancak anlamlı bir temsiline dönüştürmek için kullanılabilir. Gizli katman, giriş verisinin en önemli özelliklerini yakalayan bir "kodlama" görevi görür. Bu, veri sıkıştırma, gürültü giderme ve diğer algoritmalar için daha iyi özellik setleri oluşturma gibi görevlerde faydalıdır. Örneğin, bir görüntüdeki temel desenleri veya bir metindeki anahtar kavramları öğrenerek verinin daha kompakt bir temsilini sağlayabilir.

Tavsiye Sistemleri

Netflix Prize yarışması gibi büyük veri problemlerinde RBM'ler, tavsiye sistemlerinin geliştirilmesinde önemli bir rol oynamıştır. Kullanıcıların filmlere verdiği derecelendirmeler görünür katman olarak temsil edilebilir. RBM, kullanıcıların izleme alışkanlıklarındaki gizli desenleri (örneğin, belirli türleri veya yönetmenleri seven kullanıcı grupları) öğrenir. Bu öğrenilen desenler sayesinde, eksik derecelendirmeler tahmin edilebilir ve kullanıcılara henüz izlemedikleri filmler için kişiselleştirilmiş tavsiyelerde bulunulabilir.

Görüntü ve Ses İşleme

Görüntü işleme alanında RBM'ler, görüntü yamalarından özellik öğrenmek için kullanılmıştır. Örneğin, bir görüntünün küçük bölümlerini (patch) RBM'in görünür katmanına besleyerek, gizli katman kenarlar, köşeler veya belirli dokular gibi temel görsel özellikleri öğrenebilir. Benzer şekilde, ses işleme uygulamalarında konuş

Yorumlar
İçeriği beğendiniz mi? Bir tartışma başlatın veya görüşlerinizi paylaşın.
Yorum Yaz

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

E-posta Bülteni
Yazılım Topluluğuna Katılın
En son güncellemeleri, yaratıcı ipuçlarını ve özel kaynakları doğrudan e-posta kutunuza alın. Tasarım ve inovasyonun geleceğini birlikte keşfedelim.