日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > python >内容正文

python

受限玻尔兹曼机(RBM)与python在Tensorflow的实现

發(fā)布時(shí)間:2025/3/11 python 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 受限玻尔兹曼机(RBM)与python在Tensorflow的实现 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

任何程序錯(cuò)誤,以及技術(shù)疑問或需要解答的,請(qǐng)掃碼添加作者VX:1755337994

簡(jiǎn)介

受限玻爾茲曼機(jī)是一種無監(jiān)督,重構(gòu)原始數(shù)據(jù)的一個(gè)簡(jiǎn)單的神經(jīng)網(wǎng)絡(luò)。
受限玻爾茲曼機(jī)先把輸入轉(zhuǎn)為可以表示它們的一系列輸出;這些輸出可以反向重構(gòu)這些輸入。通過前向和后向訓(xùn)練,訓(xùn)練好的網(wǎng)絡(luò)能夠提取出輸入中最重要的特征。

為什么RBM很重要?

因?yàn)樗軌蜃詣?dòng)地從輸入中提取重要的特征。

RBM有什么用

用于協(xié)同過濾(Collaborative Filtering)
降維(dimensionality reduction)
分類(classification)
特征學(xué)習(xí)(feature leatning)
主題模型(topic modeling)
搭建深度置信網(wǎng)絡(luò)(Deep belief network)

RBM是生成模型嗎?

生成模型和判別模型的區(qū)別

判別模型: 考慮一個(gè)分類問題,如我們想根據(jù)車的一些特征分辨一輛轎車和一輛SUV。給定一個(gè)訓(xùn)練集,一個(gè)算法如邏輯回歸,它嘗試找到一條可以直線,以這條直線作為決策邊界把轎車和SUV區(qū)分開。
生成模型: 根據(jù)汽車,我們可以建立一個(gè)模型,比如轎車是什么樣子的;然后再根據(jù)SUV, 我們建立另外一個(gè)SUV的模型;最后根據(jù)這個(gè)兩個(gè)模型,判斷一輛車是轎車還是SUV.

生成模型在輸入特征下有特定的概率分布。 生成模型中既可以使用監(jiān)督學(xué)習(xí)和無監(jiān)督:
在無監(jiān)督學(xué)習(xí)中, 我們想要得到一個(gè)P(x)的模型, x是輸入向量;
在監(jiān)督學(xué)習(xí)中,我們首先得到的是P(x|y), y是x的標(biāo)記。舉個(gè)例子,如果y標(biāo)記一輛車是轎車(0)或者SUV(1), 那么p(x|y=0)就描述了轎車的特征是怎么分布的,p(x|y=1)就描述了轎車的特征是怎么分布的。 如果我們能夠找到P(x|y)和P(y), 我們就能夠使用貝葉斯公式去估算P(y|x),因?yàn)镻(y|x) = P(x|y)P(y)/P(x).

使用MINST 數(shù)據(jù)集展示如何使用RBMs

初始化并加載數(shù)據(jù)

這里要通過網(wǎng)絡(luò)獲取遠(yuǎn)程的文件utils.py到本地,python2 和 python3通過網(wǎng)絡(luò)獲取文件是不一樣的。
這里的代碼用python3。

import urllib.request response = urllib.request.urlopen('http://deeplearning.net/tutorial/code/utils.py') content = response.read().decode('utf-8') target = open('utils.py', 'w') target.write(content) target.close() import tensorflow as tf import numpy as np from tensorflow.examples.tutorials.mnist import input_data #!pip install pillow from PIL import Image # import Image from utils import tile_raster_images import matplotlib.pyplot as plt %matplotlib inline mnist = input_data.read_data_sets("MNIST_data/", one_hot=True) trX, trY, teX, teY = mnist.train.images, mnist.train.labels, mnist.test.images, mnist.test.labels

RBM的層

一個(gè)RBM有兩個(gè)層,第一層叫可視層(visible)或者輸入層,第二層是隱藏層( hidden layer)。MNIST數(shù)據(jù)庫的每一張圖片有784個(gè)像素,所以可視層必須有784個(gè)輸入節(jié)點(diǎn)。第二個(gè)隱藏層在這里設(shè)為i ii個(gè)神經(jīng)元。每一個(gè)神經(jīng)元是2態(tài)的(binary state), 稱為si。根據(jù)j jj個(gè)輸入單元,并由邏輯函數(shù)(logistic function) 產(chǎn)生一個(gè)概率輸出,決定每一個(gè)隱藏層的單元是開(si = 1)是還關(guān)(si =0)。 這里我們?nèi)?i = 500 i=500i=500.

