之前的文章有些地方不太完善,故补充完善一下。
2017-4-10。


深度信念网络,DBN,Deep Belief Nets,神经网络的一种。既可以用于非监督学习,类似于一个自编码机;也可以用于监督学习,作为分类器来使用。

从非监督学习来讲,其目的是尽可能地保留原始特征的特点,同时降低特征的维度。从监督学习来讲,其目的在于使得分类错误率尽可能地小。而不论是监督学习还是非监督学习,DBN的本质都是Feature Learning的过程,即如何得到更好的特征表达。


作为神经网络,神经元自然是其必不可少的组成部分。DBN由若干层神经元构成,组成元件是受限玻尔兹曼机(RBM)

首先来了解一下受限玻尔兹曼机(RBM):
RBM是一种神经感知器,由一个显层和一个隐层构成,显层与隐层的神经元之间为双向全连接。如下图所示:

在RBM中,任意两个相连的神经元之间有一个权值w表示其连接强度,每个神经元自身有一个偏置系数b(对显层神经元)和c(对隐层神经元)来表示其自身权重。
这样,就可以用下面函数表示一个RBM的能量:

E(v,h)=−ΣNvi=1bivi−ΣNhj=1cjhj−ΣNv,Nhi,j=1Wijvihj    (1)

E(v,h) = -\Sigma_{i=1}^{N_v}b_iv_i-\Sigma_{j=1}^{N_h}c_jh_j-\Sigma_{i,j=1}^{N_v,N_h}W_{ij}v_ih_j\space\space\space\space (1)
在一个RBM中,隐层神经元 hj h_j被激活的概率:

P(hj|v)=σ(bj+ΣiWi,jxi)    (2)

P(h_j|v) = \sigma(b_j+\Sigma_iW_{i,j}x_i)\space\space\space\space (2)
由于是双向连接,显层神经元同样能被隐层神经元激活:

P(vi|h)=σ(ci+ΣjWi,jhj)    (3)

P(v_i|h) = \sigma(c_i+\Sigma_jW_{i,j}h_j)\space\space\space\space (3)
其中, σ \sigma 为 Sigmoid 函数,也可以设定为其他函数。
值得注意的是,当 σ \sigma 为线性函数时,DBN和PCA(主成分分析)是等价的。
同一层神经元之间具有独立性,所以概率密度亦然满足独立性,故得到下式:

P(h|v)=ΠNhj=1P(hj|v)    (4)

P(h|v)=\Pi_{j=1}^{N_h}P(h_j|v)\space\space\space\space (4)

P(v|h)=ΠNvi=1P(vi|h)    (5)

P(v|h)=\Pi_{i=1}^{N_v}P(v_i|h)\space\space\space\space (5)

以上即为受限玻尔兹曼机(RBM)的基本构造。其结构并不复杂。下面来看看它的工作原理:
当一条数据(如向量 x x)赋给显层后,RBM根据(3)式计算出每个隐层神经元被开启的概率P(hj|x),j=1,2,...,NhP(h_j|x),j=1,2,...,N_h,取一个0-1的随机数 μ \mu作为阈值,大于该阈值的神经元则被激活,否则不被激活,即:

hj=1,P(hj|x)≥μ;hj=0,P(hj|x)<μ

h_j = 1,P(h_j|x) \geq \mu;h_j = 0,P(h_j|x)
由此得到隐层的每个神经元是否被激活。
给定隐层时,显层的计算方法是一样的。

