Mempelajari bobot dalam mesin Boltzmann

14

Saya mencoba memahami cara kerja mesin Boltzmann, tetapi saya tidak begitu yakin bagaimana bobot dipelajari, dan belum dapat menemukan deskripsi yang jelas. Apakah yang berikut ini benar? (Juga, petunjuk penjelasan mesin Boltzmann yang bagus juga akan bagus.)

Kami memiliki satu set unit yang terlihat (mis., Terkait dengan piksel hitam / putih pada gambar) dan satu set unit tersembunyi. Bobot diinisialisasi entah bagaimana (misalnya, seragam dari [-0,5, 0,5]), dan kemudian kami bergantian antara dua fase berikut hingga beberapa aturan penghentian tercapai:

  1. Fase penjepit - Pada fase ini, semua nilai unit yang terlihat adalah tetap, jadi kami hanya memperbarui status unit yang tersembunyi (sesuai dengan aturan aktivasi stokastik Boltzmann). Kami memperbarui hingga jaringan mencapai keseimbangan. Setelah kami mencapai kesetimbangan, kami terus memperbarui lebih banyak kali (untuk beberapa telah ditentukan ), melacak rata-rata (di mana adalah keadaan node i dan j ). Setelah pembaruan equilibrium N tersebut , kami memperbarui w_ij = w_ij + \ frac {1} {C} Rata-rata (x_i x_j) , di mana CNNxsayaxjxsaya,xjsayajNwsayaj=wsayaj+1CSEBUAHverSebuahge(xsayaxj)Cadalah tingkat belajar. (Atau, alih-alih melakukan pembaruan batch di akhir, apakah kita memperbarui setelah kita menyeimbangkan langkah?)

  2. Fase bebas - Dalam fase ini, status semua unit diperbarui. Setelah kami mencapai kesetimbangan, kami juga terus memperbarui N kali lebih banyak, tetapi alih-alih menambahkan korelasi di akhir, kami kurangi: wsayaj=wsayaj-1CSEBUAHverSebuahge(xsayaxj) .

Jadi pertanyaan utama saya adalah:

  1. Setiap kali kita berada dalam fase penjepit, apakah kita mereset unit yang terlihat ke salah satu pola yang ingin kita pelajari (dengan beberapa frekuensi yang mewakili pentingnya pola itu), atau kita meninggalkan unit yang terlihat dalam keadaan di mana mereka berada pada akhir fase bebas?

  2. Apakah kita melakukan pembaruan batch bobot pada akhir setiap fase, atau memperbarui bobot pada setiap langkah keseimbangan dalam fase? (Atau, apakah keduanya baik-baik saja?)

raegtin
sumber

Jawaban:

6

Secara intuitif, Anda dapat menganggap unit yang terlihat sebagai "apa yang dilihat model" dan unit tersembunyi sebagai "model pikiran". Saat Anda mengatur semua unit yang terlihat ke beberapa nilai, Anda "menunjukkan data ke model". Kemudian, ketika Anda mengaktifkan unit tersembunyi, model menyesuaikan keadaan pikirannya dengan apa yang dilihatnya.

Selanjutnya Anda membiarkan model menjadi bebas dan berfantasi. Ini akan menjadi tertutup dan benar-benar melihat beberapa hal yang dihasilkan pikiran, dan menghasilkan keadaan pikiran baru berdasarkan gambar-gambar itu.

Apa yang kami lakukan dengan menyesuaikan bobot (dan bias) adalah membuat model lebih percaya pada data dan kurang pada fantasi itu sendiri. Dengan cara ini setelah beberapa pelatihan akan percaya pada beberapa (mudah-mudahan) model data yang cukup bagus, dan kita dapat misalnya bertanya "apakah Anda percaya pada pasangan ini (X, Y)? Seberapa besar kemungkinan Anda menemukannya? Apa pendapat Anda mr. Mesin Boltzmann? "

Akhirnya di sini adalah deskripsi singkat dari Model Berbasis Energi, yang akan memberi Anda beberapa intuisi dari mana fase Clamped dan Free berasal dan bagaimana kami ingin menjalankannya.

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

Sangat lucu untuk melihat bahwa aturan pembaruan yang jelas secara intuitif keluar dari derivasi log-kemungkinan menghasilkan data oleh model.

Dengan mengingat intuisi ini, sekarang lebih mudah untuk menjawab pertanyaan Anda:

  1. Kita harus mengatur ulang unit yang terlihat ke beberapa data yang kita ingin model percaya. Jika kita menggunakan nilai-nilai dari akhir fase bebas itu hanya akan terus berfantasi, dan menegakkan keyakinan itu sendiri salah arah.

  2. Lebih baik melakukan pembaruan setelah akhir fase. Terutama jika ini adalah fase penjepit, lebih baik memberikan model waktu untuk "fokus" pada data. Pembaruan sebelumnya akan memperlambat konvergensi, karena mereka menegakkan koneksi ketika model belum menyesuaikan keadaan pikiran dengan kenyataan. Memperbarui bobot setelah setiap langkah keseimbangan sambil berfantasi seharusnya tidak terlalu berbahaya, meskipun saya tidak punya pengalaman dengan itu.

Jika Anda ingin meningkatkan intuisi Anda pada EBM, BM, dan RBM saya sarankan menonton beberapa kuliah Geoffrey Hinton tentang subjek, ia memiliki beberapa analogi yang baik.

sjm.majewski
sumber
2
  1. Ya, "kami mengatur ulang (penjepit) unit yang terlihat ke salah satu pola yang ingin kami pelajari (dengan beberapa frekuensi yang mewakili pentingnya pola itu)."

  2. Ya, "kami melakukan pembaruan batch bobot di akhir setiap fase." Saya tidak berpikir bahwa memperbarui "bobot pada setiap langkah keseimbangan dalam fase" akan mengarah pada konvergensi cepat karena jaringan "terganggu" oleh kesalahan sesaat - Saya telah mengimplementasikan mesin Boltzmann seperti itu, dan saya ingat itu tidak bekerja dengan baik sampai saya mengubahnya menjadi pembaruan batch.

Neil G
sumber
0

Berikut adalah contoh kode Python untuk Mesin Boltzmann berdasarkan kode Paul Ivanov dari

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

Ini bekerja dengan membuat tambalan data, tetapi ini dapat dimodifikasi sehingga kode bekerja pada semua data sepanjang waktu.

BBDynSys
sumber