第一層的每一個(gè)節(jié)點(diǎn)有一個(gè)偏差 (bias),使用vb表示;
第二層的每一個(gè)節(jié)點(diǎn)也有一個(gè)偏差,使用hb表示;

vb = tf.placeholder("float", [784]) hb = tf.placeholder("float", [500])

定義可視層和隱藏層之間的權(quán)重,行表示輸入節(jié)點(diǎn),列表示輸出節(jié)點(diǎn),這里權(quán)重W是一個(gè)784x500的矩陣。

W = tf.placeholder("float", [784, 500])

訓(xùn)練好RBM能做什么

當(dāng)RBM被訓(xùn)練好了,它就能夠在跟定一些隱藏值(如下雨)來計(jì)算一個(gè)事件(比如濕滑路面)的概率. 那就是說,RBM可以被看作是生成模型,它給每一個(gè)可能的二態(tài)向量( binary states vectors)生成一個(gè)概率。
這些二態(tài)向量( binary states vectors)多少種情況?
可視層可以有不同的二態(tài)(0或1),或者說有不同的設(shè)置。比如,當(dāng)輸入層只有7個(gè)單元時(shí),它有2 7 {2^{7}}27?中排列,每一種排列有它對(duì)應(yīng)的概率(這里我們假設(shè)沒有偏差)
- (0,0,0,0,0,0,0) --> p(config1)=p(v1)=p(s1=0,s2=0, …, s7=0)
- (0,0,0,0,0,0,1) --> p(config2)=p(v2)=p(s1=0,s2=1, …, s7=1)
- (0,0,0,0,0,1,0) --> p(config3)=p(v3)=p(s1=1,s2=0, …, s7=0)
- (0,0,0,0,0,1,1) --> p(config4)=p(v4)=p(s1=1,s2=1, …, s7=1)
- etc.
所以, 如果我們有784個(gè)單元,對(duì)于全部的2 784 {2^{784}}2784種輸入情況,它會(huì)產(chǎn)生一個(gè)概率分布,P(v)。

如何訓(xùn)練RBM

訓(xùn)練分為兩個(gè)階段:1) 前向(forward pass) 2)后向( backward pass)或者重構(gòu)(reconstruction):

階段1

前向:改變的是隱藏層的值。 輸入數(shù)據(jù)經(jīng)過輸入層的所有節(jié)點(diǎn)傳遞到隱藏層。這個(gè)計(jì)算是隨機(jī)開始(This computation begins by making stochastic decisions about whether to transmit that input or not (i.e. to determine the state of each hidden layer)). 在隱藏層的節(jié)點(diǎn)上,X乘以W再加上h_bias. 這個(gè)結(jié)果再通過sigmoid函數(shù)產(chǎn)生節(jié)點(diǎn)的輸出或者狀態(tài)。因此,每個(gè)隱藏節(jié)點(diǎn)將有一個(gè)概率輸出。對(duì)于訓(xùn)練集的每一行,生成一個(gè)概率構(gòu)成的張量(tensor),這個(gè)張量的大小為[1X500], 總共55000個(gè)向量[h0=55000x500]。 接著我們得到了概率的張量,從所有的分布中采樣,h0。 那就是說,我們從隱藏層的概率分布中采樣激活向量(activation vector). 這些得到的樣本用來估算反向梯度(negative phase gradient).

X = tf.placeholder("float", [None, 784]) _h0= tf.nn.sigmoid(tf.matmul(X, W) + hb) #probabilities of the hidden units h0 = tf.nn.relu(tf.sign(_h0 - tf.random_uniform(tf.shape(_h0)))) #sample_h_given_X

參考下面的代碼理解上面的代碼:

with tf.Session() as sess:a= tf.constant([0.7, 0.1, 0.8, 0.2])print sess.run(a)b=sess.run(tf.random_uniform(tf.shape(a)))print bprint sess.run(a-b)print sess.run(tf.sign( a - b))print sess.run(tf.nn.relu(tf.sign( a - b)))[0.7 0.1 0.8 0.2] [0.31160402 0.3776673 0.42522812 0.8557215 ] [ 0.38839597 -0.2776673 0.3747719 -0.6557215 ] [ 1. -1. 1. -1.] [1. 0. 1. 0.]

階段2

反向(重構(gòu)): RBM在可視層和隱藏層之間通過多次前向后向傳播重構(gòu)數(shù)據(jù)。
所以在這個(gè)階段,從隱藏層(h0)采樣得到的激活向量作為輸入。相同的權(quán)重矩陣和可視層偏差將用于計(jì)算并通過sigmoid函數(shù)。其輸出是一個(gè)重構(gòu)的結(jié)果,它近似原始輸入。