了解工作原理之后就可以看看RBM是如何通过数据学习的了:
RBM共有五个参数:h、v、b、c、W,其中b、c、W,也就是相应的权重和偏置值,是通过学习得到的。(v是输入向量,h是输出向量)
对于一条样本数据 x x,采用对比散度算法对其进行训练:

  • 将xx赋给显层 v1 v_1,利用(2)式计算出隐层中每个神经元被激活的概率 P(h1|v1) P(h_1|v_1)$;

    • 从计算的概率分布中采取Gibbs抽样抽取一个样本:

      h1∼P(h1|v1)

      h_1\sim P(h_1|v_1)

      • 用 h1 h_1重构显层,即通过隐层反推显层,利用(3)式计算显层中每个神经元被激活的概率 P(v2|h1) P(v_2|h_1);
      • 同样地,从计算得到的概率分布中采取Gibbs抽样抽取一个样本:
        v2∼P(v2|h1)

        v_2\sim P(v_2|h_1)

      • 通过 v2 v_2再次计算隐层中每个神经元被激活的概率,得到概率分布 P(h2|v2) P(h2|v_2)
      • 更新权重:
      • W←W+λ(P(h1|v1)v1−P(h2|v2)v2)

        W \leftarrow W+\lambda(P(h_1|v_1)v_1-P(h_2|v_2)v_2)

        b←b+λ(v1−v2)

        b \leftarrow b+\lambda(v_1-v_2)

        c←c+λ(h1−h2)

        c \leftarrow c+\lambda(h_1-h_2)
        若干次训练后,隐层不仅能较为精准地显示显层的特征,同时还能够还原显层。当隐层神经元数量小于显层时,则会产生一种“数据压缩”的效果,也就类似于自动编码器。

        深度置信网络(DBN):
        将若干个RBM“串联”起来则构成了一个DBN,其中,上一个RBM的隐层即为下一个RBM的显层,上一个RBM的输出即为下一个RBM的输入。训练过程中,需要充分训练上一层的RBM后才能训练当前层的RBM,直至最后一层。

        很多的情况下,DBN是作为无监督学习框架来使用的,并且在语音识别中取得了很好的效果。

        若想将DBM改为监督学习,方式有很多,比如在每个RBM中加上表示类别的神经元,在最后一层加上softmax分类器。也可以将DBM训出的W看作是NN的pre-train,即在此基础上通过BP算法进行fine-tune。实际上,前向的算法即为原始的DBN算法,后项的更新算法则为BP算法,这里,BP算法可以是最原始的BP算法,也可以是自己设计的BP算法。

        DBN的实现(DeepLeranToolBox):
        这里是将DBN作为无监督学习框架来使用的,将“学习成果”赋给ANN来完成分类。

        训练集是60000张28*28的手写数字图片,测试集是10000张28*28的手写数字图片,对应的单幅图片的特征维度为28*28=784

        % function test_example_DBN
        load mnist_uint8;train_x = double(train_x) / 255;
        test_x  = double(test_x)  / 255;
        train_y = double(train_y);
        test_y  = double(test_y);%%  ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NN
        rand('state',0)
        %train dbn
        %对DBN的初始化
        %除了输入层之外有两层,每层100个神经元,即为两个受限玻尔兹曼机
        dbn.sizes = [100 100];
        %训练次数
        opts.numepochs =   2;
        %每次随机的样本数量
        opts.batchsize = 100;
        %更新方向,目前不知道有什么用
        opts.momentum  =   0;
        %学习速率
        opts.alpha     =   1;
        %建立DBN
        dbn = dbnsetup(dbn, train_x, opts);
        %训练DBN
        dbn = dbntrain(dbn, train_x, opts);
        %至此,已完成了DBN的训练%unfold dbn to nn
        %将DBN训练得到的数据转化为NN的形式
        nn = dbnunfoldtonn(dbn, 10);%设置NN的阈值函数为Sigmoid函数
        nn.activation_function = 'sigm';%train nn
        %训练NN
        opts.numepochs =  3;
        opts.batchsize = 100;
        nn = nntrain(nn, train_x, train_y, opts);
        [er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');
        function dbn = dbnsetup(dbn, x, opts)%n是单个样本的特征维度,784n = size(x, 2);%dbn.sizes是rbm的维度,[784 100 100]dbn.sizes = [n, dbn.sizes];%numel(dbn.sizes)返回dbn.sizes中的元素个数,对于[784 100 100],则为3%初始化每个rbmfor u = 1 : numel(dbn.sizes) - 1%初始化rbm的学习速率dbn.rbm{u}.alpha    = opts.alpha;%学习方向dbn.rbm{u}.momentum = opts.momentum;%第一个rbm是784-100, 第二个rbm是100-100%对应的连接权重,初始值全为0dbn.rbm{u}.W  = zeros(dbn.sizes(u + 1), dbn.sizes(u));%用于更新的权重,下同,不再注释dbn.rbm{u}.vW = zeros(dbn.sizes(u + 1), dbn.sizes(u));%第一个rbm是784,第二个rbm是100%显层的偏置值,初始值全为0dbn.rbm{u}.b  = zeros(dbn.sizes(u), 1);dbn.rbm{u}.vb = zeros(dbn.sizes(u), 1);%第一个rbm是100,第二个rbm是100%隐层的偏置值,初始值全为0dbn.rbm{u}.c  = zeros(dbn.sizes(u + 1), 1);dbn.rbm{u}.vc = zeros(dbn.sizes(u + 1), 1);end
        end
        
        function dbn = dbntrain(dbn, x, opts)% n = 1;% x = train_x,60000个样本,每个维度为784,即60000*784%n为dbn中有几个rbm,这里n=2n = numel(dbn.rbm);%充分训练第一个rbmdbn.rbm{1} = rbmtrain(dbn.rbm{1}, x, opts);%通过第一个rbm,依次训练后续的rbmfor i = 2 : n%建立rbmx = rbmup(dbn.rbm{i - 1}, x);%训练rbmdbn.rbm{i} = rbmtrain(dbn.rbm{i}, x, opts);endend
        
        function x = rbmup(rbm, x)%sigm为sigmoid函数%通过隐层计算下一层x = sigm(repmat(rbm.c', size(x, 1), 1) + x * rbm.W');
        end
        
        function rbm = rbmtrain(rbm, x, opts)%矩阵x中的元素必须是浮点数,且取值为[0,1]assert(isfloat(x), 'x must be a float');assert(all(x(:)>=0) && all(x(:)<=1), 'all data in x must be in [0:1]');%m为样本数量,这里m = 60000m = size(x, 1);%训练批次,每一批是opts.batchsize个样本,注意这里opts.batchsize必须整除mnumbatches = m / opts.batchsize;%opts.batchsize必须能整除massert(rem(numbatches, 1) == 0, 'numbatches not integer');%opts.numepochs,训练次数for i = 1 : opts.numepochs%随机打乱1-m的数,也就是1-m的随机数,kk是1-m的随机数向量kk = randperm(m);%训练结果的eererr = 0;%对每一批数据进行训练for l = 1 : numbatches%取出opts.batchsize个待训练的样本%循环结束后所有样本都进行过训练,且仅训练了一次batch = x(kk((l - 1) * opts.batchsize + 1 : l * opts.batchsize), :);%赋值给v1%这里v1是100*784的矩阵v1 = batch;%通过v1计算h1的概率,吉布斯抽样h1 = sigmrnd(repmat(rbm.c', opts.batchsize, 1) + v1 * rbm.W');%通过h1计算v1的概率,吉布斯抽样v2 = sigmrnd(repmat(rbm.b', opts.batchsize, 1) + h1 * rbm.W);%通过v2计算h2的概率,吉布斯抽样h2 = sigm(repmat(rbm.c', opts.batchsize, 1) + v2 * rbm.W');%至此,h1,v1,h2,v2均已计算出来,即完成了对比散度算法的大半,只剩下相应权重的更新%权重更新的差值计算c1 = h1' * v1;c2 = h2' * v2;rbm.vW = rbm.momentum * rbm.vW + rbm.alpha * (c1 - c2)     / opts.batchsize;rbm.vb = rbm.momentum * rbm.vb + rbm.alpha * sum(v1 - v2)' / opts.batchsize;rbm.vc = rbm.momentum * rbm.vc + rbm.alpha * sum(h1 - h2)' / opts.batchsize;%更新权重rbm.W = rbm.W + rbm.vW;rbm.b = rbm.b + rbm.vb;rbm.c = rbm.c + rbm.vc;%计算errerr = err + sum(sum((v1 - v2) .^ 2)) / opts.batchsize;end%打印结果disp(['epoch ' num2str(i) '/' num2str(opts.numepochs)  '. Average reconstruction error is: ' num2str(err / numbatches)]);end
        end
        

        对于手写数字的识别结果还是很好的,即便是最简单的DBN+NN(如上参数设置),也可以达到95%的正确率。

深度学习-深度信念(置信)网络(DBN)-从原理到实现(DeepLearnToolBox)相关推荐

  1. 深度学习基础--不同网络种类--深度置信网络(DBN)

    深度置信网络(DBN)   RBM的作用就是用来生成似然分布的互补先验分布,使得其后验分布具有因子形式.   因此,DBN算法解决了Wake-Sleep算法表示分布难以匹配生成分布的难题,通过RBM使 ...

  2. 【DBN分类】基于matlab深度置信网络DBN变压器故障诊断【含Matlab源码 2284期】

    ⛄一.获取代码方式 获取代码方式1: 完整代码已上传我的资源:[DBN分类]基于matlab深度置信网络DBN变压器故障诊断[含Matlab源码 2284期] 获取代码方式2: 付费专栏Matlab智 ...

  3. 【总结】关于玻尔兹曼机(BM)、受限玻尔兹曼机(RBM)、深度玻尔兹曼机(DBM)、深度置信网络(DBN)理论总结和代码实践

    近期学习总结 前言 玻尔兹曼机(BM) 波尔兹曼分布推导过程 吉布斯采样 受限玻尔兹曼机(RBM) 能量函数 CD学习算法 代码实现受限玻尔兹曼机 深度玻尔兹曼机(DBM) 代码实现深度玻尔兹曼机 深 ...

  4. 提升深度学习模型性能及网络调参

    提升深度学习模型性能及网络调参 https://www.toutiao.com/a6637086018950398472/ 图像处理与机器视觉 2018-12-25 10:42:00 深度学习有很多的 ...

  5. 【深度学习】图像输入网络必要的处理流程

    [深度学习]图像输入网络必要的处理流程 文章目录 1 图像处理之灰度转化 2 归一化 3 CLAHE 4 伽马矫正 5 Data augmentation5.1 裁剪(Crop)5.2 缩放ÿ

  6. 【深度学习】Swin-Unet图像分割网络解析(文末提供剪枝仓库)

    [深度学习]Swin-Unet图像分割网络解析(文末提供剪枝仓库) 文章目录 1 概述 2 Swin-Unet架构 3 bottleneck理解 4 具体结构4.1 Swin Transformer ...

  7. 深度学习之生成对抗网络(8)WGAN-GP实战

    深度学习之生成对抗网络(8)WGAN-GP实战 代码修改 完整代码 WGAN WGAN_train 代码修改  WGAN-GP模型可以在原来GAN代码实现的基础上仅做少量修改.WGAN-GP模型的判别 ...

  8. 深度学习之生成对抗网络(7)WGAN原理

    深度学习之生成对抗网络(7)WGAN原理 1. JS散度的缺陷 2. EM距离 3. WGAN-GP  WGAN算法从理论层面分析了GAN训练不稳定的原因,并提出了有效的解决方法.那么是什么原因导致了 ...

  9. 深度学习之生成对抗网络(6)GAN训练难题

    深度学习之生成对抗网络(6)GAN训练难题 1. 超参数敏感 2. 模式崩塌  尽管从理论层面分析了GAN网络能够学习到数据的真实分布,但是在工程实现中,常常出现GAN网络训练困难的问题,主要体现在G ...

  10. 深度学习之生成对抗网络(4)GAN变种

    深度学习之生成对抗网络(4)GAN变种 1. DCGAN 2. InfoGAN 3. CycleGAN 4. WGAN 5. Equal GAN 6. Self-Attention GAN 7. Bi ...

最新文章

  1. 发布在《30天自制操作系统》之前的帮助阅读贴
  2. js实现搜索记录列表
  3. elk系列7之通过grok分析apache日志
  4. sql根据年月日查询注册数或者和值
  5. Linux 将文件夹下的所有文件复制到另一个文件里
  6. python解包操作_Python编程使用*解包和itertools.product()求笛卡尔积的方法
  7. 【bzoj1565】[NOI2009]植物大战僵尸 【网络流】【最大权闭合子图】
  8. php表单提交邮箱_最全实现dede订单表单提交发送到指定邮箱(附前台设置)
  9. 分阶段付款 学php,项目整理-支付宝的支付问题
  10. A Beginner's Guide To Understanding Convolutional Neural Networks Part One (CNN)笔记
  11. Bill Gates 2007年哈佛演讲(中/英文)
  12. OPENCV与OPENCL
  13. Python爬虫用到的一些浏览器代理标识
  14. c语言美元符号用法,R函数()中美元符号“$”的含义是什么?
  15. 检测浏览器是pc端还是移动端 是否微信浏览器
  16. 简单使用萤石云,实时直播,监控回放
  17. hadoop集群-单词统计
  18. 华为防火墙VRRP双机热备的配置
  19. C语言的字母大小写转化
  20. i-usb-storer android,【精品】智能手机基本知识 培训教材 金立手机集团.ppt

热门文章

  1. xlsx无法导入MySQL?
  2. 视比特“AI+3D视觉”产品系列 | 上料装配工作站
  3. svn强制弹出账号密码对话框
  4. Windows 11和Windows 2022 TLS/SSL(Schannel SSP)的加密套件
  5. java实现将将时间段分成8段,判断当前时间在哪一段时间里?
  6. 20145212罗天晨 恶意代码分析
  7. Katalon自动化测试基础教程(一)
  8. android zigbee环境监测,基于ZigBee技术的室内定位与环境监测系统
  9. STK中设置卫星的多波束模型
  10. vue项目国际化 vue-i18n以及踩坑解决 小姐姐手把手教你VUE国际化~