这个是我正在写的一篇论文的部分代码,用了一个三元因子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');