DBN代码注释.docx
- 文档编号:22779579
- 上传时间:2023-04-27
- 格式:DOCX
- 页数:24
- 大小:23.71KB
DBN代码注释.docx
《DBN代码注释.docx》由会员分享,可在线阅读,更多相关《DBN代码注释.docx(24页珍藏版)》请在冰豆网上搜索。
DBN代码注释
importjava.util.Random;
publicclassDBN{
publicintN;
publicintn_ins;
publicint[]hidden_layer_sizes;
publicintn_outs;
publicintn_layers;
publicHiddenLayer[]sigmoid_layers;
publicRBM[]rbm_layers;
publicLogisticRegressionlog_layer;
publicRandomrng;
publicstaticdoublesigmoid(doublex){
return1.0/(1.0+Math.pow(Math.E,-x));
}
//DBN的构造函数N为样本的个数,n-ins为特征个数,hidden_layer_sizes为隐藏层的结构,n-outs为输出维数,n-layers为隐藏层个数,rng为随机数实例
publicDBN(intN,intn_ins,int[]hidden_layer_sizes,intn_outs,intn_layers,Randomrng){
intinput_size;
this.N=N;//赋值样本数目
this.n_ins=n_ins;//赋值特征个数
this.hidden_layer_sizes=hidden_layer_sizes;//赋值隐藏层结构
this.n_outs=n_outs;//赋值输出维数
this.n_layers=n_layers;//赋值隐藏层数目
this.sigmoid_layers=newHiddenLayer[n_layers];//声明两个隐藏层
this.rbm_layers=newRBM[n_layers];//声明两个RBM对应每个隐藏层
if(rng==null)this.rng=newRandom(1234);//获取一个随机数值
elsethis.rng=rng;
//constructmulti-layer初始化每个隐藏层
for(inti=0;i if(i==0){ input_size=this.n_ins;//第一层隐藏层的输入为样本的特征的个数 }else{ input_size=this.hidden_layer_sizes[i-1];//后面的隐藏层的输入为上一层隐藏层的输出,也就是上一层的隐藏层节点的个数。 } //sigmoid层是用来计算的,rbm是用来调整w,b,c的 //constructsigmoid_layer初始化每个隐藏层,初始化做的事情就是给W和b赋随机值 this.sigmoid_layers[i]=newHiddenLayer(this.N,input_size,this.hidden_layer_sizes[i],null,null,rng); //constructrbm_layer初始化玻尔兹曼机,其实也就是初始化,W,b,c其中,w,b用的是hiddenlayer的 this.rbm_layers[i]=newRBM(this.N,input_size,this.hidden_layer_sizes[i],this.sigmoid_layers[i].W,this.sigmoid_layers[i].b,null,rng); } //在完成每一层的构建之后,构建一个输出的逻辑回归层 //layerforoutputusingLogisticRegression,参数为样本个数N,输入为网络结构最后一层的输出数,输出为DBM网络设置的输出维数 this.log_layer=newLogisticRegression(this.N,this.hidden_layer_sizes[this.n_layers-1],this.n_outs); } //对DBN网络进行一个预训练,目的是为每一层先构造更好的W和b,先使得网络更好的拟合样本的分布,类似于先把点放在最后值的附近 publicvoidpretrain(int[][]train_X,doublelr,intk,intepochs){ //输入训练样本,学习率lr,CD-k=1,epochs=1000 int[]layer_input=null; intprev_layer_input_size; int[]prev_layer_input; for(inti=0;i for(intepoch=0;epoch for(intn=0;n //layerinput for(intl=0;l<=i;l++){//从前面训练好的每一层开始迭代,假设有3层,i=2,0,1,2迭代3次 if(l==0){//l=0的时候只是获取数据的特征 layer_input=newint[n_ins];//第一层的输入维度为样本的特征数 for(intj=0;j //也就是第一层处理的数据是样本的原始的特征。 }else{//如果不是第一层的话,本层处理的数据是上一层的输出 if(l==1)prev_layer_input_size=n_ins;//l=1的时候输入的维度为原始数据的特征数 elseprev_layer_input_size=hidden_layer_sizes[l-2]; prev_layer_input=newint[prev_layer_input_size];//声明这一层的输入数据维度 for(intj=0;j //这一层的输入数据是上一层的输出,l=0的时候pre_layer_input为traningdata layer_input=newint[hidden_layer_sizes[l-1]];//layer_input其实就是这一层的输出 //给定上一层的输出数据作为本层的输入数据,计算出本层的输出,就只是单纯的利用rb,修改后的w,b来作出计算 sigmoid_layers[l-1].sample_h_given_v(prev_layer_input,layer_input); } } //在rbm层上,根据输入layer_input和学习率lr,对 wbc进行调整,同时每一个数据都要进行调整 rbm_layers[i].contrastive_divergence(layer_input,lr,k); }//endforeverytrainingdata }//endforepochs }//endforlayer-wise } //使用finetune进行微调,这里是有监督学习 publicvoidfinetune(int[][]train_X,int[][]train_Y,doublelr,intepochs){ int[]layer_input=newint[0]; //intprev_layer_input_size; int[]prev_layer_input=null; for(intepoch=0;epoch for(intn=0;n //layerinput for(inti=0;i if(i==0){ prev_layer_input=newint[n_ins];//如果是第一层的话,输入就是数据样本的维度 for(intj=0;j }else{ prev_layer_input=newint[hidden_layer_sizes[i-1]]; for(intj=0;j } layer_input=newint[hidden_layer_sizes[i]]; //第i层的sigmoid层计算出本层的输出,作为下一层的输入layer_input sigmoid_layers[i].sample_h_given_v(prev_layer_input,layer_input); }//endforiterlayer //一个样本从头扫到尾,遍历所有的层最后的输出保存在layer_input当中 log_layer.train(layer_input,train_Y[n],lr);//log_layer是逻辑回归的对象,用layer_input和label来做逻辑回归 }//endforiterdata //lr*=0.95; }//endforepochs } publicvoidpredict(int[]x,double[]y){//这里一次只处理一个样本 double[]layer_input=newdouble[0]; //intprev_layer_input_size; double[]prev_layer_input=newdouble[n_ins]; for(intj=0;j doublelinear_output; //layeractivation迭代每一层 for(inti=0;i layer_input=newdouble[sigmoid_layers[i].n_out];//后面层的输入是该层的输出 for(intk=0;k linear_output=0.0; for(intj=0;j linear_output+=sigmoid_layers[i].W[k][j]*prev_layer_input[j]; } linear_output+=sigmoid_layers[i].b[k]; layer_input[k]=sigmoid(linear_output); } if(i prev_layer_input=newdouble[sigmoid_layers[i].n_out]; for(intj=0;j } }//endforiterlayer for(inti=0;i y[i]=0; for(intj=0;j y[i]+=log_layer.W[i][j]*layer_input[j]; } y[i]+=log_layer.b[i]; } log_layer.softmax(y);//然后softmax获得一个归一话的结果 } privatestaticvoidtest_dbn(){ Randomrng=newRandom(123); doublepretrain_lr=0.1;//pre-training的学习率初始的时候设置为0.1 intpretraining_epochs=1000; intk=1; doublefinetune_lr=0.1;//fine-tune的学习率为0。 1 intfinetune_epochs=500;//fine-turne的迭代次数 inttrain_N=6;//训练数据集的个数,实际使用的时候最好不要用硬编码 inttest_N=4;//测试数据集的个数 intn_ins=6;//特征的维数 intn_outs=2;//输出的维数 int[]hidden_layer_sizes={10,9,8,7,6};//隐藏层的节点个数 intn_layers=hidden_layer_sizes.length;//设置了两个隐藏层 //trainingdata int[][]train_X={ {1,1,1,0,0,0}, {1,0,1,0,0,0}, {1,1,1,0,0,0}, {0,0,1,1,1,0}, {0,0,1,1,0,0}, {0,0,1,1,1,0} }; int[][]train_Y={//用这样的表示来做二分类,如果是多维的就是多分类,我他妈真是太聪明了 {1,0}, {1,0}, {1,0}, {0,1}, {0,1}, {0,1}, }; //constructDBN初始化DBN网络 DBNdbn=newDBN(train_N,n_ins,hidden_layer_sizes,n_outs,n_layers,rng); //pretrain初始化构造好网络进入pre-traning阶段,就是一层一层训练网络,k=1是CD抽样只做一次 dbn.pretrain(train_X,pretrain_lr,k,pretraining_epochs); //finetune在pre-training构造整个网络之后,用finetune进行一次微调 dbn.finetune(train_X,train_Y,finetune_lr,finetune_epochs); //testdata int[][]test_X={ {1,1,0,0,0,0}, {1,1,1,1,0,0}, {0,0,0,1,1,0}, {0,0,1,1,1,0}, }; double[][]test_Y=newdouble[test_N][n_outs]; //test for(inti=0;i dbn.predict(test_X[i],test_Y[i]);//对每个输入数据test_x[i]和对应的label进行预测,值保存在test_Y数组中 for(intj=0;j System.out.print(test_Y[i][j]+""); } System.out.println(); } } publicstaticvoidmain(String[]args){ test_dbn(); } } importjava.util.Random; publicclassRBM{ publicintN; publicintn_visible; publicintn_hidden; publicdouble[][]W; publicdouble[]hbias; publicdouble[]vbias; publicRandomrng; publicdoubleuniform(doublemin,doublemax){ returnrng.nextDouble()*(max-min)+min; } publicintbinomial(intn,doublep){ if(p<0||p>1)return0; intc=0; doubler; for(inti=0;i r=rng.nextDouble();//取一个随机数 if(r } returnc; } publicstaticdoublesigmoid(doublex){ return1.0/(1.0+Math.pow(Math.E,-x)); } //RBM的构造函数 publicRBM(intN,intn_visible,intn_hidden, double[][]W,double[]hbias,double[]vbias,Randomrng){ this.N=N;//样本的个数 this.n_visible=n_visible;//可视节点的个数,可视节点的个数就是上一层的输出 this.n_hidden=n_hidden;//隐藏节点的个数,隐藏节点的个数就是这一层的节点个数 if(rng==null)this.rng=newRandom(1234);//获取随机值 elsethis.rng=rng; if(W==null){//初始话RBM的W,因为在构建的时候,是把隐藏层的W传过来,所以W不是NULL而是sigmoid_layers[i].W this.W=newdouble[this.n_hidden][this.n_visible]; doublea=1.0/this.n_visible; for(inti=0;i for(intj=0;j this.W[i][j]=uniform(-a,a); } } }else{ this.W=W; } if(hbias==null){//初始化RBM的偏差b,同理在初始化RBM的时候,hbias是由sigmoid_layers输入的 this.hbias=newdouble[this.n_hidden]; for(inti=0;i }else{ this.hbias=hbias; } if(vbias==null){//这里初始化,可视层的偏差,反正都为0就对了 this.vbias=newdouble[this.n_visible]; for(inti=0;i }else{ this.vbias=vbias; } } //执行CD方法对wbc进行梯度下降的调整 publicvoidcontrastive_divergence(int[]input,doublelr,intk){ double[]ph_mean=newdouble[n_hidden];//n-hidden是这一层的节点个数 int[]ph_sample=newint[n_hidden];//保存的是隐藏层的0-1值 double[]nv_means=newdouble[n_visible];//采样中保存的是可视层的wx+b值 int[]nv_samples=newint[n_vis
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- DBN 代码 注释
![提示](https://static.bdocx.com/images/bang_tan.gif)