Boltzmann makinesinde ağırlıkların öğrenilmesi


14

Boltzmann makinelerinin nasıl çalıştığını anlamaya çalışıyorum, ancak ağırlıkların nasıl öğrenildiğinden emin değilim ve net bir açıklama bulamadım. Aşağıdakiler doğru mu? (Ayrıca, iyi Boltzmann makine açıklamalarına işaret etmek de harika olurdu.)

Bir dizi görünür birim (örn., Görüntüdeki siyah / beyaz piksele karşılık gelen) ve bir dizi gizli birimimiz var. Ağırlıklar bir şekilde başlatılır (örneğin, [-0,5, 0,5] 'ten eşit olarak) ve daha sonra, bir durma kuralına ulaşılana kadar aşağıdaki iki faz arasında geçiş yaparız:

  1. Kenetli faz - Bu aşamada, görünür birimlerin tüm değerleri sabittir, bu yüzden sadece gizli birimlerin durumlarını güncelleriz (Boltzmann stokastik aktivasyon kuralına göre). Ağ dengeye ulaşana kadar güncelleme yapıyoruz. Dengeye ulaştığımızda , ortalamasını (burada ve düğümlerinin durumlarıdır ) takip ederek daha fazla güncellemeye devam ediyoruz (önceden tanımlanmış bazı için ). Bu denge güncellemelerinden sonra , buradaN x i x j x i , x j i j N w i j = w i j + 1NNxixjxi,xjijNCwij=wij+1CAverage(xixj)Cbir miktar öğrenme oranıdır. (Ya da sonunda toplu güncelleme yapmak yerine, denge adımından sonra güncellenir miyiz?)

  2. Serbest aşama - Bu aşamada, tüm birimlerin durumları güncellenir. Dengeye ulaştığımızda, benzer şekilde N 'yi daha fazla güncellemeye devam ediyoruz, ancak sonunda korelasyon eklemek yerine şunu : .wij=wij1CAverage(xixj)

Temel sorularım:

  1. Kelepçeli fazdayken, görünür birimleri öğrenmek istediğimiz modellerden birine sıfırlıyor muyuz (o modelin önemini temsil eden bir miktar frekansla), yoksa görünür birimleri bulundukları durumda bırakıyor muyuz? serbest aşamanın sonunda?

  2. Her aşamanın sonunda ağırlıkların toplu olarak güncellenmesini veya aşamanın her bir denge adımında ağırlıkların güncellenmesini sağlıyor muyuz? (Ya da biri iyi mi?)

Yanıtlar:


6

Sezgisel olarak, görünür birimleri "modelin gördüğü" ve gizli birimleri "modelin zihin durumu" olarak düşünebilirsiniz. Tüm görünür birimleri bazı değerlere ayarladığınızda, "verileri modele gösterirsiniz". Ardından, gizli birimleri etkinleştirdiğinizde, model, gördüğü şeye göre zihin durumunu ayarlar.

Sonra modelin özgürleşmesini ve hayalini kurmasını sağlıyorsunuz. Kapanacak ve kelimenin tam anlamıyla zihninin ürettiği bazı şeyleri görecek ve bu görüntülere dayanan yeni zihin halleri üretecektir.

Ağırlıkları (ve sapmaları) ayarlayarak yaptığımız şey, modelin verilere daha fazla ve kendi fantezilerine daha az inanmasını sağlamaktır. Bu şekilde bir eğitimden sonra bazı (umarım) oldukça iyi bir veri modeline inanırız ve örneğin "bu çifte inanıyor musunuz (X, Y)? Bunu ne kadar olası buluyorsunuz? Boltzmann Makinesi? "

Son olarak, Kelepçeli ve Serbest fazların nereden geldiği ve bunları nasıl çalıştırmak istediğimiz hakkında bazı sezgiler vermesi gereken Enerji Tabanlı Modellerin kısa bir açıklaması.

http://deeplearning.net/tutorial/rbm.html#energy-based-models-ebm

Sezgisel olarak açık güncelleme kurallarının, model tarafından veri oluşturma olasılığının türetilmesinden ortaya çıktığını görmek komiktir.

Bu sezgileri akılda tutarak sorularınızı cevaplamak artık daha kolay:

  1. Görünür birimleri, modelin inanmasını istediğimiz bazı verilere sıfırlamak zorundayız. Serbest fazın sonundaki değerleri kullanırsak, sadece hayal kurmaya devam edecek, kendi yanlış yönlendirilmiş inançlarını uygulayacaktır.

  2. Aşama bittikten sonra güncelleme yapmak daha iyidir. Özellikle kenetlenmiş faz ise, modele verilere "odaklanmak" için biraz zaman vermek daha iyidir. Daha önceki güncellemeler yakınsama sürecini yavaşlatacaktır, çünkü model henüz gerçeğe uyum sağlamadığı zamanlarda bağlantıları zorunlu kılar. Fantazi yaparken her denge adımından sonra kilonun güncellenmesi daha az zararlı olmalıdır, ancak bununla ilgili hiçbir deneyimim yok.

EBM, BM ve RBM ile ilgili sezgilerinizi geliştirmek istiyorsanız, Geoffrey Hinton'un konu hakkındaki bazı derslerini izlemenizi tavsiye ederim, bazı iyi analojileri var.


2
  1. Evet, "görünür birimleri öğrenmek istediğimiz modellerden birine sıfırlıyoruz (sıkıştırıyoruz) (bu modelin önemini temsil eden bir miktar frekansla)."

  2. Evet, "her aşamanın sonunda ağırlıkların toplu bir güncellemesini yapıyoruz." "Anında her denge adımında ağırlıkların" güncellenmesinin hızlı yakınsamaya yol açacağını düşünmüyorum çünkü ağ "anlık hatalardan dolayı" dikkat dağılıyor "- Boltzmann makinelerini bu şekilde uyguladım ve çok iyi çalışmadığını hatırlıyorum toplu güncelleme olarak değiştirene kadar.


0

İşte Paul Ivanov'un koduna dayanan Boltzmann Makineleri için örnek Python kodu

http://redwood.berkeley.edu/wiki/VS265:_Homework_assignments

import numpy as np

def extract_patches(im,SZ,n):
    imsize,imsize=im.shape;
    X=np.zeros((n,SZ**2),dtype=np.int8);
    startsx= np.random.randint(imsize-SZ,size=n)
    startsy=np.random.randint(imsize-SZ,size=n)
    for i,stx,sty in zip(xrange(n), startsx,startsy):
        P=im[sty:sty+SZ, stx:stx+SZ];
        X[i]=2*P.flat[:]-1;
    return X.T

def sample(T,b,n,num_init_samples):
    """
    sample.m - sample states from model distribution

    function S = sample(T,b,n, num_init_samples)

    T:                weight matrix
    b:                bias
    n:                number of samples
    num_init_samples: number of initial Gibbs sweeps
    """
    N=T.shape[0]

    # initialize state vector for sampling
    s=2*(np.random.rand(N)<sigmoid(b))-1

    for k in xrange(num_init_samples):
        s=draw(s,T,b)

    # sample states
    S=np.zeros((N,n))
    S[:,0]=s
    for i in xrange(1,n):
        S[:,i]=draw(S[:,i-1],T,b)

    return S

def sigmoid(u):
    """
    sigmoid.m - sigmoid function

    function s = sigmoid(u)
    """
    return 1./(1.+np.exp(-u));

def draw(Sin,T,b):
    """
    draw.m - perform single Gibbs sweep to draw a sample from distribution

    function S = draw(Sin,T,b)

    Sin:      initial state
    T:        weight matrix
    b:        bias
    """
    N=Sin.shape[0]
    S=Sin.copy()
    rand = np.random.rand(N,1)
    for i in xrange(N):
        h=np.dot(T[i,:],S)+b[i];
        S[i]=2*(rand[i]<sigmoid(h))-1;

    return S

def run(im, T=None, b=None, display=True,N=4,num_trials=100,batch_size=100,num_init_samples=10,eta=0.1):
    SZ=np.sqrt(N);
    if T is None: T=np.zeros((N,N)); # weight matrix
    if b is None: b=np.zeros(N); # bias

    for t in xrange(num_trials):
        print t, num_trials
        # data statistics (clamped)
        X=extract_patches(im,SZ,batch_size).astype(np.float);
        R_data=np.dot(X,X.T)/batch_size;
        mu_data=X.mean(1);

        # prior statistics (unclamped)
        S=sample(T,b,batch_size,num_init_samples);
        R_prior=np.dot(S,S.T)/batch_size;
        mu_prior=S.mean(1);

        # update params
        deltaT=eta*(R_data - R_prior);
        T=T+deltaT;

        deltab=eta*(mu_data - mu_prior);
        b=b+deltab;


    return T, b

if __name__ == "__main__": 
    A = np.array([\
    [0.,1.,1.,0],
    [1.,1.,0, 0],
    [1.,1.,1.,0],
    [0, 1.,1.,1.],
    [0, 0, 1.,0]
    ])
    T,b = run(A,display=False)
    print T
    print b

Veri yamaları oluşturarak çalışır, ancak bu kod her zaman tüm veriler üzerinde çalışacak şekilde değiştirilebilir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.