Advertisement
Guest User

rbm_gicc

a guest
Dec 16th, 2019
111
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 12.11 KB | None | 0 0
  1. import numpy
  2. import numpy as np
  3. #import matplotlib.pylab as plt
  4. #import random
  5. #from scipy.linalg import norm
  6. #import PIL.Image
  7. from sklearn.datasets import load_digits
  8.  
  9. def sigmoid(x):
  10.     return 1. / (1 + numpy.exp(-x))
  11.  
  12. def dsigmoid(x):
  13.     return x * (1. - x)
  14.  
  15. class RBM_CD(object):
  16.     def __init__(self, input=None, n_visible=2, n_hidden=3, \
  17.         W=None, hbias=None, vbias=None, rng=None):
  18.  
  19.         self.n_visible = n_visible  # num of units in visible (input) layer
  20.         self.n_hidden = n_hidden    # num of units in hidden layer
  21.  
  22.         if rng is None:
  23.             rng = numpy.random.RandomState(1234)
  24.  
  25.         if W is None:
  26.             a = 1. / n_visible
  27.             initial_W = numpy.array(rng.uniform(  # initialize W uniformly(随机生成实数在-a-a之间)
  28.                 low=-a,
  29.                 high=a,
  30.                 size=(n_visible, n_hidden)))
  31.             W = initial_W
  32.  
  33.         if hbias is None:
  34.             hbias = numpy.zeros(n_hidden)  # initialize h bias 0
  35.  
  36.         if vbias is None:
  37.             vbias = numpy.zeros(n_visible)  # initialize v bias 0
  38.         self.rng = rng
  39.         self.input = input
  40.         self.W = W
  41.         self.hbias = hbias
  42.         self.vbias = vbias
  43.     def contrastive_divergence(self, lr=0.1, k=1, input=None):
  44.         if input is not None:
  45.             self.input = input
  46.         ph_mean, ph_sample = self.sample_h_given_v(self.input)
  47.         chain_start = ph_sample
  48.         #实现一步吉布斯采样通过给隐层采样
  49.         for step in range(k):
  50.             if step == 0:
  51.                 nv_means, nv_samples,\
  52.                 nh_means, nh_samples = self.gibbs_hvh(chain_start)
  53.             else:
  54.                 nv_means, nv_samples,\
  55.                 nh_means, nh_samples = self.gibbs_hvh(nh_samples)
  56.  
  57.         # chain_end = nv_samples
  58.         num_examples = self.input.shape[0]
  59.         self.W += lr * (numpy.dot(self.input.T, ph_mean)
  60.                         - numpy.dot(nv_samples.T, nh_means))/num_examples
  61.         self.vbias += lr * numpy.mean(self.input - nv_samples, axis=0)/num_examples
  62.         self.hbias += lr * numpy.mean(ph_mean - nh_means, axis=0)/num_examples
  63.         # cost = self.get_reconstruction_cross_entropy()
  64.         # return cost
  65.     # 通过给出显层单元推断出隐层单元的
  66.     #计算隐层单元的激活率通过给出显层,得到一个采样通过给他们的
  67.     def sample_h_given_v(self, v0_sample):
  68.         h1_mean = self.propup(v0_sample)
  69.         h1_sample = self.rng.binomial(size=h1_mean.shape,   # discrete: binomial
  70.                                        n=1,
  71.                                        p=h1_mean)
  72.  
  73.         return [h1_mean, h1_sample]
  74.     #一一步吉布斯采样通过从隐层率开始
  75.     def sample_v_given_h(self, h0_sample):
  76.         v1_mean = self.propdown(h0_sample)
  77.         v1_sample = self.rng.binomial(size=v1_mean.shape,   # discrete: binomial
  78.                                             n=1,
  79.                                             p=v1_mean)
  80.         return [v1_mean, v1_sample]
  81.     def propup(self, v):
  82.         pre_sigmoid_activation = numpy.dot(v, self.W) + self.hbias
  83.         return sigmoid(pre_sigmoid_activation)
  84.     def propdown(self, h):
  85.         pre_sigmoid_activation = numpy.dot(h, self.W.T) + self.vbias
  86.         return sigmoid(pre_sigmoid_activation)
  87.     #转换函数主要功能是通过给定的隐层采样来执行cd更新
  88.     def gibbs_hvh(self, h0_sample):
  89.         v1_mean, v1_sample = self.sample_v_given_h(h0_sample)
  90.         h1_mean, h1_sample = self.sample_h_given_v(v1_sample)
  91.         return [v1_mean, v1_sample,h1_mean, h1_sample]
  92.     #计算重构误差
  93.     def reconstruct_error(self, v):
  94.         h = sigmoid(numpy.dot(v, self.W) + self.hbias)
  95.         reconstructed_v = sigmoid(numpy.dot(h, self.W.T) + self.vbias)
  96.         error = numpy.mean(numpy.sum((1-v)*reconstructed_v+v*(1-reconstructed_v),axis=1))
  97.         return error
  98.  
  99.     def reconstruct_error_sample(self, v):
  100.         h = self.sample_h_given_v(v)[1]
  101.         reconstructed_v = self.sample_v_given_h(h)[1]
  102.         error = numpy.mean(numpy.sum((v-reconstructed_v)**2,axis=1))
  103.         return error
  104.  
  105.  
  106. class RBM_gicc(object):
  107.     def __init__(self, input=None, gamma=1/2, n_visible=2, n_hidden=3, \
  108.         W=None, hbias=None, vbias=None, rng=None):
  109.  
  110.         self.n_visible = n_visible  # num of units in visible (input) layer
  111.         self.n_hidden = n_hidden    # num of units in hidden layer
  112.         self.gamma = gamma
  113.  
  114.         if rng is None:
  115.             rng = numpy.random.RandomState(1234)
  116.  
  117.         if W is None:
  118.             a = 1. / n_visible
  119.             initial_W = numpy.array(rng.uniform(  # initialize W uniformly(随机生成实数在-a-a之间)
  120.                 low=-a,
  121.                 high=a,
  122.                 size=(n_hidden, n_visible)))
  123.             W = initial_W
  124.  
  125.         if hbias is None:
  126.             hbias = numpy.zeros(n_hidden)  # initialize h bias 0
  127.  
  128.         if vbias is None:
  129.             vbias = numpy.zeros(n_visible)  # initialize v bias 0
  130.         self.rng = rng
  131.         self.input = input
  132.         self.W = W
  133.         self.hbias = hbias
  134.         self.vbias = vbias
  135.    
  136.     def gicc(self, lr=0.1, iteration=5, input=None):
  137.         if input is not None:
  138.             self.input = input
  139.         h_sample = self.sample_h_given_v(self.input)[1]
  140.         print(sum(h_sample))
  141.         W_old = self.W
  142.         n = self.input.shape[0]
  143.         for j in range(len(self.vbias)):
  144.             print('j',j,'\n')
  145.  
  146.             vj = self.input[:,j]
  147.             print("vj:",sum(vj),"\n")
  148.             p_old = sigmoid(np.dot(h_sample, self.W[:,j].reshape(len(self.W[:,j]),1))+self.vbias[j]).T[0]
  149.             p_old[p_old>0.99] = 0.99
  150.             p_old[p_old < 0.01] = 0.01
  151.             coef = 1/(vj*p_old+(1-vj)*(1-p_old))**self.gamma
  152.             print(p_old)
  153.             print(vj)
  154.             for step in range(iteration):
  155. #                print('step',step,'\n')
  156.                 p = sigmoid(np.dot(h_sample, self.W[:,j].reshape(len(self.W[:,j]),1))+self.vbias[j]).T[0]
  157.                 p[p>0.99] = 0.99
  158.                 p[p<0.01] = 0.01
  159. #                if step==3:
  160. #                    print(np.dot(h_sample, self.W[:,j].reshape(len(self.W[:,j]),1))+self.vbias[j])
  161. #                    print(self.W[:,j],'\n')
  162. #                    print(self.vbias[j],'\n')
  163. #                    print('p',p,'\n')
  164. #                print(self.W[:,j],'\n')
  165.                 dw = 0
  166.                 ddw = 0
  167.                 dv = 0
  168.                 ddv = 0
  169.                 for item in range(n):
  170.                     if p[item]==0 or p[item]==1:
  171.                         print("AAAAAAAAA")
  172.                         break
  173.                     dw += coef[item]*self.dfun(h_sample[item,:],vj[item],p[item])/n
  174. #                    print('item',item,'\n')
  175. #                    print(coef)
  176. #                    print(coef[item],'\n')
  177. #                    print(h_sample[item,:],'\n')
  178. #                    print(vj[item],'\n')
  179. #                    print(p[item],'\n')
  180.                     ddw += coef[item]*self.ddfun(h_sample[item,:],vj[item],p[item])/n
  181. #                    print('delta_ddw',ddw,'\n')
  182.                     dv += coef[item]*self.dfun(np.array([1]),vj[item],p[item])[0][0]/n
  183.                     ddv += coef[item]*self.ddfun(np.array([1]),vj[item],p[item])[0][0]/n
  184. #                    print('dw:',dw,'\n')
  185. #                    print('ddw:',ddw,'\n')
  186. #                    print('dv:',dv,'\n')
  187. #                    print('ddv:',ddv,'\n')
  188. #                print('dw:',dw,'\n')
  189.                 #print('ddw:',np.matrix(ddw),'\n')
  190.  
  191.                 if not np.all(dw==0):
  192.                     if  np.linalg.det(ddw) == 0:
  193.                         print(coef)
  194.                         print(p_old)
  195.                     self.W[:,j] -= np.ravel(np.dot(np.matrix(ddw).I,dw))
  196.                 if not np.all(dv==0):
  197.                     self.vbias[j] -= dv/ddv
  198.  
  199.         for i in range(len(self.hbias)):
  200.             hi = h_sample[:,i]
  201.             ph_old = sigmoid(np.dot(self.input,W_old[i,:].reshape(len(W_old[i,:]),1))+self.hbias[i]).T[0]
  202.             ph_old[ph_old>0.99] = 0.99
  203.             ph_old[ph_old <0.01] = 0.01
  204.             coef = 1/(hi*ph_old+(1-hi)*(1-ph_old))**self.gamma
  205.             for step in range(iteration):
  206.                 p = sigmoid(np.dot(self.input, self.W[i,:].reshape(len(self.W[i,:]),1))+self.hbias[i]).T[0]
  207.                 p[p>0.99] = 0.99
  208.                 p[p<0.01] = 0.01
  209.                 dh = 0
  210.                 ddh = 0
  211.                 for item in range(n):
  212.                     if p[item]==0 or p[item]==1: break
  213.                     dh += coef[item]*self.dfun(np.array([1]),hi[item],p[item])[0][0]/n
  214.                     ddh += coef[item]*self.ddfun(np.array([1]),hi[item],p[item])[0][0]/n
  215.  
  216.                 if not np.all(dh==0):
  217.                     self.hbias[i] -= dh/ddh
  218.                    
  219.  
  220.            
  221.    
  222.     def fun(self, v, p):
  223.         f = v*p**self.gamma + (1-v)*(1-p)**self.gamma
  224.         return f
  225.     def dfun(self, x, v, p):
  226.         r = self.gamma
  227.         df = x.reshape(len(x),1)*(v*r*(1-p)*p**r-(1-v)*r*p*(1-p)**r)
  228.         return df
  229.     def ddfun(self, x, v, p):
  230.         r = self.gamma
  231.         coef = r*p*(1-p)*(v*r*p**(r-1)-(r+1)*v*p**r-(1-v)*(1-p)**r+r*(1-v)*p*(1-p)**(r-1))
  232.         x = x.reshape(len(x),1)
  233.         ddf = np.dot(x,x.T)*coef
  234.         return ddf
  235.  
  236.        
  237.     def sample_h_given_v(self, v0_sample):
  238.         h1_mean = self.propup(v0_sample)
  239.         h1_sample = self.rng.binomial(size=h1_mean.shape,   # discrete: binomial
  240.                                        n=1,
  241.                                        p=h1_mean)
  242.  
  243.         return [h1_mean, h1_sample]
  244.     def sample_v_given_h(self, h0_sample):
  245.         v1_mean = self.propdown(h0_sample)
  246.         v1_sample = self.rng.binomial(size=v1_mean.shape,   # discrete: binomial
  247.                                             n=1,
  248.                                             p=v1_mean)
  249.         return [v1_mean, v1_sample]
  250.     def propup(self, v):
  251.         pre_sigmoid_activation = numpy.dot(v, self.W.T) + self.hbias
  252.         return sigmoid(pre_sigmoid_activation)
  253.     def propdown(self, h):
  254.         pre_sigmoid_activation = numpy.dot(h, self.W) + self.vbias
  255.         return sigmoid(pre_sigmoid_activation)
  256.    
  257.     #计算重构误差
  258.     def reconstruct_error(self, v):
  259.         h = sigmoid(numpy.dot(v, self.W.T) + self.hbias)
  260.         reconstructed_v = sigmoid(numpy.dot(h, self.W) + self.vbias)
  261.         error = numpy.mean(numpy.sum((1-v)*reconstructed_v+v*(1-reconstructed_v),axis=1))
  262.         return error
  263.     def reconstruct_error_sample(self, v):
  264.         h = self.sample_h_given_v(v)[1]
  265.         reconstructed_v = self.sample_v_given_h(h)[1]
  266.         error = numpy.mean(numpy.sum((v-reconstructed_v)**2,axis=1))
  267.         return error
  268.  
  269.  
  270. def test_rbm(learning_rate=0.1, training_epochs=50):
  271.     ''' data = numpy.array([[1,1,1,0,0,0],
  272.                       [1,0,1,0,0,0],
  273.                        [1,1,1,0,0,0],
  274.                        [0,0,1,1,1,0],
  275.                       [0,0,1,1,0,0],
  276.                        [0,0,1,1,1,0]])
  277.    '''
  278.     #data = readData('data.txt')
  279.     digits = load_digits()
  280.     data = np.array(digits.data)
  281.     data[data>0] = 1
  282.     rng = numpy.random.RandomState(123)
  283. #    data = numpy.array([[1,1,1,0,0,0],
  284. #                       [1,0,1,0,0,0],
  285. #                        [1,1,1,0,0,0],
  286. #                        [0,0,1,1,1,0],
  287. #                       [0,0,1,1,0,0],
  288. #                        [0,0,1,1,1,0]])
  289.     # construct RBM
  290. #    rbm_CD = RBM_CD(input=data, n_visible=6, n_hidden=2, rng=rng)
  291. #    rbm_gicc = RBM_gicc(input=data, n_visible=6, n_hidden=2, rng=rng)
  292.     rbm_CD = RBM_CD(input=data, n_visible=64, n_hidden=5, rng=rng)
  293.     rbm_gicc = RBM_gicc(input=data, n_visible=64, n_hidden=5, rng=rng)
  294.     # train
  295.     for epoch in range(training_epochs):
  296.         #rbm_CD.contrastive_divergence(lr=learning_rate, k=1)
  297.         #cost_CD = rbm_CD.reconstruct_error_sample(data)
  298.         rbm_gicc.gicc(lr=learning_rate,iteration=10)
  299.         cost_gicc = rbm_gicc.reconstruct_error_sample(data)
  300.         print('Training epoch %d, cost of gicc is %f.' % (epoch+1, cost_gicc))
  301.  
  302.  
  303.  
  304. if __name__ == "__main__":
  305.     test_rbm()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement