受限玻尔兹曼机RBM实现——matlab实现

这个是我正在写的一篇论文的部分代码,用了一个三元因子RBM,大家只需要看采样部分和权重与偏置的更新部分就行了

%第一层RBM训练:数据before-数据current-隐单元1

numbatches = length(minibatch);
numdims = size(batchdata,2);
%学习率的设置
%权重的学习率
epsilonvisfac=single(1e-2);  %可见层到因子层的学习率
epsilonhidfac=single(1e-2);  %隐藏层到因子层
epsilonpastfac=single(1e-3);%过去到因子层的学习率
%偏置学习率
epsilonvisbias=single(1e-2);  %可见层偏置学习率0.01
epsilonhidbias=single(1e-2);  %隐含层偏置学习率0.01



%所有权重的的衰减
wdecay = single(0.0002);

mom = single(0.9);       %动量学习率,每五个周期用一次
if restart==1,
    restart=0;
    epoch=1;
    
    %初始化权重
    visfac = single(0.01*randn(numdims,numfac));%可见层到因子层权重
    hidfac = single(0.01*randn(numhid,numfac));%隐藏层到因子层之间的权重
    pastfac= single(0.01*randn(nt*numdims,numfac));%隐藏层到因子层之间的权重
    
    %初始化偏置
    visbiases = zeros(1,numdims,'single');  %可见层偏置1*58
    hidbiases = zeros(1,numhid,'single');   %隐藏层偏置1*600
    
    clear posdataprod pospastprod poshidprod posvishidprod posvisact poshidact
    clear negdataprod negpastprod neghidprod negvishidprod negvisact neghidact
    
    %keep previous updates around for momentum  %为当前状态保存前面的更新信息
    visfacinc = zeros(size(visfac),'single');   %可见层到因子层的信息
    hidfacinc = zeros(size(hidfac),'single');   %隐藏层到因子层的信息
    pastfacinc = zeros(size(pastfac),'single'); %过去层到因子层
    
    visbiasinc = zeros(size(visbiases),'single');   %可见层偏置
    hidbiasinc = zeros(size(hidbiases),'single');   %隐藏层偏置
    
    %动态绘制误差曲线
    x=1:maxepoch;
    h=plot(0,0);
    annotation('arrow',[0.132 0.132],[0.8,1]);
    annotation('arrow',[0.8 1],[0.108,0.108]);
    errorrecord=[];
end


%Main loop
for epoch = epoch:maxepoch,  %1到200 训练周期
    errsum=0; %重构数据与原始数据的误差
    for batch = 1:numbatches,     %对每一批数据都进行处理
        
        %%%%%%%%% START POSITIVE PHASE %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
        
        numcases = length(minibatch{batch});   %每一批数据的大小
        mb = minibatch{batch}; %caches the indices  找到对应批次的内容,里面存的是随机数,前面定义过
        
        past = zeros(numcases,nt*numdims,'single'); %初始化过去层的数据,帧数*15帧总共的感兴趣数据
        
        data = single(batchdata(mb,:));%把随机数对应的那个帧的数据取出来一般来说是100*58维的(每批100帧,每帧58个维度)
        
        for hh=nt:-1:1 %100个随机帧的前面15个帧信息的综合,即100*(12*58维)
            past(:,numdims*(nt-hh)+1:numdims*(nt-hh+1)) = batchdata(mb-hh,:) + randn(numcases,numdims);
        end
        
        yvis = data*visfac;
        ypast=past*pastfac;
        ypastvis=yvis.*ypast;
        poshidprobs = 1./(1 + exp(-ypastvis*hidfac' - repmat(hidbiases,numcases,1)));
        batchposhidprobs{batch}=poshidprobs;
        %Activate the hidden units    激活隐单元
        hidstates = single(poshidprobs > rand(numcases,numhid)); %全是0和1
        
        yhid = hidstates*hidfac;     %找到激活的单元,把权重保留,其他的权重置零
        yhid_ = poshidprobs*hidfac;  %概率乘以隐藏层到因子层的权值
        
        
        %Calculate statistics needed for gradient update
        %Gradients are taken w.r.t neg energy
        %Note that terms that are common to positive and negative stats
        %are left out
        posvisprod = data'*(ypast.*yhid_); %smoothed
        pospastprod = past'*(yvis.*yhid_); %smoothed
        poshidprod = poshidprobs'*(ypast.*yvis); %smoothed
        
        posvisact = sum(data,1);
        poshidact = sum(poshidprobs,1);  %smoothed
        
        %%%%%%%%% END OF POSITIVE PHASE %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
        
        %%%%%%%%% START NEGATIVE PHASE  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
        %10步对比散度算法
        for cdn = 1:cdsteps
            negdata =(ypast.*yhid)*visfac' + repmat(visbiases,numcases,1);    %重构数据
            
            yvis = negdata*visfac;
            ypastvis=yvis.*ypast;
            neghidprobs = 1./(1 + exp(-ypastvis*hidfac'- repmat(hidbiases,numcases,1)));
            
            if cdn == 1
                %Calculate reconstruction error计算重构误差
                err= sum(sum( (data(:,:,1)-negdata).^2 ));
                errsum = err + errsum;
            end
            
            if cdn == cdsteps
                
                yhid_ = neghidprobs*hidfac; %smoothed version
                yvishid_ = yvis.*yhid_;
                
                negvisprod = negdata'*(ypast.*yhid_); %smoothed
                negpastprod = past'*(yvishid_); %smoothed
                neghidprod = neghidprobs'*(ypast.*yvis); %smoothed
                
                %negvishidprod = data'*neghidprobs;
                negvisact = sum(negdata,1);
                neghidact = sum(neghidprobs,1);  %smoothed
                
            else
                %Stochastically sample the hidden units
                hidstates = single(neghidprobs > rand(numcases,numhid));
                yhid = hidstates*hidfac;
            end
        end
        
        
        %%%%%%%%% END NEGATIVE PHASE  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
        if epoch > 5 %use momentum
            momentum=mom;
        else %no momentum
            momentum=0;
        end
        
        %%%%%%%%% UPDATE WEIGHTS AND BIASES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
        
        visfacinc = momentum*visfacinc + ...
            epsilonvisfac*( ( posvisprod - negvisprod)/numcases - wdecay*visfac);
        
        hidfacinc = momentum*hidfacinc + ...
            epsilonhidfac*( (poshidprod - neghidprod)/numcases - wdecay*hidfac);   %前面一个参数应该是学习率,后面那个wdecay应该是权重衰减率
        
        pastfacinc = momentum*pastfacinc + ...
            epsilonpastfac*( (pospastprod - negpastprod)/numcases - wdecay*pastfac);
        
        %两个偏置
        visbiasinc = momentum*visbiasinc + ...
            (epsilonvisbias/numcases)*(posvisact - negvisact);
        hidbiasinc = momentum*hidbiasinc + ...
            (epsilonhidbias/numcases)*(poshidact - neghidact);
        
        
        visfac = visfac + visfacinc;
        pastfac = pastfac + pastfacinc;
        hidfac = hidfac + hidfacinc;
        
        visbiases = visbiases + visbiasinc;
        hidbiases = hidbiases + hidbiasinc;
        
        %%%%%%%%%%%%%%%% END OF UPDATES  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
        
    end
    
    %%%动态绘制误差曲线
    title('第一层误差折线图')
    errorrecord=[errorrecord errsum];
    set(h,'xData',x(1:epoch),'yData',errorrecord(1:epoch))

    fprintf(1, 'epoch %4i error %6.1f  \n', epoch, errsum);
    
    %Checkpoint models
    %最终得到的就是可见层-因子层权重、特征曾-因子层权重、隐藏层-因子层权重、过去-因子层A(或者称为m)的权重、可见层-因子层A的权重
    %过去-因子层B的权重、隐藏层-因子层B的权重、标签-特征的权重;可见层偏置,隐藏层偏置、k步采样、隐藏层单元个数、周期数、训练帧数
    if ~isnan(errsum)
        snapshot_file = [snapshot_path '1.mat'];
        save(snapshot_file, 'pastfac','visfac','hidfac', 'visbiases','hidbiases', ...
            'cdsteps', 'numhid','numfac','epoch', 'nt','n1','batchposhidprobs');
    else
        break;
    end
    
   drawnow; %update any plots你可以理解为把当前需要画的东西都画到屏幕上。一般用于循环内,显示动画效果。看看文档的例子吧http://cn.mathworks.com/help/matlab/ref/drawnow.html
end
%
%         snapshot_file = [snapshot_path '1.mat'];
%         save(snapshot_file, 'pastfac','visfac','hidfac', 'visbiases','hidbiases', ...
%             'cdsteps', 'numhid','numfac','epoch', 'nt','n1');


你可能感兴趣的:(算法,Gibbs采样)