深度学习DBN深度置信网络

转载 2017年06月20日 11:48:28

之前的文章有些地方不太完善,故补充完善一下。
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)

在一个RBM中,隐层神经元hj被激活的概率:
P(hj|v)=σ(bj+ΣiWi,jxi)    (2)

由于是双向连接,显层神经元同样能被隐层神经元激活:
P(vi|h)=σ(ci+ΣjWi,jhj)    (3)

其中,σ 为 Sigmoid 函数,也可以设定为其他函数。
值得注意的是,当σ 为线性函数时,DBN和PCA(主成分分析)是等价的。
同一层神经元之间具有独立性,所以概率密度亦然满足独立性,故得到下式:
P(h|v)=ΠNhj=1P(hj|v)    (4)

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

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

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

由此得到隐层的每个神经元是否被激活。
给定隐层时,显层的计算方法是一样的。

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

  • x赋给显层v1,利用(2)式计算出隐层中每个神经元被激活的概率P(h1|v1)$;
  • 从计算的概率分布中采取Gibbs抽样抽取一个样本:
    h1P(h1|v1)
  • h1重构显层,即通过隐层反推显层,利用(3)式计算显层中每个神经元被激活的概率P(v2|h1)
  • 同样地,从计算得到的概率分布中采取Gibbs抽样抽取一个样本:
    v2P(v2|h1)
  • 通过v2再次计算隐层中每个神经元被激活的概率,得到概率分布P(h2|v2)
  • 更新权重:

WW+λ(P(h1|v1)v1P(h2|v2)v2)

bb+λ(v1v2)

cc+λ(h1h2)

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

深度置信网络(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');
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
function dbn = dbnsetup(dbn, x, opts)
    %n是单个样本的特征维度,784
    n = size(x, 2);
    %dbn.sizes是rbm的维度,[784 100 100]
    dbn.sizes = [n, dbn.sizes];

    %numel(dbn.sizes)返回dbn.sizes中的元素个数,对于[784 100 100],则为3
    %初始化每个rbm
    for 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
        %对应的连接权重,初始值全为0
        dbn.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
        %显层的偏置值,初始值全为0
        dbn.rbm{u}.b  = zeros(dbn.sizes(u), 1);
        dbn.rbm{u}.vb = zeros(dbn.sizes(u), 1);
        %第一个rbm是100,第二个rbm是100
        %隐层的偏置值,初始值全为0
        dbn.rbm{u}.c  = zeros(dbn.sizes(u + 1), 1);
        dbn.rbm{u}.vc = zeros(dbn.sizes(u + 1), 1);
    end
end
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
function dbn = dbntrain(dbn, x, opts)
    % n = 1;
    % x = train_x,60000个样本,每个维度为784,即60000*784
    %n为dbn中有几个rbm,这里n=2
    n = numel(dbn.rbm);
    %充分训练第一个rbm
    dbn.rbm{1} = rbmtrain(dbn.rbm{1}, x, opts);
    %通过第一个rbm,依次训练后续的rbm
    for i = 2 : n
        %建立rbm
        x = rbmup(dbn.rbm{i - 1}, x);
        %训练rbm
        dbn.rbm{i} = rbmtrain(dbn.rbm{i}, x, opts);
    end

end
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
function x = rbmup(rbm, x)
    %sigm为sigmoid函数
    %通过隐层计算下一层
    x = sigm(repmat(rbm.c', size(x, 1), 1) + x * rbm.W');
end
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
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 = 60000
    m = size(x, 1);
    %训练批次,每一批是opts.batchsize个样本,注意这里opts.batchsize必须整除m
    numbatches = m / opts.batchsize;

    %opts.batchsize必须能整除m
    assert(rem(numbatches, 1) == 0, 'numbatches not integer');

    %opts.numepochs,训练次数
    for i = 1 : opts.numepochs

        %随机打乱1-m的数,也就是1-m的随机数,kk是1-m的随机数向量
        kk = randperm(m);

        %训练结果的eer
        err = 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;

            %计算err
            err = 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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62

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

系统学习深度学习(三) --RBM及DBN

转自:/zouxy09/article/details/8781396 9.3、Restricted Boltzmann Machine (RBM)限制波尔兹曼...
  • App_12062011
  • App_12062011
  • 2017年01月10日 13:41
  • 7340

DeepLearningToolBox学习——DBN(Deep Belief Net )

下载地址:DeepLearningToolBox 1. DBN基础知识 DBN 是由多层 RBM 组成的一个神经网络,它既可以被看作一个生成模型,也可以当作判别模型,其训练过程是:使用非监...
  • u010025211
  • u010025211
  • 2016年01月25日 20:21
  • 2792

DBN(深度置信网络)

参考文献:/zouxy09/article/details/8775518 具有层次结构的数学算法:                  神经网络      ...
  • win_in_action
  • win_in_action
  • 2014年05月08日 19:25
  • 25525

深度学习 —— 深度置信网络

深度置信网络 [Hinton06]提出了RBMs可以堆叠起来以贪婪的方式进行训练以构成深度置信网络(DBN)。DBNs是学习提取训练数据深度结构表征的图模型,为观察到的向量x和l隐藏层h_k的联合分...
  • wangli0519
  • wangli0519
  • 2017年06月03日 22:00
  • 1664

深度置信网络(DBN)和受限玻尔兹曼机(RBM)

原博客于http://blog.163.com/silence_ellen/blog/static/176104222201431710264087/ 本篇非常简要地介绍了深度信念网络的基本概念...
  • OPPOA113
  • OPPOA113
  • 2015年01月07日 09:41
  • 5600

theano学习指南--深度置信网络(DBN)(翻译)

欢迎fork我的github:https://github.com/zhaoyu611/DeepLearningTutorialForChinese最近在学习Git,所以正好趁这个机会,把学习到的知识...
  • zhaoyu106
  • zhaoyu106
  • 2016年08月30日 21:11
  • 4116

深度置信网络学习总结

深度置信网络学习总结 目录 深度置信网络学习总结... 1 一、 蒙特卡洛方法和Gibbs 采样... 2 1.1 随机模拟(蒙特卡罗方法)的作用... 2 3.2蒙特卡洛的基础——马...
  • qq_27652147
  • qq_27652147
  • 2016年12月22日 14:56
  • 1716

DBN(深度置信网络)解析

我在上篇文章介绍了RBM(受限玻尔兹曼机),本篇文章需要RBM的先验知识,不了解的可以去看看,了解了继续往下看。1.DBN结构 DBN: 将RBM像砖块一样叠加起来构建的一个网络。 DBN训练方法...
  • zhoutaochun
  • zhoutaochun
  • 2016年12月14日 22:42
  • 985

深度学习阅读笔记(二)之自动编码器SAD

一、自动编码器(DAE)    7. 《深度自动编码器的研究与展望》    主要内容:讲述了自动编码器的发展由来。阐述了DAE的基本概念和原理;网络模型的构建和训练方法。并对DAE进行了分类,指出了D...
  • lqfarmer
  • lqfarmer
  • 2015年05月04日 12:41
  • 3468

DBN模型

(一)马尔可夫随机场 1.概率图模型:1)用图的形式来表示概率分布;2)用图的方法来求解概率分布问题;3)可分为概率有向图模型跟概率无向图模型; 2.马尔可夫随机场定义(又叫概率无向图模型): (1)...
  • dream_catcher_10
  • dream_catcher_10
  • 2015年07月19日 13:39
  • 3158
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习DBN深度置信网络
举报原因:
原因补充:

(最多只允许输入30个字)