_v1 = tf.nn.sigmoid(tf.matmul(h0, tf.transpose(W)) + vb) v1 = tf.nn.relu(tf.sign(_v1 - tf.random_uniform(tf.shape(_v1)))) #sample_v_given_h h1 = tf.nn.sigmoid(tf.matmul(v1, W) + hb)

重構(gòu)步驟:

  • 從數(shù)據(jù)集中拿一個(gè)數(shù)據(jù), 如x, 把它通過網(wǎng)絡(luò)
  • Pass 0: (x) -> (x:-:_h0) -> (h0:-:v1) (v1 is reconstruction of the first pass)
  • Pass 1: (v1) -> (v1:-:h1) -> (_h0:-:v2) (v2 is reconstruction of the second pass)
  • Pass 2: (v2) -> (v2:-:h2) -> (_h1:-:v3) (v3 is reconstruction of the third pass)
  • Pass n: (vn) -> (vn:-:hn+1) -> (_hn:-:vn+1)(vn is reconstruction of the nth pass)
  • 如何計(jì)算梯度

    為了訓(xùn)練RBM, 我們必須使賦值到訓(xùn)練集V上的概率乘積最大。假如數(shù)據(jù)集V,它的每一行看做是一個(gè)可視的向量v:

    ?

    ?

    或者等效地最大化訓(xùn)練集概率的對(duì)數(shù)

    ?

    我們也可以定義一個(gè)目標(biāo)函數(shù)并嘗試最小化它。為了實(shí)現(xiàn)這個(gè)想法,我們需要這個(gè)函數(shù)的各個(gè)參數(shù)的偏導(dǎo)數(shù)。從上面的表達(dá)式我們知道,他們都是由權(quán)重和偏差間接組成的函數(shù),所以最小化目標(biāo)函數(shù)就是優(yōu)化權(quán)重。因此,我們可以使用隨機(jī)梯度下降(SGD)去找到最優(yōu)的權(quán)重進(jìn)而使目標(biāo)函數(shù)取得最小值。在推導(dǎo)的時(shí)候,有兩個(gè)名詞,正梯度和負(fù)梯度。這兩個(gè)狀態(tài)反映了他們對(duì)模型概率密度的影響。正梯度取決于觀測(cè)值(X),負(fù)梯度只取決于模型。

    正的階段增加訓(xùn)練數(shù)據(jù)的可能性;
    負(fù)的階段減少由模型生成的樣本的概率。

    負(fù)的階段很難計(jì)算,所以我們用一個(gè)對(duì)比散度(Contrastive Divergence (CD))去近似它。它是按照這樣的方式去設(shè)計(jì)的:梯度估計(jì)的方向至少有一些準(zhǔn)確。實(shí)際應(yīng)用中,更高準(zhǔn)確度的方法如CD-k 或者PCD用來訓(xùn)練RBMs。 計(jì)算對(duì)比散度的過程中,我們要用吉布斯采樣(Gibbs sampling)對(duì)模型的分布進(jìn)行采樣。

    對(duì)比散度實(shí)際是一個(gè)用來計(jì)算和調(diào)整權(quán)重矩陣的一個(gè)矩陣。 改變權(quán)重W漸漸地變成了權(quán)重值的訓(xùn)練。然后在每一步(epoch), W通過下面的公式被更新為一個(gè)新的值w’。
    W ′ = W + α ? C D W' = W + \alpha * CDW′=W+α?CD
    α \alphaα?是很小的步長(zhǎng),也就是大家所熟悉的學(xué)習(xí)率(Learning rate)

    如何計(jì)算相對(duì)散度?

    下面展示了單步相對(duì)散度的計(jì)算(CD-1)步驟:

    1.從訓(xùn)練集X中取訓(xùn)練樣本,計(jì)算隱藏層的每個(gè)單元的概率并從這個(gè)概率分布中采樣得到一個(gè)隱藏層激活向量h0;
    _ h 0 = s i g m o i d ( X ? W + h b ) \_h0 = sigmoid(X \otimes W + hb)_h0=sigmoid(X?W+hb)
    h 0 = s a m p l e P r o b ( _ h 0 ) h0 = sampleProb(\_h0)h0=sampleProb(_h0)

    2.計(jì)算X和h0的外積,這就是正梯度
    w _ p o s _ g r a d = X ? h 0 w\_pos\_grad = X \otimes h0w_pos_grad=X?h0(Reconstruction in the first pass)
    3.從h重構(gòu)v1, 接著對(duì)可視層單元采樣,然后從這些采樣得到的樣本中重采樣得到隱藏層激活向量h1.這就是吉布斯采樣。
    _ v 1 = s i g m o i d ( h 0 ? t r a n s p o s e ( W ) + v b ) \_v1=sigmoid(h0?transpose(W)+vb)_v1=sigmoid(h0?transpose(W)+vb)
    v 1 = s a m p l e p r o b ( _ v 1 ) ? ( S a m p l e v g i v e n h ) v1=sampleprob(\_v1) \ (Sample v given h)v1=sampleprob(_v1)?(Samplevgivenh)
    h 1 = s i g m o i d ( v 1 ? W + h b ) h1=sigmoid(v1?W+hb)h1=sigmoid(v1?W+hb)
    4.計(jì)算v1和h1的外積,這就是負(fù)梯度。
    w _ n e g _ g r a d = v 1 ? h 1 ? ( R e c o n s t r u c t i o n 1 ) w\_neg\_grad=v1?h1 \ (Reconstruction 1)w_neg_grad=v1?h1?(Reconstruction1)
    5. 對(duì)比散度等于正梯度減去負(fù)梯度,對(duì)比散度矩陣的大小為784x500.
    C D = ( w _ p o s _ g r a d ? w _ n e g _ g r a d ) / d a t a p o i n t s CD = (w\_pos\_grad - w\_neg\_grad) / datapointsCD=(w_pos_grad?w_neg_grad)/datapoints

  • 更新權(quán)重為W ′ = W + α ? C D W' = W + \alpha*CDW′=W+α?CD
  • 最后可視層節(jié)點(diǎn)會(huì)保存采樣的值。
  • 什么是采樣(sampleProb)?

    在前向算法中,我們隨機(jī)地設(shè)定每個(gè)hi的值為1,伴隨著概率s i g m o i d ( v ? W + h b ) sigmoid(v \otimes W + hb)sigmoid(v?W+hb);
    在重構(gòu)過程中,我們隨機(jī)地設(shè)定每一個(gè)vi的值為1,伴隨著概率s i g m o i d ( h ? t r a n s p o s e ( W ) + v b ) sigmoid(h \otimes transpose(W) + vb)sigmoid(h?transpose(W)+vb)

    alpha = 1.0 w_pos_grad = tf.matmul(tf.transpose(X), h0) w_neg_grad = tf.matmul(tf.transpose(v1), h1) CD = (w_pos_grad - w_neg_grad) / tf.to_float(tf.shape(X)[0]) update_w = W + alpha * CD update_vb = vb + alpha * tf.reduce_mean(X - v1, 0) update_hb = hb + alpha * tf.reduce_mean(h0 - h1, 0)

    什么是目標(biāo)函數(shù)?

    目的:最大限度地提高我們從該分布中獲取數(shù)據(jù)的可能性
    計(jì)算誤差: 每一步(epoch), 我們計(jì)算從第1步到第n步的平方誤差的和,這顯示了數(shù)據(jù)和重構(gòu)數(shù)據(jù)的誤差。

    err = tf.reduce_mean(tf.square(X - v1)) # tf.reduce_mean computes the mean of elements across dimensions of a tensor.

    創(chuàng)建一個(gè)回話并初始化向量:

    cur_w = np.zeros([784, 500], np.float32) cur_vb = np.zeros([784], np.float32) cur_hb = np.zeros([500], np.float32) prv_w = np.zeros([784, 500], np.float32) prv_vb = np.zeros([784], np.float32) prv_hb = np.zeros([500], np.float32) sess = tf.Session() init = tf.global_variables_initializer() sess.run(init)

    查看第一次運(yùn)行的誤差:

    sess.run(err, feed_dict={X: trX, W: prv_w, vb: prv_vb, hb: prv_hb}) # 0.48134533

    整個(gè)算法的運(yùn)算流程:

    對(duì)于每一個(gè)epoch:對(duì)于每一batch:計(jì)算對(duì)比散度:對(duì)batch中的每一個(gè)數(shù)據(jù)點(diǎn):w_pos_grad = 0, w_neg_grad= 0 (matrices)數(shù)據(jù)向前傳播,計(jì)算v(重構(gòu))和h 更新w_neg_grad = w_neg_grad + v1 ? h1對(duì)比散度=pos_grad和neg_grad的平均值除以輸入數(shù)據(jù)個(gè)數(shù)更新權(quán)重和偏差 W' = W + alpha * CD計(jì)算誤差重復(fù)下一epoch直到誤差足夠小或者在多個(gè)epoch下不再改變 #Parameters epochs = 5 batchsize = 100 weights = [] errors = []for epoch in range(epochs):for start, end in zip( range(0, len(trX), batchsize), range(batchsize, len(trX), batchsize)):batch = trX[start:end]cur_w = sess.run(update_w, feed_dict={ X: batch, W: prv_w, vb: prv_vb, hb: prv_hb})cur_vb = sess.run(update_vb, feed_dict={ X: batch, W: prv_w, vb: prv_vb, hb: prv_hb})cur_hb = sess.run(update_hb, feed_dict={ X: batch, W: prv_w, vb: prv_vb, hb: prv_hb})prv_w = cur_wprv_vb = cur_vbprv_hb = cur_hbif start % 10000 == 0:errors.append(sess.run(err, feed_dict={X: trX, W: cur_w, vb: cur_vb, hb: cur_hb}))weights.append(cur_w)print('Epoch: %d' % epoch,'reconstruction error: %f' % errors[-1]) plt.plot(errors) plt.xlabel("Batch Number") plt.ylabel("Error") plt.show()


    最后的權(quán)重:

    uw = weights[-1].T print(uw) # a weight matrix of shape (500,784)

    我們能夠獲得每一個(gè)隱藏的單元并可視化隱藏層和輸入之間的連接。使用tile_raster_images可以幫助我們從權(quán)重或者樣本中生成容易理解的圖片。它把784行轉(zhuǎn)為一個(gè)數(shù)組(比如25x20),圖片被重塑并像地板一樣鋪開。

    tile_raster_images(X=cur_w.T, img_shape=(28, 28), tile_shape=(25, 20), tile_spacing=(1, 1)) import matplotlib.pyplot as plt from PIL import Image %matplotlib inline image = Image.fromarray(tile_raster_images(X=cur_w.T, img_shape=(28, 28) ,tile_shape=(25, 20), tile_spacing=(1, 1))) ### Plot image plt.rcParams['figure.figsize'] = (18.0, 18.0) imgplot = plt.imshow(image) imgplot.set_cmap('gray')


    每一張圖片表示了隱藏層和可視層單元之間連接的一個(gè)向量。

    下面觀察其中一個(gè)已經(jīng)訓(xùn)練好的隱藏層單元的權(quán)重,灰色代表權(quán)重為0,越白的地方權(quán)重越大,接近1.相反得, 越黑的地方,權(quán)重越負(fù)。 權(quán)重為正的像素使隱藏層單元激活的概率,負(fù)的像素會(huì)減少隱藏層單元被激活的概率。 所以我們可以知道特定的小塊(隱藏單元) 可以提取特征如果給它輸入。

    我們?cè)倏纯粗貥?gòu)得到一張圖片
    1)首先畫出一張?jiān)嫉膱D片

    sample_case = trX[1:2] img = Image.fromarray(tile_raster_images(X=sample_case, img_shape=(28, 28),tile_shape=(1, 1), tile_spacing=(1, 1))) plt.rcParams['figure.figsize'] = (2.0, 2.0) imgplot = plt.imshow(img) imgplot.set_cmap('gray') #you can experiment different colormaps (Greys,winter,autumn)


    2) 把原始圖像向下一層傳播,并反向重構(gòu)

    hh0 = tf.nn.sigmoid(tf.matmul(X, W) + hb) vv1 = tf.nn.sigmoid(tf.matmul(hh0, tf.transpose(W)) + vb) feed = sess.run(hh0, feed_dict={ X: sample_case, W: prv_w, hb: prv_hb}) rec = sess.run(vv1, feed_dict={ hh0: feed, W: prv_w, vb: prv_vb})

    3)畫出重構(gòu)的圖片

    img = Image.fromarray(tile_raster_images(X=rec, img_shape=(28, 28),tile_shape=(1, 1), tile_spacing=(1, 1))) plt.rcParams['figure.figsize'] = (2.0, 2.0) imgplot = plt.imshow(img) imgplot.set_cmap('gray')

    參考:
    https://en.wikipedia.org/wiki/Restricted_Boltzmann_machine
    http://deeplearning.net/tutorial/rbm.html
    http://deeplearning4j.org/restrictedboltzmannmachine.html
    http://imonad.com/rbm/restricted-boltzmann-machine/

    總結(jié)

    以上是生活随笔為你收集整理的受限玻尔兹曼机(RBM)与python在Tensorflow的实现的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。