加载中…
个人资料
乘风破浪
乘风破浪
  • 博客等级:
  • 博客积分:0
  • 博客访问:9,783
  • 关注人气:0
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

Boltzmann(玻尔兹曼机)的算法实现

(2016-12-17 15:20:57)
标签:

boltzmann

神经网络

分类: 神经网络
Boltzmann概述:

Hinton Ackley等人以模拟退火思想为基础,对Hopfield模型引入了随机机制,提出了Boltzmann机。

Boltzmann(Boltzmann machines BM)是由加拿大多伦多大学教授Hinton等人于1985年提出的。
Boltzmann机是第一个受统计力学启发的多层学习机,它是一类典型的随机神经网络属于反馈神经网络类型 。其命名来源于Boltzmann在统计热力学中的早期工作和网络本身的动态分布行为 。
它在神经元状态变化中引入了统计概率,网络的平衡状态服从Boltzmann分布,网络运行机制基于模拟退火算法。
Boltzmann机结合多层前馈神经网络和离散Hopfield网络在网络结构、学习算法和动态运行机制方面的优点,是建立在离散Hopfield网基础上的,具有学习能力,能够通过一个模拟退火过程寻求最优解。不过,其训练时间比BP网络要长。
离散Hopfield神经网络+模拟退火+隐单元=Boltzman


给定如下图所示的一个Boltzmann网络参数:


具体的求解过程如下图所示:
为了求得给定温度下的某一状态下各节点的输入Uj(t),使用上面的step2步骤,然后根据求得的Uj(t)求出各个节点下一时刻输出为1的概率P1(1)和输出为0的概率1-P1(1);然后可以得出以下表9.1

然后计算出各个状态转移到下一个状态的概率,分三种情况进行讨论,编程实现时也是根据不同情况采取相应的代码公式加以实现。比如当前状态为S0(000),它可以转移到000-111,这其中如果有只有一位发生变化,比如到001(S1(001)转移到S0(000)也是一样的)统一用下式计算状态转移概率:
http://s11/mw690/003x2huTzy77g5VWufMea&690

如果S0(000)转移到的下一个状态依然是S0(000)也就是说转移到自身了,或者有两个位及以上发生转移则认为概率为0,此时可以采取以下公式进行计算:
http://s14/mw690/003x2huTzy77g5YeTk9ed&690
即可以得出下面的状态转移图如下表9.2所示:


http://s2/mw690/003x2huTzy77g5WTLbP61&690

还需要求出每一个状态的下一个时刻到达其他状态的概率:假设在温度T=1,t=0时刻各个状态的概率都为0.125,则各个状态的下一个时刻的概率可以用以下公式求出:
假设要求出1时刻的状态S2(010)的概率,则可以通过t=0时刻各个状态的概率乘以上图S2(1)状态的列即可获得下一时刻各个状态转移到S2(010)的概率。在给定温度下各个时刻的状态概率:

http://s14/mw690/003x2huTzy77g5XqwtT7d&690
以上都是在温度T=1的时候所求出的数值,随着t的增加每一个温度T下都会得到一个稳定的状态,也就是转移到一个状态后基本不发生变化或上一个时刻和下一个时刻的各个状态的概率小于某一精度范围,比如0.00001就可以认为是收敛的,即达到稳态。又Boltzmann是基于模拟退火算法,即温度会不断的向下降低,因此当降低到下一个温度时之前温度下所达到的稳态会被打破,然后重新开始网络的各个参数。当温度降到一定程度时会找到全局最小点,此时系统又将达到一个稳态并且基本不会再发生变化。本文是以0.01的速度进行下降,精度采取0.00001,当运行到1613次时系统达到稳定状态并收敛于状态S7。如下图所示:


具体的Boltzmann算法实现如下所示:
%本设计是Boltzmann的MATLAB算法实现
16/12/16
clear all;clc;
%参数矩阵,由于Wii=0;所以斜对角线上参数为0;
W =[ 0      0.1  -0.7;  %根据PPT上的参数
         0.1      0.4;
        -0.7  0.4    0];
theta=[-0.9,-0.2,0.3]; %根据PPT上参数;
% W =[ 0      0.2  -0.6;  %老师给的仿真例题参数
         0.2      0.4;
        -0.6  0.4    0];
% theta=[-0.9,0.2,-0.7]; %老师给的仿真例题参数;
%8个状态矩阵
Status=[      0 0 0;
                    0 0 1;
                    0 1 0;
                    0 1 1;
                    1 0 0;
                    1 0 1;
                    1 1 0;
                    1 1 1];
   %定义一个8X3的零矩阵为了存储输入Ui;   
      U = zeros(8,3);
   
    %根据公式求得激活函数U各个节点的值
     for c=1:8     
         U(c,1) = W(1,2)*Status(c,2)+W(1,3)*Status(c,3)-theta(1);
         U(c,2) = W(2,1)*Status(c,1)+W(2,3)*Status(c,3)-theta(2);
         U(c,3) = W(3,1)*Status(c,1)+W(3,2)*Status(c,2)-theta(3);   
     end  
  
     %表1  求得各个状态节点的激活概率放在矩阵EveStaNodeActPro中;
 EveStaNodeActPro =zeros(24,3);  %定义一个EveStaNodeActPro(激活概率)各个状态节点的激活概率
         
 %定义一个整型常量S  用于记录总的时间t;
 S = 1;
 T=1;
 Pbegin = [0.125,0.125,0.125,0.125,0.125,0.125,0.125,0.125];  %定义一面开始0时刻的概率P
 %Pbegin = [0.2,0.1,0.01,0.2,0.3,0.1,0.05,0.04];  %老师要求仿真例题的参数 各状态先验概率
 DiTempStaProDisCon = zeros(2000,8); %DiTempStaProDisCon(不同温度下状态概率分布情况)
 DiTempStaProDisCon(1,1:8) = Pbegin;
 while T >=0.01
         T = T-0.01;
        for c = 1:8
            for r = 1:3
                    for n = 1:3
                        %转换成列
                        EveStaNodeActPro(3*c-3+n,2)= 1/[1+exp(-U(c,n)/T)];
                        EveStaNodeActPro(3*c-3+n,3) = 1-EveStaNodeActPro(3*c-3+n,2);
                        EveStaNodeActPro(3*c-3+n,1) = n;
                    end
            end       
        end
   StatusChange = zeros(8,8);  %表2  定义一个8*8的全零矩阵  用于存储转移后的状态转移图
for c = 1:8
    for N = 1:8
        flag = 0;     %用于标记转移后的状态与前一个状态有多少位不一样;
        Bitflag = 0; %用于记录哪一个位发生转移  用于后面的Vi;
        for r = 1:3
            if  Status(c,r) ~= Status(N,r)
                flag = flag+1;  %作为flag标志位 用于计算出由一个状态转移到另外一种状态有几个位发生
               
                  if flag ==1
                      Bitflag = r;%用于标记第一个发生变化的位
                  end
            end
        end
        
        if flag == 0   %当转移到本身的时候  (V1P1(1)+(1-V1)P1(0)+V2P2(1)+(1-V2)P2(0)+V3P3(1)+(1-V3)P3(0))/3
        
            StatusChange(c,N) = (Status(c,1)*EveStaNodeActPro(3*c-2,2)+(1-Status(c,1))*EveStaNodeActPro(3*c-2,3) + Status(c,2)*EveStaNodeActPro(3*c-1,2)+(1-Status(c,2))*EveStaNodeActPro(3*c-1,3) + Status(c,3)*EveStaNodeActPro(3*c,2)+(1-Status(c,3))*EveStaNodeActPro(3*c,3))/3;
        elseif flag == 1  %当有一位发生变化的时候  ((1-Vj)Pj(1)+VjPj(0))/3   (讲义上面的公式有所调整)
            StatusChange(c,N) = ((1-Status(c,Bitflag))*EveStaNodeActPro(3*c-3+Bitflag,2)+Status(c,Bitflag)*EveStaNodeActPro(3*c-3+Bitflag,3))/3;
        else
            StatusChange(c,N) = 0;  %由于不能异步转移顾有两位及以上不一样时全部为0;
        end
    end
end
%表3  在给定温度下各状态的概率;
 for t=S:2000
        for N = 1:8
            NextTimePro=0;   %作为下一时刻状态为Sj(t+1)的概率
            for r=1:8
               NextTimePro =NextTimePro+ DiTempStaProDisCon(S,r)*StatusChange(r,N);   %假设在t时刻出现Si的概率为Pi(t), 那么在t+1时刻状态为Sj的概率Pj(t+1)可以由所有进入该状态的概率求和得到Pj (t+1)=∑ P i(t)pij
            end
        DiTempStaProDisCon(S+1,N) =NextTimePro;
        end
        S = S + 1;
        %通过DiTempStaProDisCon的后一行的每一个元素分布减去前一行对应的元素
        %如果绝对值小于精度0.00001就可以认为是收敛的  即跳出循环
         if  (abs(DiTempStaProDisCon(S,1)-DiTempStaProDisCon(S-1,1))<0.00001)& (abs(DiTempStaProDisCon(S,2)-DiTempStaProDisCon(S-1,2))<0.00001)& (abs(DiTempStaProDisCon(S,3)-DiTempStaProDisCon(S-1,3))<0.00001)& (abs(DiTempStaProDisCon(S,4)-DiTempStaProDisCon(S-1,4))<0.00001)& (abs(DiTempStaProDisCon(S,5)-DiTempStaProDisCon(S-1,5))<0.00001)& (abs(DiTempStaProDisCon(S,6)-DiTempStaProDisCon(S-1,6))<0.00001)& (abs(DiTempStaProDisCon(S,7)-DiTempStaProDisCon(S-1,7))<0.00001)& (abs(DiTempStaProDisCon(S,8)-DiTempStaProDisCon(S-1,8))<0.00001)
             break;
         end
end
     T
     %输出总的时间S
    DiTempStaProDisCon() %输出不同温度下状态概率的分布情况
end

 




0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有