1、本章简介本章简介我们已经在上面章节中介绍了处理不同类型数据的深度学习模我们已经在上面章节中介绍了处理不同类型数据的深度学习模型,例如能够处理图像数据的卷积神经网络,能够处理序列数型,例如能够处理图像数据的卷积神经网络,能够处理序列数据的一维卷积网络以及长短期记忆网络,同时在据的一维卷积网络以及长短期记忆网络,同时在KerasKeras中实现了中实现了这些模型。我们也讨论了一些提升模型性能的方法,但是还没这些模型。我们也讨论了一些提升模型性能的方法,但是还没有讨论在实际工程中如何去优化模型。本章将系统地介绍几种有讨论在实际工程中如何去优化模型。本章将系统地介绍几种常见的深度学习模型的优化方法,同
2、时讨论影响深度学习模型常见的深度学习模型的优化方法,同时讨论影响深度学习模型优化的因素。优化的因素。6-1 6-1 参数初始化参数初始化 深度学习模型的训练算法通常是迭代的,需要一步一步地更新,因深度学习模型的训练算法通常是迭代的,需要一步一步地更新,因此要设置一些初始点。初始点的选择很大程度地决定了算法是否收敛,此要设置一些初始点。初始点的选择很大程度地决定了算法是否收敛,以及收敛速度是否达到期望。有一些初始点使模型表现得十分不稳定,以及收敛速度是否达到期望。有一些初始点使模型表现得十分不稳定,致使训练完全失败。致使训练完全失败。当初始化点靠近一个局部最优点时,它有更大的概率收敛至相距最当初
3、始化点靠近一个局部最优点时,它有更大的概率收敛至相距最近的局部最优点。这一点可以通过图近的局部最优点。这一点可以通过图6.36.3来理解。来理解。图图6-3 6-3 初始点的梯度与模型收敛至最近局部最优点有关初始点的梯度与模型收敛至最近局部最优点有关目前存在的一些初始化策略是简单的、启发式的,并没有一个对于目前存在的一些初始化策略是简单的、启发式的,并没有一个对于参数初始化的成熟理论。而有些初始点从优化的观点看或许是有利的,参数初始化的成熟理论。而有些初始点从优化的观点看或许是有利的,但是从泛化的观点看是不利的。但是从泛化的观点看是不利的。虽然如此,但是有一个初始化原则确是很明确的,那就是初始
4、化参虽然如此,但是有一个初始化原则确是很明确的,那就是初始化参数时需要在有相同输入的不同单元间数时需要在有相同输入的不同单元间“破坏相似性破坏相似性”。也就是说,如果。也就是说,如果有同一个输入连接到具有相同激活函数的两个不同的隐藏单元时,这些有同一个输入连接到具有相同激活函数的两个不同的隐藏单元时,这些隐藏单元必须具有不同的初始参数。如果它们具有相同的初始参数,后隐藏单元必须具有不同的初始参数。如果它们具有相同的初始参数,后面在计算模型的确定性损失和更新参数时都将一直以相同的方式处理这面在计算模型的确定性损失和更新参数时都将一直以相同的方式处理这两个单元。通常情况下,我们将每个单元的偏置设置
5、为常数,仅随机初两个单元。通常情况下,我们将每个单元的偏置设置为常数,仅随机初始化权重。始化权重。有些启发式方法可用于选择权重的初始大小。例如使用标准初始化有些启发式方法可用于选择权重的初始大小。例如使用标准初始化(Normalized InitializationNormalized Initialization)。初始化。初始化m m个输入和个输入和 n n个输出的个输出的全连接层权重的启发式方法满足式全连接层权重的启发式方法满足式6.36.3所示的分布。所示的分布。,66,i jWUm nm n(6-3)另一种方法是初始化为随机正交矩阵,这时需要仔细挑选每一层的非另一种方法是初始化为随机
6、正交矩阵,这时需要仔细挑选每一层的非线性缩放或增益线性缩放或增益(Gain)(Gain)因子因子 。这种初始化方案也是受启发于不含非。这种初始化方案也是受启发于不含非线性的矩阵相乘序列的深度网络。在该模型下,这个初始化方案保证线性的矩阵相乘序列的深度网络。在该模型下,这个初始化方案保证了达到收敛所需的训练迭代总次数独立于深度。换句话说在这种初始了达到收敛所需的训练迭代总次数独立于深度。换句话说在这种初始化方案下,深度学习模型的深度不再对训练所需的迭代总次数产生影化方案下,深度学习模型的深度不再对训练所需的迭代总次数产生影响。该方法的一个重要观点是,在前馈网络中,激活和梯度会在每一响。该方法的一
7、个重要观点是,在前馈网络中,激活和梯度会在每一步前向传播或反向传播中增加或减小,由于前馈网络在每一层使用了步前向传播或反向传播中增加或减小,由于前馈网络在每一层使用了不同的权重矩阵,因此遵循随机游走行为。如果该随机游走调整到保不同的权重矩阵,因此遵循随机游走行为。如果该随机游走调整到保持范数,那么前馈网络能够很大程度地避免相同权重矩阵用于每层的持范数,那么前馈网络能够很大程度地避免相同权重矩阵用于每层的梯度消失与爆炸问题。梯度消失与爆炸问题。有一种被称为稀疏初始化(有一种被称为稀疏初始化(Sparse InitializationSparse Initialization)的替代方案,)的替代
8、方案,它令每个单元初始化有它令每个单元初始化有 个非零权重。这个想法是将该单元输入的个非零权重。这个想法是将该单元输入的数量独立于单元所在层总的输入数目数量独立于单元所在层总的输入数目 ,保证了不使权重的大小随,保证了不使权重的大小随着标准化(除以着标准化(除以 )而变得极小。简单来说非零权重的个数是固定)而变得极小。简单来说非零权重的个数是固定的,与每一层的具体规模无关。所以稀疏初始化有助于实现单元之的,与每一层的具体规模无关。所以稀疏初始化有助于实现单元之间初始化时的多样性,避免了由于层规模过大而造成的权重变小的间初始化时的多样性,避免了由于层规模过大而造成的权重变小的现象。但是,由于获得
9、较大取值的权重相当于被加了较强的先验,现象。但是,由于获得较大取值的权重相当于被加了较强的先验,因此需要长时间的梯度下降才能够修正较大的目标函数偏离值。因此需要长时间的梯度下降才能够修正较大的目标函数偏离值。本节讨论了权重初始化对模型性能的影响,并介绍了几种常用本节讨论了权重初始化对模型性能的影响,并介绍了几种常用的权重与偏置的初始化方法,如标准化权重初始值、稀疏初始的权重与偏置的初始化方法,如标准化权重初始值、稀疏初始化等。但是深度学习模型的参数不仅仅只是权重与偏置,它还化等。但是深度学习模型的参数不仅仅只是权重与偏置,它还拥有许多超参数,诸如学习率、动量系数等。下一节将介绍这拥有许多超参数
10、,诸如学习率、动量系数等。下一节将介绍这些超参数的寻优算法。些超参数的寻优算法。大部分深度学习算法都包含许多超参数,从不同方面或多或少地影响着大部分深度学习算法都包含许多超参数,从不同方面或多或少地影响着算法的性能。例如,有些超参数会影响算法运行的时间和存储成本,有算法的性能。例如,有些超参数会影响算法运行的时间和存储成本,有些超参数会影响模型的质量,有些会影响推断正确结果的能力。这些超些超参数会影响模型的质量,有些会影响推断正确结果的能力。这些超参数包括前面提到的学习率(影响学习速度)、模型深度(影响模型的参数包括前面提到的学习率(影响学习速度)、模型深度(影响模型的泛化能力)等。泛化能力)
11、等。有两种选择超参数的基本方法:手动选择和自动选择。手动选择超参数有两种选择超参数的基本方法:手动选择和自动选择。手动选择超参数需要了解这些超参数是要完成什么工作,以及机器学习模型如何通过这需要了解这些超参数是要完成什么工作,以及机器学习模型如何通过这些参数才能取得良好的泛化。自动选择超参数算法可以从很大程度上减些参数才能取得良好的泛化。自动选择超参数算法可以从很大程度上减少人为工作量,但是往往需要更高的计算成本。少人为工作量,但是往往需要更高的计算成本。6-2 6-2 超参数寻优算法超参数寻优算法手动搜索超参数通常是当我们受限于运行时间和内存大小的时候采手动搜索超参数通常是当我们受限于运行时
12、间和内存大小的时候采取的最小化泛化误差的方式。在此我们不去探讨如何确定各种超参取的最小化泛化误差的方式。在此我们不去探讨如何确定各种超参数对运行时间和内存的影响,因为这高度依赖于平台硬件或网络模数对运行时间和内存的影响,因为这高度依赖于平台硬件或网络模型的框架。手动搜索超参数的主要目标是调整模型的有效容量以匹型的框架。手动搜索超参数的主要目标是调整模型的有效容量以匹配任务的复杂性。配任务的复杂性。6.2.1 6.2.1 手动超参数寻优手动超参数寻优当泛化误差是以某个超参数为变量的函数时,通常会表现为一条当泛化误差是以某个超参数为变量的函数时,通常会表现为一条U U形曲线,如图形曲线,如图6-4
13、6-4所示。在某个极端情况下,超参数对应着低容量,所示。在某个极端情况下,超参数对应着低容量,并且泛化误差由于训练误差较大而很高,如当模型的深度过低的时并且泛化误差由于训练误差较大而很高,如当模型的深度过低的时候所对应欠拟合的情况。另一种极端情况就是超参数对应着高容量,候所对应欠拟合的情况。另一种极端情况就是超参数对应着高容量,并且泛化误差由于训练误差和测试误差之间的差距较大而很高,如并且泛化误差由于训练误差和测试误差之间的差距较大而很高,如模型的深度过深,虽然模型能够很好地学习输入数据但是会发生过模型的深度过深,虽然模型能够很好地学习输入数据但是会发生过拟合。最优的模型容量应该位于这个拟合。
14、最优的模型容量应该位于这个U U型曲线中间的某个位置,能型曲线中间的某个位置,能够达到最低可能的泛化误差。够达到最低可能的泛化误差。图图6-4 6-4 超超参数与模型性能关系参数与模型性能关系并非每个超参数与损失之间的关系都能对应着完整的并非每个超参数与损失之间的关系都能对应着完整的U形曲线。很多超参数与形曲线。很多超参数与性能之间的对应是离散的,如中间层单元的数目,这种情况下只能离散地探索性能之间的对应是离散的,如中间层单元的数目,这种情况下只能离散地探索一些点的性能。有些超参数是二值化的,通常这些超参数用来指定是否使用学一些点的性能。有些超参数是二值化的,通常这些超参数用来指定是否使用学习
15、算法中的一些可选部分,如前面介绍的门控制是否参与计算的深度学习模型习算法中的一些可选部分,如前面介绍的门控制是否参与计算的深度学习模型(这些超参数只能探索曲线上的两点,即(这些超参数只能探索曲线上的两点,即“是是”=1或或“否否”=0)。还有一些超)。还有一些超参数可能会有最小值或最大值,可以限制其探索曲线的其他范围(例如权重衰参数可能会有最小值或最大值,可以限制其探索曲线的其他范围(例如权重衰减系数的最小值是减系数的最小值是0。当其为。当其为0时意味着约束项不起作用)。时意味着约束项不起作用)。手动调整超参数时不要忘记最终目标,就是提升测试集性能。加手动调整超参数时不要忘记最终目标,就是提升
16、测试集性能。加入正则化方法只是我们实现这个目标的一种方式。当然也可以通入正则化方法只是我们实现这个目标的一种方式。当然也可以通过收集更多的训练数据来减少模型的泛化误差。实践中能够确保过收集更多的训练数据来减少模型的泛化误差。实践中能够确保训练有效的训练有效的“暴力暴力”方法就是不断提高模型容量和训练集的大小,方法就是不断提高模型容量和训练集的大小,直到解决问题。但是这种做法增加了训练的计算代价,所以只有直到解决问题。但是这种做法增加了训练的计算代价,所以只有在拥有足够计算机资源时才是可行的,同时要注意数据资源的质在拥有足够计算机资源时才是可行的,同时要注意数据资源的质量。量。如前所述,当我们做
17、过相同类型的应用或具有相似网络结构建模如前所述,当我们做过相同类型的应用或具有相似网络结构建模经验的话,就可以适当地自行确定初始值和调整超参数。但现在经验的话,就可以适当地自行确定初始值和调整超参数。但现在越来越需要的是通过自动算法找到合适的超参数,因为大多数情越来越需要的是通过自动算法找到合适的超参数,因为大多数情况下已经无法手动寻找大型网络较优的初始值了。下面介绍两种况下已经无法手动寻找大型网络较优的初始值了。下面介绍两种自动超参数优化(自动超参数优化(Hyperparameter OptimizationHyperparameter Optimization)算法,分别是)算法,分别是网
18、格搜索(网格搜索(Grid SearchGrid Search)和随机搜索()和随机搜索(Random SearchRandom Search)。)。6.2.2 6.2.2 超参数寻优算法超参数寻优算法一、网格搜索算法一、网格搜索算法当有三个或更少的超参数存在时,常见的超参数搜索方法就是网当有三个或更少的超参数存在时,常见的超参数搜索方法就是网格搜索。对于每个超参数都选择一个较小的有限值集去探索,最格搜索。对于每个超参数都选择一个较小的有限值集去探索,最后挑选使验证集误差达到最小的超参数。那么应该如何选择搜索后挑选使验证集误差达到最小的超参数。那么应该如何选择搜索集合的范围呢?在超参数是数值有
19、序的情况下,每个列表中的最集合的范围呢?在超参数是数值有序的情况下,每个列表中的最小和最大元素可以先提取出来,以确保在所选范围内寻找最优解。小和最大元素可以先提取出来,以确保在所选范围内寻找最优解。通常,网格搜索会在对数尺度(通常,网格搜索会在对数尺度(Logarithmic ScaleLogarithmic Scale)下挑选合适)下挑选合适值,例如,一个学习率的取值集合可以是值,例如,一个学习率的取值集合可以是 ,或者隐藏,或者隐藏单元数目的取值集合可以为单元数目的取值集合可以为 。123410,10,10,1050,100,200,500二、随机搜索算法与网格搜索算法相比,随机搜索算法能
20、更快地收敛到超参数的较优取与网格搜索算法相比,随机搜索算法能更快地收敛到超参数的较优取值。算法如下所示。值。算法如下所示。(1)首先为每个超参数定义一个边缘分布,例如,)首先为每个超参数定义一个边缘分布,例如,Bernoulli分布或者分布或者对数尺度上的均匀分布,对应着正实值超参数。例如:对数尺度上的均匀分布,对应着正实值超参数。例如:(6-4)(6-5)其中,其中,表示区间在表示区间在 上均匀采样的样本。上均匀采样的样本。(2)然后搜索算法从联合的超参数空间中采样并运行每一个样本,逐)然后搜索算法从联合的超参数空间中采样并运行每一个样本,逐个比较目标函数值,将坏的点抛弃,保留好的点,最后便
21、得到近似的个比较目标函数值,将坏的点抛弃,保留好的点,最后便得到近似的最优解。最优解。log_(1,4)learningrateu log_10learningratelearningrate 6-3 6-3 基于梯度的自适应学习算法基于梯度的自适应学习算法通过对深度学习算法的讨论,我们可以很清楚地看出几乎所有的学通过对深度学习算法的讨论,我们可以很清楚地看出几乎所有的学习过程都离不开梯度。模型中几乎所有的权重与偏置参数的学习过习过程都离不开梯度。模型中几乎所有的权重与偏置参数的学习过程都需要梯度的参与。前面介绍的梯度下降算法,虽然是一种能让程都需要梯度的参与。前面介绍的梯度下降算法,虽然是一
22、种能让模型自动学习的方法,但又不可避免地引出了一个新的超参数,即模型自动学习的方法,但又不可避免地引出了一个新的超参数,即学习率。学习率是一个非常重要的超参数,因为它对模型的性能有学习率。学习率是一个非常重要的超参数,因为它对模型的性能有显著的影响。太小的学习率会使模型的学习缓慢,而太大的学习率显著的影响。太小的学习率会使模型的学习缓慢,而太大的学习率有可能导致跨过希望得到的较优点,如图有可能导致跨过希望得到的较优点,如图6-56-5所示,无法达到损失值所示,无法达到损失值的最小点。的最小点。损失值通常是高度敏感于参数空间中某些方向的,也就是梯度下降的方损失值通常是高度敏感于参数空间中某些方向
23、的,也就是梯度下降的方向,它不能漫无目的地迭代。虽然前面所说的带动量的梯度下降学习算向,它不能漫无目的地迭代。虽然前面所说的带动量的梯度下降学习算法可以在一定程度上缓解这些问题,但这样做的代价是引入了另一个超法可以在一定程度上缓解这些问题,但这样做的代价是引入了另一个超参数,即动量参数,这又增加了工作量。参数,即动量参数,这又增加了工作量。图图6-5 损失函数损失函数6.3.1 6.3.1 AdaGradAdaGrad算法算法AdaGrad算法流程如图算法流程如图6-6所示,学习率所示,学习率独立地应用于模型所有的参数。独立地应用于模型所有的参数。在损失函数上,拥有最大偏导数的参数相应地拥有一
24、个较大的学习率使之在损失函数上,拥有最大偏导数的参数相应地拥有一个较大的学习率使之能够快速地下降,而具有小偏导值的参数就获得一个小学习率。值得注意能够快速地下降,而具有小偏导值的参数就获得一个小学习率。值得注意的是,算法中为了数值计算的稳定增加了一个平滑值的是,算法中为了数值计算的稳定增加了一个平滑值。该参数避免了计算。该参数避免了计算过程中分母可能为零的情况发生。过程中分母可能为零的情况发生。图图6-6 AdaGrad算法流程算法流程RMSProp算法优化了算法优化了AdaGrad,改变梯度积累为指数加权的移动平均。,改变梯度积累为指数加权的移动平均。AdaGrad旨在应用于凸问题时快速收敛
25、(关于凸优化的知识超出了本书的范围,读旨在应用于凸问题时快速收敛(关于凸优化的知识超出了本书的范围,读者可以参考凸优化的相关书籍)。者可以参考凸优化的相关书籍)。AdaGrad根据平方梯度的整个历史收缩学根据平方梯度的整个历史收缩学习率,会使得学习率在达到较优结果前就变得太小了。而习率,会使得学习率在达到较优结果前就变得太小了。而RMSProp使用指数使用指数衰减平均以丢弃遥远过去的历史值,从而避免了过大衰减的问题,使其能够衰减平均以丢弃遥远过去的历史值,从而避免了过大衰减的问题,使其能够找到较优值,并且快速收敛。找到较优值,并且快速收敛。RMSProp的标准算法形式如图的标准算法形式如图6-
26、7所示,结合了所示,结合了Nesterov动量的算法形式如图动量的算法形式如图6-8所示。相比于所示。相比于AdaGrad,RMSProp引入了一个新的超参数引入了一个新的超参数,用来控制指数,用来控制指数衰减的程度。结合了衰减的程度。结合了Nesterov动量的动量的RMSProp算法对梯度计算了指数衰减平算法对梯度计算了指数衰减平均。这种做法有利于进一步消除摆动幅度大的方向,用来修正摆动幅度,使均。这种做法有利于进一步消除摆动幅度大的方向,用来修正摆动幅度,使得各个维度的摆动幅度都较小,进而使得网络函数收敛更快。得各个维度的摆动幅度都较小,进而使得网络函数收敛更快。6.3.2 AMSPro
27、p6.3.2 AMSProp算法算法图图6-7 标准标准RMSProp算法流程算法流程图图6-8 含动量含动量RMSProp算法流程算法流程6.3.4 Adam6.3.4 Adam算法算法AdamAdam是另一种学习率自适应优化算法。是另一种学习率自适应优化算法。“Adam”Adam”这个名字来自于这个名字来自于“Adaptive Moments”Adaptive Moments”。AdamAdam优化算法是随机梯度下降算法的扩展,优化算法是随机梯度下降算法的扩展,广泛用于深度学习,尤其是计算机视觉和自然语言处理等任务。广泛用于深度学习,尤其是计算机视觉和自然语言处理等任务。AdamAdam算
28、法和传统的随机梯度下降不同。随机梯度下降利用单一的学习算法和传统的随机梯度下降不同。随机梯度下降利用单一的学习率更新所有的权重,学习率在训练过程中并不会改变。而率更新所有的权重,学习率在训练过程中并不会改变。而AdamAdam通过计通过计算梯度的一阶矩估计和二阶矩估计为不同的参数设计独立的自适应学算梯度的一阶矩估计和二阶矩估计为不同的参数设计独立的自适应学习率。习率。图图6-9 Adma算法流程算法流程Adam算法具有如下优点:算法具有如下优点:为每一个参数保留了一个学习率来提升在稀疏梯度(即自然语为每一个参数保留了一个学习率来提升在稀疏梯度(即自然语言和计算机视觉问题)上的性能;言和计算机视
29、觉问题)上的性能;基于权重梯度最近量级的均值为每一个参数适应性地保留学习基于权重梯度最近量级的均值为每一个参数适应性地保留学习率(避免了率(避免了AdaGrad的过度收缩),在非稳态问题上有着较优秀的的过度收缩),在非稳态问题上有着较优秀的性能。性能。总的来说,总的来说,Adma综合了综合了AdaGrad与与RMSProp的优点,并在实际的的优点,并在实际的工程应用中表现出了不错的性能。工程应用中表现出了不错的性能。前面已经提到,循环性状态前面已经提到,循环性状态h h在时间上向前传播信息,而循环性状态在时间上向前传播信息,而循环性状态g g在时间上向后传播信息。因此在每个时间步在时间上向后传
30、播信息。因此在每个时间步t t,输出单元,输出单元o o(t)(t)都可以接都可以接收到输入收到输入h h(t)(t)中关于过去的相关信息以及输入中关于过去的相关信息以及输入g g(t)(t)中所包括的关于未来中所包括的关于未来的相关要素。的相关要素。值得注意的是,虽然我们一直使用时间步来进行说明,但是值得注意的是,虽然我们一直使用时间步来进行说明,但是RNNRNN也可也可以应用于非时间序列的序列数据,此时时间步索引就变成了序列数据以应用于非时间序列的序列数据,此时时间步索引就变成了序列数据的位置索引。例如,上述的双向的位置索引。例如,上述的双向RNNRNN也可以应用于处理图像数据:由也可以应
31、用于处理图像数据:由四个四个RNNRNN组成,每一个网络沿着四个方向中的一个计算:上、下、左组成,每一个网络沿着四个方向中的一个计算:上、下、左、右。相比卷积网络,应用于图像的、右。相比卷积网络,应用于图像的RNNRNN计算成本通常更高,但允许计算成本通常更高,但允许同一特征图的特征之间存在长期横向的相互作用。同一特征图的特征之间存在长期横向的相互作用。6-4 6-4 生成对抗神经网络生成对抗神经网络GANGAN及实例及实例实验中我们发现,当在识别精度达到人类水平的神经网络上有意地在样实验中我们发现,当在识别精度达到人类水平的神经网络上有意地在样本中增加人类难以被干扰(或人类难以发现变化)的数
32、据时,网络的误本中增加人类难以被干扰(或人类难以发现变化)的数据时,网络的误差率可以接近差率可以接近100%100%。简单来说就是有意地在原始数据中稍微增加些扰动,。简单来说就是有意地在原始数据中稍微增加些扰动,从人类角度来看并不会对分类结果产生影响,但是对于深度学习来说却从人类角度来看并不会对分类结果产生影响,但是对于深度学习来说却是一个致命的问题。这种稍微增加了扰动的样本,我们称之为对抗样本是一个致命的问题。这种稍微增加了扰动的样本,我们称之为对抗样本(Adversarial ExampleAdversarial Example)如图如图6-106-10所示,人类实际上很难通过眼睛识别出原
33、始图像和对抗样本图所示,人类实际上很难通过眼睛识别出原始图像和对抗样本图像之间区别的。但是对抗样本是给原始图像增加了微小扰动的图像后得像之间区别的。但是对抗样本是给原始图像增加了微小扰动的图像后得到的,因此在训练网络时,原始图像和对抗样本的数值是明显不同的。到的,因此在训练网络时,原始图像和对抗样本的数值是明显不同的。图图6-10 对抗样本生成与分类结果对抗样本生成与分类结果抽象地讲,模型在对抗样本图像上某点的输出与原始图像同一点的输出抽象地讲,模型在对抗样本图像上某点的输出与原始图像同一点的输出可能具有很大的差异。但是在许多情况下,人类通过肉眼难以察觉到差可能具有很大的差异。但是在许多情况下
34、,人类通过肉眼难以察觉到差异,而网络却会作出非常不同的预测异,而网络却会作出非常不同的预测。如何实现对抗训练呢,就是使用生成对抗神经网络(如何实现对抗训练呢,就是使用生成对抗神经网络(Generative Adversarial Networks,GAN)。生成对抗网络分为如下两步:)。生成对抗网络分为如下两步:生成模型;生成模型;鉴别模型。鉴别模型。原理如图原理如图6.11所示,生成模型从无到有地不断生成数据,而鉴别模型所示,生成模型从无到有地不断生成数据,而鉴别模型不断地鉴别输入进来的究竟是生成模型产生的数据还是原始数据,两不断地鉴别输入进来的究竟是生成模型产生的数据还是原始数据,两者不断
35、产生对抗。生成模型努力生成不让鉴别模型可以识别出来的数者不断产生对抗。生成模型努力生成不让鉴别模型可以识别出来的数据,而鉴别模型则尽力地鉴别数据的来源,二者不断成长,从而得到据,而鉴别模型则尽力地鉴别数据的来源,二者不断成长,从而得到最好的生成模型和鉴别模型。生成对抗神经网络最好的生成模型和鉴别模型。生成对抗神经网络GAN是从学习数据是从学习数据的分布出发,最终得到两个一样的数据分布模型,。的分布出发,最终得到两个一样的数据分布模型,。图图6-11生成对抗网络原理生成对抗网络原理我们希望鉴别模型能判断出输入样本是否来自于真实的原始数据。如果来我们希望鉴别模型能判断出输入样本是否来自于真实的原始
36、数据。如果来自于真实数据则模型输出自于真实数据则模型输出1,否则输出为,否则输出为0。可以将鉴别模型定义为:。可以将鉴别模型定义为:(6-6)这里,将原始数据的数学分布定义为这里,将原始数据的数学分布定义为,而,而 为输入为输入 判断为真实样本的概率。判断为真实样本的概率。这样我们就证明了生成对抗神经网络的理论可行性。这样我们就证明了生成对抗神经网络的理论可行性。下面通过下面通过TensorFlow来实现来实现GAN,我们还是使用手写数字数据集进行训练。,我们还是使用手写数字数据集进行训练。#导入导入tensorflowimport tensorflow as tf#导入手写数字数据集导入手写
37、数字数据集from tensorflow.examples.tutorials.mnist import input_data#导入导入numpyimport numpy as np#plt是绘图工具,在训练过程中用于输出可视化结果是绘图工具,在训练过程中用于输出可视化结果import matplotlib.pyplot as plt#gridspec是图片排列工具,在训练过程中用于输出可视化结果是图片排列工具,在训练过程中用于输出可视化结果import matplotlib.gridspec as gridspec#导入导入osimport os#保存模型的保存模型的save函数函数def
38、save(saver,sess,logdir,step):#模型名前缀模型名前缀model_name=model#保存路径保存路径 checkpoint_path=os.path.join(logdir,model_name)#保存模型保存模型 saver.save(sess,checkpoint_path,global_step=step)print(The checkpoint has been created.)#初始化参数时使用的初始化参数时使用的xavier_init函数函数def xavier_init(size):in_dim=size0#X表示真的样本表示真的样本(即真实的手写
39、数字即真实的手写数字)X=tf.placeholder(tf.float32,shape=None,784)#表示使用表示使用xavier方式初始化的判别器的方式初始化的判别器的D_W1参数,是一个参数,是一个784行行128列列的矩阵的矩阵D_W1=tf.Variable(xavier_init(784,128)#表示全零方式初始化的判别器的表示全零方式初始化的判别器的D_1参数,是一个长度为参数,是一个长度为128的向量的向量D_b1=tf.Variable(tf.zeros(shape=128)#表示使用表示使用xavier方式初始化的判别器的方式初始化的判别器的D_W2参数,是一个参数
40、,是一个128行行1列的列的矩阵矩阵D_W2=tf.Variable(xavier_init(128,1)#表示全零方式初始化的判别器的表示全零方式初始化的判别器的D_1参数,是一个长度为参数,是一个长度为1的向量的向量D_b2=tf.Variable(tf.zeros(shape=1)#theta_D表示判别器的可训练参数集合表示判别器的可训练参数集合theta_D=D_W1,D_W2,D_b1,D_b2#Z表示生成器的输入表示生成器的输入(在这里是噪声在这里是噪声),是一个,是一个N列列100行的矩阵行的矩阵Z=tf.placeholder(tf.float32,shape=None,10
41、0)#表示使用表示使用xavier方式初始化的生成器的方式初始化的生成器的G_W1参数,是一个参数,是一个100行行128列的列的矩阵矩阵G_W1=tf.Variable(xavier_init(100,128)#表示全零方式初始化的生成器的表示全零方式初始化的生成器的G_b1参数,是一个长度为参数,是一个长度为128的向量的向量G_b1=tf.Variable(tf.zeros(shape=128)#表示使用表示使用xavier方式初始化的生成器的方式初始化的生成器的G_W2参数,是一个参数,是一个128行行784列的列的矩阵矩阵G_W2=tf.Variable(xavier_init(12
42、8,784)#表示全零方式初始化的生成器的表示全零方式初始化的生成器的G_b2参数,是一个长度为参数,是一个长度为784的向量的向量G_b2=tf.Variable(tf.zeros(shape=784)#theta_G表示生成器的可训练参数集合表示生成器的可训练参数集合theta_G=G_W1,G_W2,G_b1,G_b2#生成维度为生成维度为m,n的随机噪声作为生成器的随机噪声作为生成器G的输入的输入def sample_Z(m,n):return np.random.uniform(-1.,1.,size=m,n)#生成器,生成器,z的维度为的维度为N,100def generator(
43、z):#输入的随机噪声乘以输入的随机噪声乘以G_W1矩阵加上偏置矩阵加上偏置G_b1,G_h1维度为维度为N,128G_h1=tf.nn.relu(tf.matmul(z,G_W1)+G_b1)#G_h1乘以乘以G_W2矩阵加上偏置矩阵加上偏置G_b2,G_log_prob维度为维度为N,784 G_log_prob=tf.matmul(G_h1,G_W2)+G_b2#G_log_prob经过一个经过一个sigmoid函数,函数,G_prob维度为维度为N,784G_prob=tf.nn.sigmoid(G_log_prob)#返回返回G_prob return G_prob#判别器,判别器,
44、x的维度为的维度为N,784def discriminator(x):#输入乘以输入乘以D_W1矩阵加上偏置矩阵加上偏置D_b1,D_h1维度为维度为N,128D_h1=tf.nn.relu(tf.matmul(x,D_W1)+D_b1)#D_h1乘以乘以D_W2矩阵加上偏置矩阵加上偏置D_b2,D_logit维度为维度为N,1 D_logit=tf.matmul(D_h1,D_W2)+D_b2#D_logit经过一个经过一个sigmoid函数,函数,D_prob维度为维度为N,1 D_prob=tf.nn.sigmoid(D_logit)#返回返回D_prob,D_logit return
45、D_prob,D_logit#保存图片时使用的保存图片时使用的plot函数函数def plot(samples):#初始化一个初始化一个4行行4列包含列包含16张子图像的图片张子图像的图片fig=plt.figure(figsize=(4,4)#调整子图的位置调整子图的位置 gs=gridspec.GridSpec(4,4)#设置子图间的间距设置子图间的间距 gs.update(wspace=0.05,hspace=0.05)#依次将依次将16张子图填充进需要保存的图像张子图填充进需要保存的图像 for i,sample in enumerate(samples):ax=plt.subplot
46、(gsi)plt.axis(off)ax.set_xticklabels()ax.set_yticklabels()ax.set_aspect(equal)plt.imshow(sample.reshape(28,28),cmap=Greys_r)return fig#取得生成器的生成取得生成器的生成结果结果 G_sample=generator(Z)#取得判别器判别的真实手写数字的结果取得判别器判别的真实手写数字的结果D_real,D_logit_real=discriminator(X)#取得判别器判别的生成的手写数字的结果取得判别器判别的生成的手写数字的结果D_fake,D_logit_
47、fake=discriminator(G_sample)D_loss_real=#对判别器对真实样本的判别结果计算误差对判别器对真实样本的判别结果计算误差(将结果与将结果与1比较比较)tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(logits=D_logit_real,labels=tf.ones_like(D_logit_real)#对判别器对虚假样本对判别器对虚假样本(即生成器生成的手写数字即生成器生成的手写数字)的判别结果计算误差的判别结果计算误差(将结果将结果与与0比较比较)D_loss_fake=tf.reduce_me
48、an(tf.nn.sigmoid_cross_entropy_with_logits(logits=D_logit_fake,labels=tf.zeros_like(D_logit_fake)#判别器的误差判别器的误差D_loss=D_loss_real+D_loss_fake#生成器的误差生成器的误差(将判别器返回的对虚假样本的判别结果与将判别器返回的对虚假样本的判别结果与1比较比较)G_loss=tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(logits=D_logit_fake,labels=tf.ones_like(D_
49、logit_fake)#记录判别器判别真实样本的误差记录判别器判别真实样本的误差dreal_loss_sum=tf.summary.scalar(dreal_loss,D_loss_real)#记录判别器判别虚假样本的误差记录判别器判别虚假样本的误差dfake_loss_sum=tf.summary.scalar(dfake_loss,D_loss_fake)#记录判别器的误差记录判别器的误差d_loss_sum=tf.summary.scalar(d_loss,D_loss)#记录生成器的误差记录生成器的误差g_loss_sum=tf.summary.scalar(g_loss,G_loss
50、)#日志记录器日志记录器summary_writer=tf.summary.FileWriter(snapshots/,graph=tf.get_default_graph()最后得到了它的损失图像如图最后得到了它的损失图像如图6-12所示所示。图图6-12 GAN训练图像训练图像迁移学习(迁移学习(Transfer LearningTransfer Learning)是指利用一个情景中已经学到)是指利用一个情景中已经学到的内容去改善另一个情景中的泛化情况。的内容去改善另一个情景中的泛化情况。我们可以利用自己的学习经历去理解迁移学习。在我们学习了许我们可以利用自己的学习经历去理解迁移学习。在我
侵权处理QQ:3464097650--上传资料QQ:3464097650
【声明】本站为“文档C2C交易模式”,即用户上传的文档直接卖给(下载)用户,本站只是网络空间服务平台,本站所有原创文档下载所得归上传人所有,如您发现上传作品侵犯了您的版权,请立刻联系我们并提供证据,我们将在3个工作日内予以改正。