




已阅读5页,还剩10页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
import java.util.Random;public class DBN public int N;public int n_ins;public int hidden_layer_sizes;public int n_outs;public int n_layers;public HiddenLayer sigmoid_layers;public RBM rbm_layers;public LogisticRegression log_layer;public Random rng;public static double sigmoid(double x) return 1.0 / (1.0 + Math.pow(Math.E, -x);/DBN 的构造函数 N 为样本的个数, n-ins 为特征个数, hidden_layer_sizes 为 隐藏层的结构, n-outs 为输出维数, n-layers 为隐藏层个数, rng 为随机数实例public DBN(int N, int n_ins, int hidden_layer_sizes, int n_outs, int n_layers, Random rng) int input_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 = new HiddenLayern_layers; / 声明两个隐藏层this.rbm_layers = new RBMn_layers; /声明两个RBM对应每个隐藏层if(rng = null)this.rng = new Random(1234); / 获取一个随机数值else this.rng = rng;/ construct multi-layer 初始化每个隐藏层for(int i=0; ithis.n_layers; i+) if(i = 0) input_size = this.n_ins; /第一层隐藏层的输入为样本的特征的个数 else input_size = this.hidden_layer_sizesi-1; / 后面的隐藏层的输入为上一层隐藏层的输出,也就是上一层的隐藏层节点的个数。 / sigmoid 层是用来计算的, rbm 是用来调整 w , b , c 的/ construct sigmoid_layer 初始化每个隐藏层 , 初始化做的事情就是给W和b赋随机值this.sigmoid_layersi = new HiddenLayer(this.N, input_size, this.hidden_layer_sizesi, null, null, rng);/ construct rbm_layer 初始化玻尔兹曼机,其实也就是初始化,W, b , c 其中,w , b 用的是hiddenlayer的this.rbm_layersi = new RBM(this.N, input_size, this.hidden_layer_sizesi, this.sigmoid_layersi.W, this.sigmoid_layersi.b, null, rng);/在完成每一层的构建之后,构建一个输出的逻辑回归层/ layer for output using LogisticRegression, 参数为样本个数N, 输入为网络结构最后一层的输出数, 输出为DBM网络设置的输出维数this.log_layer = new LogisticRegression(this.N, this.hidden_layer_sizesthis.n_layers-1, this.n_outs);/对DBN网络进行一个预训练,目的是为每一层先构造更好的W和b, 先使得网络更好的拟合样本的分布,类似于先把点放在最后值的附近public void pretrain(int train_X, double lr, int k, int epochs) /输入训练样本, 学习率lr , CD-k =1 , epochs=1000int layer_input = null ;int prev_layer_input_size;int prev_layer_input;for(int i=0; in_layers; i+) / layer-wise迭代每一个层 for(int epoch=0; epochepochs; epoch+) / training epochs 每个层都迭代优化epochs次 for(int n=0; nN; n+) / input x1.xN 每一层都遍历每个训练样本 , 这种方式相当于是随机梯度下降/ layer inputfor(int l=0; l=i; l+) /从前面训练好的每一层开始迭代 ,假设有3层,i=2 , 0,1,2 迭代3次if(l = 0) / l=0 的时候只是获取数据的特征layer_input = new intn_ins; /第一层的输入维度为样本的特征数for(int j=0; jn_ins; j+) layer_inputj = train_Xnj; /遍历第i个样本的第j个特征赋值给layer _input/ 也就是第一层处理的数据是样本的原始的特征。 else / 如果不是第一层的话,本层处理的数据是上一层的输出if(l = 1) prev_layer_input_size = n_ins; / l = 1 的时候输入的维度为原始数据的特征数else prev_layer_input_size = hidden_layer_sizesl-2;prev_layer_input = new intprev_layer_input_size; / 声明这一层的输入数据维度for(int j=0; jprev_layer_input_size; j+) prev_layer_inputj = layer_inputj;/这一层的输入数据是上一层的输出,l=0的时候pre_layer_input 为 traning datalayer_input = new inthidden_layer_sizesl-1; / layer_input其实就是这一层的输出/给定上一层的输出数据作为本层的输入数据,计算出本层的输出, 就只是单纯的利用rb,修改后的w ,b来作出计算sigmoid_layersl-1.sample_h_given_v(prev_layer_input, layer_input);/ 在rbm 层上 , 根据输入 layer_input 和学习率lr ,对 w b c 进行调整 , 同时每一个数据都要进行调整rbm_layersi.contrastive_divergence(layer_input, lr, k); / end for every training data/end for epochs/ end for layer-wise/ 使用finetune 进行微调 , 这里是有监督学习public void finetune(int train_X, int train_Y, double lr, int epochs) int layer_input = new int0;/ int prev_layer_input_size;int prev_layer_input = null ;for(int epoch=0; epochepochs; epoch+) /迭代epochs 次for(int n=0; nN; n+) /遍历所有的输入数据样本/ layer inputfor(int i=0; in_layers; i+) if(i = 0) prev_layer_input = new intn_ins; / 如果是第一层的话,输入就是数据样本的维度for(int j=0; jn_ins; j+) prev_layer_inputj = train_Xnj; /获取输入数据 else prev_layer_input = new inthidden_layer_sizesi-1;for(int j=0; jhidden_layer_sizesi-1; j+) prev_layer_inputj = layer_inputj;layer_input = new inthidden_layer_sizesi;/第i层的sigmoid 层计算出本层的输出,作为下一层的输入layer_inputsigmoid_layersi.sample_h_given_v(prev_layer_input, layer_input); / end for iter layer /一个样本从头扫到尾, 遍历所有的层最后的输出保存在layer_input当中log_layer.train(layer_input, train_Yn, lr); /log_layer是逻辑回归的对象, 用layer_input 和label 来做逻辑回归 / end for iter data/ lr *= 0.95;/ end for epochs public void predict(int x, double y) / 这里一次只处理一个样本double layer_input = new double0;/ int prev_layer_input_size;double prev_layer_input = new doublen_ins;for(int j=0; jn_ins; j+) prev_layer_inputj = xj; /最开始的输入是特征xdouble linear_output;/ layer activation 迭代每一层for(int i=0; in_layers; i+) layer_input = new doublesigmoid_layersi.n_out; /后面层的输入是该层的输出for(int k=0; k sigmoid_layersi.n_out; k+) /遍历的是一个n-outn-in的数组linear_output = 0.0; for(int j=0; jsigmoid_layersi.n_in; j+) linear_output += sigmoid_layersi.Wkj * prev_layer_inputj;linear_output += sigmoid_layersi.bk;layer_inputk = sigmoid(linear_output);if(i n_layers-1) / 上层的输出是layer_input , 做为下一层的输入prev_layer_input = new doublesigmoid_layersi.n_out;for(int j=0; jsigmoid_layersi.n_out; j+) prev_layer_inputj = layer_inputj; / end for iter layerfor(int i=0; ilog_layer.n_out; i+) /到最后一层的时候,做一个逻辑回归yi = 0;for(int j=0; jlog_layer.n_in; j+) yi += log_layer.Wij * layer_inputj;yi += log_layer.bi;log_layer.softmax(y); /然后softmax 获得一个归一话的结果private static void test_dbn() Random rng = new Random(123);double pretrain_lr = 0.1; /pre-training 的学习率初始的时候设置为0.1int pretraining_epochs = 1000; int k = 1;double finetune_lr = 0.1; / fine-tune 的学习率为0。1int finetune_epochs = 500; /fine-turne 的迭代次数int train_N = 6; / 训练数据集的个数,实际使用的时候最好不要用硬编码int test_N = 4; / 测试数据集的个数int n_ins = 6; / 特征的维数int n_outs = 2; / 输出的维数int hidden_layer_sizes = 10, 9,8,7,6 ; /隐藏层的节点个数int n_layers = hidden_layer_sizes.length; /设置了两个隐藏层/ training dataint 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,;/ construct DBN 初始化DBN网络 DBN dbn = new DBN(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);/ test dataint 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 = new doubletest_Nn_outs;/ testfor(int i=0; itest_N; i+) dbn.predict(test_Xi, test_Yi); / 对每个输入数据test_xi和对应的label 进行预测 , 值保存在test_Y数组中for(int j=0; jn_outs; j+) System.out.print(test_Yij + );System.out.println();public static void main(String args) test_dbn();import java.util.Random;public class RBM public int N;public int n_visible;public int n_hidden;public double W;public double hbias;public double vbias;public Random rng;public double uniform(double min, double max) return rng.nextDouble() * (max - min) + min;public int binomial(int n, double p) if(p 1) return 0;int c = 0;double r;for(int i=0; in; i+) r = rng.nextDouble(); /取一个随机数if (r p) c+; /这里就是以概率p 来至0或者至1return c;public static double sigmoid(double x) return 1.0 / (1.0 + Math.pow(Math.E, -x);/RBM 的构造函数public RBM(int N, int n_visible, int n_hidden, double W, double hbias, double vbias, Random rng) this.N = N; / 样本的个数this.n_visible = n_visible; / 可视节点的个数 , 可视节点的个数就是上一层的输出this.n_hidden = n_hidden; / 隐藏节点的个数 , 隐藏节点的个数就是这一层的节点个数if(rng = null)this.rng = new Random(1234); /获取随机值else this.rng = rng;if(W = null) / 初始话 RBM的 W , 因为在构建的时候,是把隐藏层的 W传过来,所以W不是NULL而是sigmoid_layersi.Wthis.W = new doublethis.n_hiddenthis.n_visible;double a = 1.0 / this.n_visible;for(int i=0; ithis.n_hidden; i+) for(int j=0; jthis.n_visible; j+) this.Wij = uniform(-a, a); else this.W = W;if(hbias = null) /初始化RBM 的偏差b , 同理在初始化RBM的时候,hbias是由sigmoid_layers输入的this.hbias = new doublethis.n_hidden;for(int i=0; ithis.n_hidden; i+) this.hbiasi = 0; else this.hbias = hbias;if(vbias = null) /这里初始化,可视层的偏差, 反正都为0就对了this.vbias = new doublethis.n_visible;for(int i=0; ithis.n_visible; i+) this.vbiasi = 0; else this.vbias = vbias;/执行 CD 方法对 w b c 进行梯度下降的调整public void contrastive_divergence(int input, double lr, int k) double ph_mean = new doublen_hidden;/ n-hidden是这一层的节点个数int ph_sample = new intn_hidden; / 保存的是隐藏层的0-1 值double nv_means = new doublen_visible; /采样中 保存的是可视层的 wx+b值int nv_samples = new intn_visible; /采样中 保存的是可视层的0-1值double nh_means = new doublen_hidden; / 采样中 隐藏层的 wx+b 值int nh_samples = new intn_hidden; / 采样中 可视层的0-1值/* CD-k */sample_h_given_v(input, ph_mean, ph_sample); /ph_mean 是wx+b , ph_sample是归一化到01之间for(int step=0; stepk; step+) / k = 1 这里其实也就执行了一次采样if(step = 0) / 执行Gibbs 采样, 从隐藏层到可视层,然后从可视层在返回隐藏层gibbs_hvh(ph_sample, nv_means, nv_samples, nh_means, nh_samples); else gibbs_hvh(nh_samples, nv_means, nv_samples, nh_means, nh_samples);/ 根据梯度下降对 w 的值进行调整 ph_mean为初次计算的隐藏层的值wx+b, input 的原可视层的值(01), nh_means为采样后的隐藏层的值wx+b, nv为采样后的可视层的值(01)for(int i=0; in_hidden; i+) for(int j=0; jn_visible; j+) / Wij += lr *(ph_samplei * inputj - nh_meansi * nv_samplesj) / N;Wij += lr *(ph_meani * inputj - nh_meansi * nv_samplesj) / N;/ 对隐藏层的偏差进行调整hbiasi += lr * (ph_samplei - nh_meansi) / N; /ph_sample 为隐藏层的值01 , nh_means 为采样后返回隐藏层的值wx+b / 对可视层的偏差进行调整for(int i=0; in_visible; i+) vbiasi += lr * (inputi - nv_samplesi) / N;/给定v 计算 h , 其实就是sigmoid(wx+b)public void sample_h_given_v(int v0_sample, double mean, int sample) /mean是wx+b , sample 是归一化到0,1之间for(int i=0; in_hidden; i+) / n-hidden 为这一层的节点个数meani = propup(v0_sample, Wi, hbiasi); /wi为第i个节点的权重, 函数计算这个W*x , 同时传送对应的偏差samplei = binomial(1, meani); /给定 h 计算v public void sample_v_given_h(int h0_sample, double mean, int sample) for(int i=0; in_visible; i+) / n-visible 为可视层的节点个数meani = propdown(h0_sample, i, vbiasi);/h-sample 是从隐藏层传回来的值samplei = binomial(1, meani); / sample 保存的值是0-1的归一化结果/函数计算 sigmoid(wx+b) public double propup(int v, double w, double b) double pre_sigmoid_activation = 0.0;for(int j=0; jn_visible; j+) /n-visible 为上一层的输出维度pre_sigmoid_activation += wj * vj; / 整个for循环就是wij*xj ,向量内积pre_sigmoid_activation += b; / 对向量内积后的实值加上一个偏差return sigmoid(pre_sigmoid_activation); /返回sigmoid 后的数值/计算从隐藏层返回可视层的wx+b ? 为什么不是wc+cpublic double propdown(int h, int i, double b) double pre_sigmoid_activation = 0.0; for(int j=0; jn_hidden; j+) pre_sigmoid_activation += Wji * hj; / 把隐藏层的结果作为输入, 计算wx+b pre_sigmoid_activation += b; return sigmoid(pre_sigmoid_activation);public void gibbs_hvh(int h0_sample, double nv_means, int nv_samples, double nh_means, int nh_samples) sample_v_given_h(h0_sample, nv_means, nv_samples); / 计算从隐藏层到可视层的结果 sample_h_given_v(nv_samples, nh_means, nh_samples); / 在计算从可视层到隐藏层的结果public void reconstruct(int v, double reconstructed_v) double h = new doublen_hidden; double pre_sigmoid_activation; for(int i=0; in_hidden; i+) hi = propup(v, Wi, hbiasi); for(int i=0; in_visible; i+) pre_sigmoid_activation = 0.0; for(int j=0; jn_hidden; j+) pre_sigmoid_activation += Wji * hj; pre_sigmoid_activation += vbiasi; reconstructed_vi = sigmoid(pre_sigmoid_activation); import java.util.Random;public class HiddenLayer public int N; /样本的个数public int n_in; / 隐藏层的输入维度public int n_out; /隐藏层的输出维度public double W; / 隐藏层的权重public double b; / 隐藏层的偏差public Random rng; public double uniform(double min, double max) / 返回 min 到 max的随机值return rng.nextDouble() * (max - min) + min;/ 根据概率p , 获取0-1public int binomial(int n, double p) if(p 1) return 0;int c = 0;double r;for(int i=0; in; i+) r = rng.nextDouble();if (r p) c+;return c;/ sigmoidpublic static double sigmoid(double x) return 1.0 / (1.0 + Math.pow(Math.E, -x);/隐藏层的构建函数public HiddenLayer(int N, int n_in, int n_out, double W, double b, Random rng) this.N = N; / 样本数目 this.n_in = n_in; / 这个隐藏层的输入数目this.n_out = n_out; / 这个隐藏层的输出数目 , 其实就是这一层的节点个数 hidden_layer_sizeiif(rng = null)this.rng = new Random(1234); / 获取随机数else this.rng = rng;if(W = null) / 这里构建隐藏层的权重, 如果W有值的话,就赋值给他,如果没有值的话就随机初始化this.W = new doublen_outn_in; /在计算的时候,上一层的输出会和这一层的W进行内积运算/W*x , Wn-outn-in , xn-in ,相乘后是一个 n-out 维的向量,也就是这一层隐藏层的节点个数,作为下一层的输入double a = 1.0 / this.n_in; for(int i=0; in_out; i+) for(int j=0; jn_in; j+) this.Wij = uniform(-a, a); /为权值矩阵W赋值 ,随机取一个-a , a 之间的数值 else this.W = W;if(b = null) this.b = new doublen_out; / 偏差的维度和输出向量的维度应该是要一样的else this.b = b;/这里和RBM 的propup 是一样的public double output(int input, double w, double b) double linear_output = 0.0;for(int j=0; jn_in; j+) linear_output += wj * inputj;linear_output += b;return sigmoid(linear_output);/ 这里和RBM 的wx+b 是一样的 , 输入input是维度为n-in 的向量,输出sample是n-out的向量public void sample_h_given_v(int input, int sample) for(int i=0; in_out;
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 七练级上册数学试卷
- 平江八上期末数学试卷
- 浦东区笔试数学试卷
- 期末检测卷二数学试卷
- 去年中考无锡卷数学试卷
- 七上数学数学试卷
- 2025中国建筑总部招聘考试模拟试题及答案解析
- 宁乡考试数学试卷
- 萍乡中学九年级数学试卷
- 崎岭中学九年级数学试卷
- 2025年新高考全国一卷地理试题及答案解析
- 2025年吉林银行招聘考试(综合知识)历年参考题库含答案详解(5套)
- 入职合同里的保密协议竞业协议
- 出租充电桩车位合同范本
- 人工晶体创新创业项目商业计划书
- 2025年长沙市中考数学真题(含答案)
- 开放性骨折感染预防的护理
- 浙江宁波江北区重点达标名校2026届中考三模语文试题含解析
- PC构件吊装专项施工方案(修改1)
- 混泥土计量管理办法
- 二级生物安全实验室备案材料
评论
0/150
提交评论