1 深度生成模型

1. 深度信念网络

2. 深度玻尔兹曼机

3. 深度自编码器

4. 降噪自编码器

5. 栈式自编码器

6. 生成对抗网络

7. 非参数贝叶斯网络

8. 深度生成模型事件脉络

        1982 -- Hopfield 网络提出

        1983 -- 玻尔兹曼机生成模型被提出

        1992 -- Neal 提出了sigmoid信念网络

        2006 -- Hinton 提出深度信念网络

        2008 -- 采用DBNs完成回归任务

        2009 -- 将卷积深度信念网络用于可视物体识别

        2012 -- DBNs在语音识别领域应用 

        2014 -- GoodFollow提出生成对抗网络

2016 -- DeepMind创建了一个深度生成模型Wavenet可用来生成具有自然人生的语音

2 Hopfield Network

1. 提出时间 20世纪80年代

        单层、全连接、迭代过程

        功能: 记忆并复原-- 通过联想记忆法去除数据中的噪声

2. 优点:

        单元之间的连接权重对称(

深度学习结果模型转化为代码 深度生成模型_网络

) -- 达到稳态的情况 (异步更新)        每个单元没有到自身的连接(

深度学习结果模型转化为代码 深度生成模型_深度学习结果模型转化为代码_02

        单元的状态采用随机异步更新方式,每次只有一个单元改变状态

        n个二值单元做成的二值神经网络,每个单元的输出只能是0或1的两个值

3. 联想记忆--当输入模式为某种状态时,输出端要给出与之相应的输出模式

        若输出模式与输入模式一致,成为自联想记忆,否则称为异联想记忆

深度学习结果模型转化为代码 深度生成模型_神经网络_03

         关于联想记忆可以这么理解: 你在街上看到一个人,感觉其很眼熟,然后你通过联想各类你见过的相似的人,最后得出其是你的一个小学同学;

                输入输出都是同一个人,只不过这个人小时候与现在有了变化。

        其次就是这个的应用,怎么用联想记忆来做应用呢?

                举个简单的例子,做二分类,有橘子和苹果,他们都有同一属性的不同属性值,将其放入网络中计算,最后输出的值要么符合橘子的设定值,要么符合苹果的设定值。

4. 神经网络的计算 -- 神经元状态变化规则

        假设有n个单元组成的Hopfield ,第i个单元在t时刻的输入记做

深度学习结果模型转化为代码 深度生成模型_网络_04

, 输出记作

深度学习结果模型转化为代码 深度生成模型_深度学习_05

,连接权重为

深度学习结果模型转化为代码 深度生成模型_神经网络_06

,阈值为

深度学习结果模型转化为代码 深度生成模型_编码器_07

,则 t+1时刻i单元的输出

深度学习结果模型转化为代码 深度生成模型_深度学习_08

可表示为:

深度学习结果模型转化为代码 深度生成模型_深度学习结果模型转化为代码_09

        权重综合大于阈值,取1; 权重总和小于阈值,取0;

        其中

                

深度学习结果模型转化为代码 深度生成模型_神经网络_10

        输入是来自于其他单元对其的输入计算得来;

5. Hopfield 网络每个时刻只选择一个单元发生状态变化,对于一个由n个单元组成的网络,如果要完成全部单元的状态变化,至少需要n个时刻;

        单元的状态变化会一直进行下去,直到达到网络的稳定状态,各单元的最终状态就是输出模式;

6. 根据输入模式联想输出模式时,需要事先确定连接权重

深度学习结果模型转化为代码 深度生成模型_神经网络_06

,连接权重要对输入模式的训练样本进行训练后才能确定;

        和多层神经网络一样,一次训练并不能确定连接权重,而是要不断重复这个过程,直到满足终止判断条件,而这个指标就是Hopfield神经网络的能量函数𝐸:(这是在物理中常用的说法):

深度学习结果模型转化为代码 深度生成模型_编码器_12

        当输入模式与输出模式一致时,能量函数𝐸的结果是0;

        也就是说能量函数越小越稳定;

7. 根据前面定义的状态变化规则改变网络状态时,上式中定义的能量函数𝐸总是非递增的,即随时间的不断增加而逐渐减小,直到网络达到稳定状态为止;

        能量函数分解成单元k的能量函数和k 以外的单元的能量函数;

8. hopfield network应用

        记住训练样本 -- 自联想记忆 -- 对测试样本去噪 (对比一下和哪个类型比较像,之后把测试样本变得与那个类别更像一些)

        当需要记忆的模式之间的较为相似,或者需要记忆的模式太多时,Hopfield神经网络就不能正确地辨别模式。这种相互干扰、不能准确记忆的情况称为串扰(crosstalk)

关于串扰的例子,如下图所示:

深度学习结果模型转化为代码 深度生成模型_网络_13

 

        由于“4”中包含了“1”中的全部竖线,Hopfield网络错把带有“横线”噪音的测试样本“1”识别为“4”,这种情况即串扰。

9. Hopfield神经网络能够记忆的模式数量有限,大约是网络单元数的15%左右,为了防止串扰,可以采用先把模式正交化再进行记忆等方法。

        但是正交化方法并不能完全解决问题玻尔兹曼机可以解决这一问题

3 玻尔兹曼机与受限玻尔兹曼机

1. 玻尔兹曼机也是相互连接型网络

        如果发生串扰或陷入局部最优解(相当于达到了一个相对稳定的状态,也就是说E已经比较小了,相当于在函数的一个极值点,但不是最小值点),Hopfield神经网络就不能正确的辨别模式

        而玻尔兹曼机(Boltzmann Machine)则可以通过让每个单元按照一定的概率分布发生状态变化,来避免陷入局部最优解;

2. 玻尔兹曼机保持了Hopfield神经网络的假设:

        权重对称;

        自身无连接;

        二值输出;

深度学习结果模型转化为代码 深度生成模型_深度学习结果模型转化为代码_14

 3. 玻尔兹曼机是按照某种概率分布决定的

深度学习结果模型转化为代码 深度生成模型_深度学习结果模型转化为代码_15

        𝑇(>0)表示温度系数,当𝑇趋近于无穷时,无论

深度学习结果模型转化为代码 深度生成模型_深度学习结果模型转化为代码_16

取值如何,

深度学习结果模型转化为代码 深度生成模型_深度学习_17

等于1 或0 的概率都是1/2,这种状态称为稳定状态,k是玻尔兹曼常数.

4. 玻尔兹曼机的输出是按照某种概率分布决定的

深度学习结果模型转化为代码 深度生成模型_编码器_18

5. 玻尔兹曼机选择模拟退火算法,可以先采用较大的温度系数进行粗调,然后逐渐减小温度系数进行微调;

        温度系数越大,跳出局部最优解的概率越高。但是温度系数增大时,获得能量函数极小值的概率就会降低 ;

        反之,温度系数减小时,虽然获得能量函数极小值的概率增加了,但是玻尔兹曼机需要经历较长时间才能达到稳定状态;

模拟退火算法简单介绍:

        模拟退火是一种贪心算法,但是它的搜索过程引入了随机因素,以一定的概率来接受一个比当前解要差的解,因此有可能会跳出这个局部的最优解,达到全局的最优解, 而且这个概率随着时间推移逐渐降低(逐渐降低才能趋向稳定)

6. 玻尔兹曼机训练过程

        1. 训练准备:初始化连接权重

深度学习结果模型转化为代码 深度生成模型_神经网络_06

和偏置

深度学习结果模型转化为代码 深度生成模型_深度学习_20


        2. 调整参数

                2.1 选取一个单元𝑖,求

深度学习结果模型转化为代码 深度生成模型_深度学习结果模型转化为代码_16

                2.2 根据

深度学习结果模型转化为代码 深度生成模型_深度学习结果模型转化为代码_16

的值,计算输出

深度学习结果模型转化为代码 深度生成模型_深度学习_17

                2.3 根据输出

深度学习结果模型转化为代码 深度生成模型_深度学习_17


深度学习结果模型转化为代码 深度生成模型_编码器_25

的值,调整连接权重

深度学习结果模型转化为代码 深度生成模型_网络_26

和偏置;

                重复步骤2,直到满足终止判断条件

具体而言,当初始化连接权重后,选取一个单元𝑖

        计算单元激活值

深度学习结果模型转化为代码 深度生成模型_深度学习结果模型转化为代码_16

                

深度学习结果模型转化为代码 深度生成模型_网络_28

        

深度学习结果模型转化为代码 深度生成模型_深度学习结果模型转化为代码_09

        计算

深度学习结果模型转化为代码 深度生成模型_深度学习_17

等于1或0的概率:

深度学习结果模型转化为代码 深度生成模型_深度学习结果模型转化为代码_15

                

         根据概率,调整

深度学习结果模型转化为代码 深度生成模型_深度学习_17

的值,一般是随机产生一个(0,1)之间的随机数λ,如果p>λ, 确认状态改变,否则不改变;        不能将计算所得概率直接作为

深度学习结果模型转化为代码 深度生成模型_深度学习_17

的值,而是作为概率来决定

深度学习结果模型转化为代码 深度生成模型_深度学习_17

的值;7. 调整连接权重

深度学习结果模型转化为代码 深度生成模型_神经网络_06

和偏置

深度学习结果模型转化为代码 深度生成模型_深度学习_20

, 这里用似然函数𝐿(θ)导出调整值,θ表示所有的连接权重和偏置: -- 这相当于现在学习的神经网络中的损失函数

深度学习结果模型转化为代码 深度生成模型_深度学习_37

        其中,概率分布的定义如下,𝐸表示能量函数,𝑍(θ)是归一化常数

深度学习结果模型转化为代码 深度生成模型_编码器_38

深度学习结果模型转化为代码 深度生成模型_编码器_39

        通常,使用对数似然函数求解:(连乘,概率会变得很小):

深度学习结果模型转化为代码 深度生成模型_深度学习_40

        当对数似然函数的梯度为0时,就可以得到最大似然估计量,即通过求连接权重

深度学习结果模型转化为代码 深度生成模型_神经网络_06

和偏置

深度学习结果模型转化为代码 深度生成模型_深度学习_20

的相关梯度,可以求出调整值;

        似然函数是基于所有单元组合来计算的,所以单元数过多将导致组合数异常庞大,无法进行实时计算。为了解决这个问题,人们提出了一种近似算法,对比散度算法

对比散度算法介绍:

        2002年Hinton提出, MCMC(马尔可夫链蒙特卡洛)的状态以训练样本为起点,这样只需很少的状态转移就可以得到RBM的分布

对比散度算法的训练过程:

        1. 训练准备:初始化连接权重和偏置; -- 随机初始化

        2. 调整参数

                2.1 在可见层

深度学习结果模型转化为代码 深度生成模型_网络_43

设置输入模式;                2.2 调整隐藏层中单元

深度学习结果模型转化为代码 深度生成模型_深度学习_44

的值;

                        根据参数初始值计算隐藏层为状态1的概率

        

深度学习结果模型转化为代码 深度生成模型_神经网络_45

                        根据这个概率计算符合二项分布的隐藏层中单元

深度学习结果模型转化为代码 深度生成模型_编码器_46

的状态,其中𝜎表示sigmoid函数

                        根据隐藏层的状态,计算在可见层各单元状态为1的概率:

深度学习结果模型转化为代码 深度生成模型_深度学习结果模型转化为代码_47

                        根据这个概率计算各可见单元

深度学习结果模型转化为代码 深度生成模型_网络_48

的状态

                        上述过程还可以继续进行k次(k步的Gibbs采样),称为k步对比散度法,记做CD-k

                2.3根据输出

深度学习结果模型转化为代码 深度生成模型_深度学习_17


深度学习结果模型转化为代码 深度生成模型_编码器_25

的值,调整连接权重

深度学习结果模型转化为代码 深度生成模型_神经网络_06

,偏置

深度学习结果模型转化为代码 深度生成模型_网络_52

,偏置

深度学习结果模型转化为代码 深度生成模型_编码器_53

;

                

深度学习结果模型转化为代码 深度生成模型_深度学习结果模型转化为代码_54

 

        重复步骤2,直到满足终止判断条件

        玻尔兹曼机中调整参数时也可以Mini-Batch为单位进行计算时效果更佳 -- 每个mini-batch(训练集的一个子集)更新参数,Batch size

8. 前面介绍的玻尔兹曼机默认了所有单元都为可见单元,在实际应用上,玻尔兹曼机还可以由可见单元和隐藏单元共同构成:

        隐藏单元与输入数据没有直接联系,但会影响可见单元的概率。假设可见单元为可见变量𝑣,隐藏单元为隐藏变量ℎ;

        玻尔兹曼机含有隐藏变量时,概率分布仍然与前面计算的结果相同;

        受限玻尔兹曼机隐层与显层层内是不相互连接的:

深度学习结果模型转化为代码 深度生成模型_深度学习_55

含有隐藏变量的玻尔兹曼机训练非常困难,所以Hinton等人提出了受限玻尔兹曼机

        由可见层(v)和隐藏层(h)构成

        层内单元之间无连接

        信息可双向流动

受限玻尔兹曼机的能量函数为:

深度学习结果模型转化为代码 深度生成模型_编码器_56

 其中,

深度学习结果模型转化为代码 深度生成模型_网络_52

是可见变量的偏置,

深度学习结果模型转化为代码 深度生成模型_编码器_53

是隐藏变量的偏置,

深度学习结果模型转化为代码 深度生成模型_神经网络_06

是连接权重,𝜃 = (𝑊,𝐚,𝐛 )是表示所有连接权重和偏置的参数集合;

利用能量函数,可以给出状态(v, h)的联合概率分布:

深度学习结果模型转化为代码 深度生成模型_深度学习_60

观测数据

深度学习结果模型转化为代码 深度生成模型_深度学习_61

的概率分布, 也就是可见层状态变量的概率分布:

深度学习结果模型转化为代码 深度生成模型_网络_62

 类似地,有关于隐藏层状态变量的概率分布:

深度学习结果模型转化为代码 深度生成模型_编码器_63

 调整参数θ训练RBM,和玻尔兹曼机一样,计算时通常使用对数似然函数

深度学习结果模型转化为代码 深度生成模型_编码器_64

 最大化时就沿着梯度的正方向更新

深度学习结果模型转化为代码 深度生成模型_深度学习结果模型转化为代码_65

 给定可见层(或隐藏层)上所有神经元的状态时,隐藏层(或可见层)上的某个神经元被激活(即取值为1)的概率。

4 深度玻尔兹曼机和深度信念网络

1. 深度玻尔兹曼机:由受限玻尔兹曼机堆叠组成

        深度玻尔兹曼机采用与多层神经网络不同的训练方法,在训练时采用对比散度算法逐层来调整连接权重和偏置

        首先训练输入层和隐藏层之间的参数,把训练后得到的参数作为下一层的输入;

        再调整该层与下一个隐藏层之间的参数;

        然后逐次迭代,完成多层网络的训练;

深度学习结果模型转化为代码 深度生成模型_深度学习_66

         深度玻尔兹曼机既可以当作生成模型,也可以当作判别模型:

生成模型使用时:

按照某种概率分布生成训练数据

                概率分布可根据训练样本导出,但是覆盖全部数据模式的概率分布很难导出,所以通常选择最大似然估计法训练参数,得到最能覆盖训练样本的概率分布

                这种生成模型能够:去除输入数据中含有的噪声,得到新的数据,对输入数据压缩和特征表达

判别模型使用时,需要在模型顶层添加一层Softmax实现分类:

                进行分类时,需要同时提供训练样本和期望输出,在最顶层级联一个𝑆𝑜𝑓𝑡𝑚𝑎𝑥层;

                训练方法:

                        除最顶层外,其他各层都可以使用无监督学习进行训练

                        把训练得到的参数作为初始值,使用误差反向传播算法对包含最顶层的神经网络进行训练;

                        最顶层的参数使用随机数进行初始化;

2. 深度信念网络:最上面的两层在它们之间有无向的、对称的连接,并形成一个联想记忆较低层从上层接收自上而下的定向连接最底层单元的状态代表一个数据向量

深度学习结果模型转化为代码 深度生成模型_神经网络_67

 5 自编码器及其变种

 1. 自编码器(Autoencoder):是一种有效的数据维度压缩算法,主要应用在以下两个方面:

        构建一种能够重构输入样本并进行特征表达的神经网络

 特征表达:是指对于分类会发生变动的不稳定模式,例如手写字体识别中由于不同人的书写习惯和风格的不同造成字符模式不稳定,或者输入样本中包含噪声等情况,神经网络也能将其转换成可以准确识别的特征

                训练多层神经网络时,通过自编码器训练样本得到参数初始值;

2. 自编码器结构:

        和RBM类似,由输入层和输出层组成。输入数据𝑥与对应的连接权重𝑊相乘,再加上偏置𝑏,并经过激活函数𝑓(∙)变换后,就可以得到输出𝑦;

        自编码器是一种基于无监督学习的神经网络,目的在于通过不断调整参数,重构经过维度压缩的输入样本

 

深度学习结果模型转化为代码 深度生成模型_网络_68

 

这里,𝑓(∙)表示编码器的激活函数,

深度学习结果模型转化为代码 深度生成模型_网络_69

表示解码器的激活函数。中间层和重构层之间的连接权重及偏置分别记为

深度学习结果模型转化为代码 深度生成模型_深度学习_70


深度学习结果模型转化为代码 深度生成模型_深度学习_71

,重构值记作

深度学习结果模型转化为代码 深度生成模型_神经网络_72

深度学习结果模型转化为代码 深度生成模型_网络_73

 参数的训练使用误差反向传播算法,误差函数可以使用最小二乘误差函数或交叉熵代价函数

         

深度学习结果模型转化为代码 深度生成模型_深度学习结果模型转化为代码_74

 当样本中包含噪声时,如果神经网络能够消除噪声,则被称为降噪自编码器;

还有一种称为稀疏自编码器( Sparse Autoencoder )的网络,它在自编码器中引入了正则化项,以去除冗余信息;

3. 降噪自编码器 Denoising Autoencoder

        降噪自编码器(Denoising Autoencoder)的网络结构和自编码器一样,只是对训练方法进行了改进;

        自编码器是把训练样本直接输入给输入层,而降噪自编码器则是把通过向训练样本中加入随机噪声得到的样本

深度学习结果模型转化为代码 深度生成模型_神经网络_72

输入给输入层        

深度学习结果模型转化为代码 深度生成模型_网络_76

        假设随机噪声𝜀服从均值为0,方差为

深度学习结果模型转化为代码 深度生成模型_深度学习_77

的正态分布,我们需要训练神经网络,使得重构结果和不含噪声的样本之间的误差收敛于极小值;

        误差函数会对不含噪声的输入样本进行计算,故降噪自编码器可以完成以下两项训练:

                保持输入样本不变的条件下,能够更好地反映样本属性的特征;

                消除输入样本中包含的噪声;

深度学习结果模型转化为代码 深度生成模型_深度学习结果模型转化为代码_78

 4. 稀疏自编码器

        在多层自编码器中,中间层的单元数太少会导致神经网络很难重构输入样本,而单元数太多又会产生单元冗余,降低压缩效率;

        为了解决这个问题,人们将稀疏正则化引入到自编码器中,提出了稀疏自编码器(Sparse Autoencoder):

                通过增加正则化项,大部分单元的输出都变成了0,就能利用少数单元完成压缩或重构;

        加入正则化后的误差函数𝐸如下所示:

深度学习结果模型转化为代码 深度生成模型_深度学习_79

        𝜌表示平均激活度的目标值,𝛽用于控制稀疏性的权重

深度学习结果模型转化为代码 深度生成模型_神经网络_80

表示中间层第𝑗个单元的平均激活度:

深度学习结果模型转化为代码 深度生成模型_深度学习结果模型转化为代码_81

         

深度学习结果模型转化为代码 深度生成模型_深度学习_82

表示KL距离(Kullback-Leibler divergence)

深度学习结果模型转化为代码 深度生成模型_神经网络_83

         KL距离反映了平均激活度和目标值的差异。𝜌值越接近于0,中间层的平均激活度

深度学习结果模型转化为代码 深度生成模型_神经网络_80

就越小        稀疏自编码器的训练也需要用到误差反向传播算法,对误差函数求导时须考虑𝐾𝐿(𝜌||

深度学习结果模型转化为代码 深度生成模型_神经网络_80

)的导数

深度学习结果模型转化为代码 深度生成模型_网络_86

         平均激活度是根据所有样本计算出来的,所以在计算任何单元的反向传播之前,需要对所有样本计算一遍正向传播,从而获取平均激活度,所以使用小批量梯度下降法进行训练时的效率很低;

        为了解决此问题,可以只计算Mini-Batch中包含的样本的平均激活度,然后在Mini-Batch之间计算加权平均并求近似值;

5. 栈式自编码器

        自编码器、降噪自编码器、稀疏自编码器都是包括编码器和解码器的三层结构;

        但是在进行维度压缩时,可以只包括输入层和中间层。输入层和中间层多层堆叠后,就可以得到栈式自编码器(Stacked Autoencoder)

        栈式自编码器和深度信念网络一样,都是逐层训练。但两种网络的训练方法不同,深度信念网络是利用对比散度算法逐层训练两层之间的参数。而栈式自编码器的训练过程
如下:

                首先训练第一个自编码器,然后保留第一个自编码器的编码器部分;

                把第一个自编码器的中间层作为第二个自编码器的输入层进行训练;

                反复地把前一个自编码器的中间层作为后一个编码器的输入层,进行迭代训练;

深度学习结果模型转化为代码 深度生成模型_编码器_87

         与上面深度信念网络训练对比图就可以看出不同。

        栈式自编码器每层都能得到有效的参数,所以我们可以把训练后的参数作为神经网络或卷积神经网络的参数初始值,这种方法叫作预训练

        预训练属于无监督学习,接下来需要使用有监督学习来调整整个网络的参数,这也叫作微调( fine tuning )。