吴恩达深度学习(六)

超参数调整

第一课:调整过程

调整神经网络的过程包含了对许多不同超参数的设置,那么怎么样为这些参数找到比较合适的设定值呢?

准则和系统化进行超参数设置的技巧将帮助你更加快速有效的获得合适的超参数。

在深度神经网络训练中,面对大量的超参数,包括学习速率α、动量超参数β1、Adam优化算法中的超参数β2和ε、网络层数以及每层网络中隐藏单元的数量、学习率衰减情况下不可能只有单一的学习率、mini-batch的大小等。

根据我的实践经验,一部分超参数比其他的更加重要。对于大多数的学习算法,学习速率α是需要调优的超参数中最重要的一个,没有之一。
除了学习速率α,我接下来需要调整的参数也许是动量项,β1 = 0.9或许是一个不错的默认值。接下来是mini-batch的大小,来保证最优化算法的运行效率。调试隐藏单元数量。这三个是我认为重要性仅次于学习速率α的超参数。
调整完这些超参数后,接下来是重要性排在第三的超参数,网路层数有时候对结果起重要作用,学习衰减率也一样。

此外,当使用Adam算法时,我几乎不调节β1、β2和ε,几乎都是使用默认参数0.9、0.999和10^-8。

以上就是对超参数重要性的排序。

如果你要调整超参数,怎么选择这些值的组合呢?

在早起的机器学习算法中,人们对超参数比较少的系统进行网格取点,然后系统化的尝试这些点所代表的值,然后选择最优的超参数。
但是在深度学习中,参数非常多,所以建议在网格中进行随机取样。在这些随机选取的点中,尝试所有的超参数。
这样做的原因是:事先你很难知道在你的问题中,哪个超参数是最重要的,所以随机取样会放大你的取样深度。
实际上,你会遇到非常多的超参数,比如超参数为3时,你需要通过在三维立方体中抽样,就会需要尝试更多三个超参数的组合值。

所以事先知道哪个超参数对你的模型最重要,在不知道的前提下,使用随机取样而不是在网格中规则取样,将帮助你更充分的为最重要的超参数尝试尽可能多的值的组合。

当你对超参数进行取样时,另一种常见的方法就是使用区域定位的抽样方案。即如果发现表现比较好的点,可以对这些点所在的区域进行限定,然后在这个区域内进行密度更高的抽样,或者依然选择随机取样,但是需要把更多的资源集中在蓝色方块中进行搜索。(前提是你大体能确定这个区域内的值能产生最优结果)

即在对整个框选范围进行粗略的抽样后,结果会引导你集中在一个更小的区域内,然后你可以在更小的方块中,进行更密集的抽样。

接下来你可以选择最优的超参数值,使训练集或者开发集有最理想的结果。或者在超参数搜寻过程中,实现你希望获得的其他优化结果。

总结:
使用随机取样,而不是规则取样
使用区域定位的搜索过程

第二课:使用适当的比例来选择超参数

超参数值域的随机取样能让你有效的搜索超参数空间,但实际上,随机抽样并不意味着是在有效值的范围内的均匀随机抽样,相反,更重要的是选取适当的尺度用以研究这些超参数。

假设你要选择第l层隐藏单元的个数n[l],均匀随机抽样好像都是合理的方案。但它并不是对所有的超参数都适用。

在学习速率α的选择过程中,更合理的方法似乎应该是以对数尺度来搜索,而不是用线性尺度。

通过在对数尺度上均匀随机取样,你可以有更多的资源致力于搜索0.001-0.1范围之间的数值。即一般而言,如果你要在10^ a -10^ b的范围内取样,你可以用基于10的对数计算a和b,然后a~b的范围内均匀随机取样。

整理:要基于对数尺度取样,首先取得下限值,取其对数得到a,再取上限值,取其对数得到b,然后在对数尺度10^ a -10^ b范围内取样,即在a~b的范围内均匀随机取r值,最后得到超参数值为10^r,这就是在对数尺度上取样方法的实现。

最后一个棘手的问题就是超参数β的取样,β用于计算指数加权平均值,假设你要搜索的值空间是0.9-0.999,要记住的是,用0.9计算指数加权平均值,相当于计算最后10个值的平均值,而使用0.999就相当于计算1000个值的平均值。在0.9-0.999之间使用线性尺度的均匀的随机的取样是没有意义的,考虑这个问题的最好方法是将这个范围扩展至1-β,得到0.1-0.001的范围,现在运用我们之前学到的方法,进行对数变换以后,即在-3~-1的范围内云均匀随机取样,就得到了超参数在适当尺度上的随机取样值。

从数学的角度考虑为什么线性尺度取样是个坏主意?
因为随着β趋近于1,其结果对于β的改变非常敏感,即使是对β非常小的改变,如果β从0.9变成0.9005,其结果变化不大,但是如果是从0.999变成0.9995,将会对你正在运行的算法产生巨大的影响。

那么上述整个取样过程中所做的就是使你在β趋近于1的区域内以更大的密度取样,也就是在1-β趋近于0的时候,因此你能够得到更高效的样本分布,即在搜索可能的超参数空间时更有效率。

第三课:超参数在实践中调整:熊猫与鱼子酱

在对超参数探寻的各种方式进行总结之前,分享一些关于如何有规划的探寻超参数的小技巧。

关于如何探寻超参数的问题,有两种主流思想:
1.你精心照料的一个单一模型,通常你需要处理一个非常庞大的数据集,但是没有充足的计算资源,比如没有很多的CPU/GPU,那么你一次只能训练一个或者非常少量的模型,这种情况下,即使非常枯燥的训练你也要盯着,你每天都照看你的模型,尝试微调参数。即照看模型观察性能曲线耐心的微调学习率,这通常发生在你没有足够的计算资源,同时训练几个模型的情况下

2.并行训练多个模型。你可能设置好模型的超参数以后,让模型自己运行一天或者几天,得到代价函数或者损失函数的曲线,于此同时,你可能会运行另一个不同的模型,第二个模型可能会反馈一条不同的学习曲线,或者同时第三个...模型,得到相应的曲线。
用这样的方式,你就可以尝试不同的超参数设置,这可以让超参数选择变得简单,只要最终找到一个最好的结果就行了。

熊猫产子-熊猫模式
鱼类产子-鱼子酱模式

那么如何挑选适合你的模式呢?这取决于你有多少的计算资源?

如果你有足够的计算机来并行训练很多模型,就选择鱼子酱模式,但是在某些应用领域,例如在线广告设置以及计算机识别领域,有海量的数据和大量模型需要去训练,而同时训练大量模型是极其困难的事情。

现在有一种技术,可以让你的神经网络对于超参数的选择不再那么敏感?这可能无法普及所有的神经网络,但是一旦奏效,能够让超参数探寻变得更加容易,也可以让训练过程缩短许多,下节课见。

批量标准化

第四课:规范化网络中的激活

在深度学习的崛起过程中,最重要的创新之一是一种叫批量归一化的算法,可以让你的超参数搜索过程变得很简单,让你的神经网络变得更加有鲁棒性,可以让你的神经网络对于超参数的选择上不再那么敏感,而且可以让你更容易地训练非常深的网络。

让我们来看看批量归一化是如何工作的?
还记得当训练一个模型比如说是逻辑回归模型时,对输入特征进行归一化可以加速学习过程,这意味着计算平均值,用训练集减去平均值,计算方差,求x[i]的平方和(元素相乘的平方),然后用方差来归一化你的数据集。这些操作会让你的机器学习模型从扁的变得更圆些,从而便于梯度下降算法。

所以对于神经网络或者逻辑回归针对输入值的归一化处理是有用的,对于层数更多的模型呢?

对于一个多层神经网络系统,除非你能对a[2]进行标准差归一化,否则对于w[3] b[3]的训练都不会太有效率,在逻辑回归中我们发现对x1 x2 x3做归一化处理对w和b的训练更有效,所以对于一个多层神经网络,对于任何一个隐藏层我们是否也可以对a值作归一化呢?这就是batch norm。实际上,对z[2]做归一化要普遍的多,而不是a[2],所以我们也应该把归一化z[2]作为默认用法。

如何实现batch norm?

假设有一些神经网络的中间值,隐藏单元z(1)到z(m),这些来自于同一个隐藏层,当给你这些值时,你要做的是计算平均值,然后计算方差,然后针对每一个z(i)去归一化,就是把z值减去均值,然后除以标准差,这样我们就把z标准化为一组均值0方差1的值了。每一组z都是均值0方差1,但是我们并不希望所有的隐藏单元都是这样的,也许本身它们的分布就有所不同,所以我们使用一个新公式:

这里的γ和β可以从你的模型中学习,这样我们就可以使用梯度下降算法或者其他类似算法,比如momentum的梯度下降算法或者atom算法更新γ和β,就像更新神经网络的权重一样。

即归一化就是通过左边的四个方程,选择不同的γ和β可以让隐藏单元呈现不同的分布。把这个方法运用到你的神经网络中就是在你使用z[1]、z[2]...等时,你换成z(波浪线)代替z[i],再进行接下来的计算。

总结:如何对输入特征X做归一化来帮助神经网络的训练,以及batcn norm所做的就是不仅仅在输入层,而且在一些隐藏层上也作归一化,你使用这种归一化的方法,对某些隐藏单元的值z作归一化,但是隐藏层和输入层的归一化还有一点不同,就是隐藏层归一化后并不一定是均值0方差1。比如对于sigmoid函数,你就不希望归一化的值都聚集在零点附近,而是希望它们可以有更高的方差,以便于更好的利用sigmoid函数非线性的特点。

这就是为什么要设置γ和β,你可以控制z(i)在你希望的范围内,或者说它真正实现的是通过两个参数γ和β来让你的隐藏单元有可控的方差和均值。这两个参数可以在算法中自由设置。目的就是可以得到一些修正的均值和方差,这意味着可以是均值0方差1,也可以是被参数γ和β控制的其他值。

如何在神经网络包括深度神经网络中使用batch norm?以及如何用数据训练它?以及如何使它在不同的层都能起作用?

第五课:将批量规范拟合到神经网络中

我们已经知道了单隐藏层的batch norm公式,那么如何在深度神经网络中使用它?

如果我们在深度神经网络中使用batch norm,我们让输入x进入到第一级隐藏层,得到z[1],然后通过batch norm得到z1,然后让gl函数作用于z1,就完成了第一层的计算。在此,BN算法确实被应用于由z到a的计算过程中,下一步通过a[1]计算z[2],与第一层类似,通过BN算法得到z2,以此类推...

直觉是不使用未归一化的z值而是使用归一化的(带波浪号)的z值。所以新网络中的新参数是γ[1]和β[1]、γ[2]和β[2]、γ[3]和β[3]...对每个采用BN算法的网络层都是如此。

注意:BN算法中学习参数β不同于Adam、RMSprop和Momentum算法中使用的超参数β。

得到新参数以后,我们可以根据需求进行优化,例如采用梯度递减的方法来实现它。

BN算法的效果是计算平均值和方差,并把它们减去和除去,如果你正在使用深度学习编程框架,通常你不必自己去实现BN算法,在变成框架中,它也许仅仅是一行代码。即实际上,你不可能自己去实现这些细节,了解它怎么工作就可以了,这有助于我们理解自己的代码。

到目前为止,我们已经讲过了在整个训练集上利用批量梯度下降训练的BN算法。实际上,通常应用到训练集上的是少批量BN算法。

即在第一个mini-batch上进行BN算法的梯度下降,然后转到第二个mini-batch上,我们会用第二个mini-batch中的数据来归一化(带波浪号的)z。

关于参数的一个细节:

我曾经说过每一层的参数w[l],b[l]以及γ[l]和β[l]。BN算法所做的就是使用mini-batch并且归一化zl来满足均值为0以及标准方差,然后通过γ和β重新调整。这意味着,不管bl的值为多少,实际上都要被减去,因为经过BN这一步,我们将计算zl的均值并将其减去,所以在mini-batch中对所有例子加上一个常量,并不会改变什么,因为无论我们加上什么常量他都会通过-减均值-这一步去除。
所以如果你使用BN算法,你可以忽略该参数b或者认为它永远等于0。我们在此基础上进行z[l](带波浪号)的计算。

总结:因为BN算法使层级中各个z[l]的均值为0,我们没有理由保留参数b[l],就可以把它忽略,相应地被β[l]所代替。β[l]:一个用来控制最终偏移量影响的参数。

最后,z[l]的维度应该是nLx1,那么b[l]的维度也是nLx1,假设n[l]为L层中隐藏单元数,β[l]和γ[l]的维度也是n^Lx1,就等于隐藏单元数,它应用于调整每一个隐藏单元的值和方差,这是由网络决定的。

汇总一下并且总结如何实现梯度BN算法:
假设我们使用mini-batch梯度下降算法,枚举从t等于1直到mini-batch数,在mini-batch(Xt)上计算前向传播,然后在每一层上计算前向传播,使用BN算法,用(带波浪号的)z[l]代替z[l],即利用mini-batch算法z值会进行归一化均值和方差处理,这个经历归一化均值和方差的值就是带波浪的z[l],然后利用反向传播计算dw、db以及所有L层的值dγ和dβ,并且在技术层面上我们已经忽略了b,但是它没有最终消除,最终我们更新了所有参数。

这就是梯度下降算法,它同样适用于Momentum或RMSprop或Adam的梯度下降算法。它们采用的梯度下降算法同样可用于更新新增参数γ和β。

如果你正在使用某种深度学习编程框架,希望你能调用框架中的方法,来轻松实现BN算法。

它为什么提高训练速度?

第六课:为什么Batch Norm有效?

其中一个理由是我们看到经过归一化的输入特征(X),它们的均值为0,方差为1,这将大幅加快学习过程,所以与其含有某些在0到1范围内变动的特征,或在1到1000范围内变动的特征,通过归一化所有输入特征X,让它们都拥有相同的变化范围将加速学习。
因此,BN算法有效的一个原因是:它同样是通过归一化,只不过它应用于隐藏层的值而不是这里的输入特征。

以上只是BN算法的一部分,还有很多关于BN算法的进一步解释,这将有助于我们更深一层的理解BN算法:

BN算法有效的第二个原因是:
它产生权重(w参数)在深度神经网络中,假设在10层中的参数w比神经网络初始的层级,假设为0层更具有鲁棒性。

当我们的数据随着某种东西在变化时,也就是协变量。即我们学习了某种x-y映射,如果x的分布变化了,那么我们就得重新训练学习算法,尽管x-y映射的真函数没有变,比如下图中的黑猫变成了彩猫:

那么,协变量是如何影响神经网络的呢?
从第三级隐藏层的角度来看,这些隐藏单元值一直在变,所以它受协变量问题影响。而BN算法做的就是:它减少了这些隐藏单元值的分布不稳定性。
假设我们想画出这些隐藏单元值的分布,技术上讲就是归一化的z, z21和z22的值可以变化,当神经网络刷新前几层参数时,它们的确会变化,但是BN算法就是确保的是无论它怎么变,z12和z22的均值和方差始终不变。即限制了先前层参数的更新,对第三层,即现在看到和要学习的值的分布的影响。

所以BN算法减少输入值变化所产生的问题,它的确使这些值变得稳定,所以神经网络的后层可以有更稳固的基础,尽管输入分布变化了一点,它变化的更少,实际是尽管前几层继续学习,后面层适应前面层变化的力量被削弱。即如果我们愿意,BN算法削弱了前面层参数和后面层参数之间的耦合,所以它允许网络的每一层独立学习,有一点独立于其它层的意思,所以这将有效提升整个网络学习速度。

结论:BN算法意味着,尤其是从神经网络某一后层角度来看,前面层的影响不会很大,因为它们被同一均值和方差所限制,所以这使后层的学习工作变得更加简单。

BN算法还有第二个效果:它具有轻微的正则化效果,mini-batch是BN算法中一个模糊的概念。例如mini-batch中的X{t}拥有值z{t}还有值z[l],均值和方差已经在该mini-batch上归一化过了,现在因为我们在该mini-batch上计算了均值和方差,而不是在整个数据集上计算,所以该均值和方差包含有噪声,因为这仅仅是在mini-batch上计算得到的,所以均值和方差都有噪声,因为它是由相对较少的数据集评估得来该归一化过程,从z[l]到(带波浪号的)z[l],这个过程也会产生噪声,因为它是用带有一定噪声的均值和方差来计算的。

所以和dropout算法类似,它会为每个隐藏层的激活函数增加一些噪声,dropout有噪声的原因是它将隐藏单元以一定概率乘以0,以一定概率乘以1,所以dropout算法有很多噪声是因为它要么乘以0要么乘以1,然而BN算法有许多噪声是因为被标准方差归一化了,此外,因为减去均值BN算法还有附加噪声,均值和标准方差的评估值都含有噪声,所以和dropout算法类似,BN算法因此具有轻微的正则化效果,通过在隐藏层单元增加噪声,它使后续的隐藏单元不要过度依赖其他隐藏单元,这就增加了隐藏层噪声,具有轻微的正则化效果。
因为加入的噪声太小,这没有强大的正则化效果,那么我们会选择BN算法和dropout算法一起使用,如果你想获得更强大的正则化效果的话。

如果你使用更大的mini-batch尺寸,我们可以减少噪声同时减少正则化效果,所以dropout算法的一个奇怪特性:使用更大的mini-batch尺寸,将会削弱正则化效果。

虽然正则化不是我们想要的效果,但是它对我们的学习算法有着额外的有意或无意的影响,但是一定不要把BN算法看作是正则化方法,而是把它当做是归一化隐藏单元激活函数用来加速学习的方法,正则化效果只是一种无意的副作用。

细节:在BN算法中,一个mini-batch处理一次数据,在该mini-batch上计算均值和方差,在测试时,当你尝试做出预测和评估神经网络时,你可能没有包含多个例子的mini-batch,你可能每次只处理一个例子,所以在测试时你要做出一点变化来确保你的测试准确。

第七课:在测试时进行batch norm

批量标准化每次只处理一个最小批的数据,但是在测试时你大概需要一个一个实例处理,如何修改神经网络实现这一功能?

注意上图中,我们计算缩放比例和所需要的u和σ的平方是在整个最小批上计算的,但是在测试时你可能没有一个最小批实例来同时处理,所以你需要一种不同的方式来获得u和σ的平方,如果你只有一个实例,那么计算这个这一个实例的平均值和标准差显然是不合理的。

那么实际上应该怎么做呢?以便于我们在测试时使用我们的神经网络?我们需要一种单独的方式来估算u和σ的平方。

通常情况下,我们是通过指数加权平均数来估算的。这个平均数是根据最小批来计算的。

也就是说我们用不同的最小批来训练神经网络时,我们会保持一个移动均值来记录每一层的u和σ的平方,最后在测试时,我们不用这些公式来计算znorm,而是用我们当前的z值和之前训练时最新的u和σ的平方的指数加权平均数来进行比例缩放。

所以,在训练时,我们是用整个最小批比方说64个或者128个或者其他数量的训练实例,来计算u和σ的平方,但是在测试时,我们可能会需要处理单个测试实例,那么处理的方式就是通过训练集来估算u和σ的平方。理论上,我们可以用我们最后的网络运行整个训练集,来得到u和σ的平方,但是实际上,人们通常会实现某种指数加权平均来记住训练时见到的u和σ的平方的值。然后用这个指数加权平均数,有时也被称为移动均值,来得到u和σ的平方的粗略的估算。然后我们用这些u和σ的平方的估算值在测试时进行比例缩放来获取隐藏神经元的z值。

实际上,对于你具体如何估算u和σ的平方,这个过程是比较鲁棒的,所以我不太会担心你具体怎么做,而且如果你使用一个深度学习框架,它们通常会有一些默认的方式来估算u和σ的平方,这些方式一般效果也会较好。
但是实际上,任何合理的方式来估算隐藏神经元的均值和方差,应该在测试时都是效果可以的。

应用批量标准化,我相信你们可以训练更深的神经网络,并且让你们的算法运行的更快。

第八课:Softmax回归

到目前为止,我们所讨论的分类示例使用了二进制分类,其中有两个可能的标签,0或1,即它是猫吗,它不是猫吗?如果我们有多个可能的结果怎么办?

Logistic回归的推广被称为Softmax回归。

所以我们将使用一些缩写:
使用大写C来表示你将要预测的总的类别数。

在这种情况下,我们就需要构建一个新的神经网络,其中输出层是4个,或者说有C个输出单元,即输出层L的单元数N等于4。我们想得到的是每个输出层单元告诉我们得到每个类别的概率。所以这里的输出层y帽就是一个4*1维度的向量,由于输出的概率之和应该等于1。

标准化的做法就是使你的神经网络使用这里的softmax层以及生成输出层。

首先和之前一样,计算每层的线性部分,计算出z以后,需要把这个softmax激活函数用起来,这个激活函数和sofrmax层有一点不同:

首先,我们计算一个临时的值t(对所有元素求幂),t是一个4*1的向量,这个输出层基本上就是t,但是需要进行归一化到1,计算可以得到a[l],以及对应层中的每一个元素值a[l]i。

神经网络a[l]的输出就是y帽,是4*1维向量,其中的4个元素就代表了总和为1的4个对应概率值。

如果我们总结一下从z[l]到a[l]的计算过程,这整个过程从计算幂,到得出临时变量,再做归一化,我们可以把这个过程总结为一个softmax激活函数。即假设a[l]等于向量z[l]的激活函数g。这个激活函数的不同之处在于函数g需要输入一个41的向量,也会输出一个41的向量。以前我们的激活通常是接受单行输入,比如sigmoid函数和ReLu函数,然后输出一个实数。softmax函数的不同之处就在于由于需要把输出归一化,以及输入输出都是向量。

softmax分类器还能代表什么呢?
线性决策边界(泛化的逻辑回归) VS softmax分类器

softmax没有隐藏层时:

如何训练一个带有softmax层的神经网络?

第九课:训练softmax分类器

加深对softmax分类器的理解并学习如何训练采用了softmax层的模型。

softmax的名字对应hardmax,hardmax将矢量z映射到这个矢量[1 0 0 0],即hardmax函数遍历z中的元素,将z中最大的元素对应的位置置1,其余位置置0,所以它简单粗暴最大的元素得到输出1,其余的元素对应输出0,与之对应的是softmax中z到这些值的概率值的映射要平和一些。

另外值得注意的一点是:
sfotmax函数把logistic激活函数从2分类推广到C分类。
即softmax回归是logistic回归从2分类到多分类的推广。

实际上训练一个包含softmax输出层的神经网络应该怎么做?

更一般的,损失函数的功能是查看训练集的真实分类值,并令其对应的概率值尽可能的大。如果你熟悉最大似然估计统计学习方法,这实际上也是某种形式上的最大似然估计。

那么对于整个训练集:
基于某个参数集的损失包含权重和偏差等等,它定义为整个训练集的损失的和,即所有训练样例的预测值和真实值所反映的损失。因此,你要做的是使用梯度下降法使损失最小化。

最后一个值得注意的细节:
如果你使用矢量化计算实现,矩阵Y表示列矩阵,类似的,y帽也是一个列矩阵。

最后让我们看一下梯度下降法在包含softmax输出层的神经网络上的实现。
我们之前讨论的是如何实现前向传播以获得输出并计算损失,那么反向传播也就是梯度下降法如何实现?

实际上关键步骤或者说关键方程式的初始化是表达式,它在最后一层对z求偏导得到dz[l] = y帽-y。
有了这个公式,你就可以计算dz[l]开始你的反向传播过程,并遍历神经网络各层以计算你所需的各个导数。

我们要学会使用深度学习框架,这些基本框架通常只需要你专注于正确实现前向传播,只要你指定它为一个基本框架并指定前向传播过程,该框架会自动为你实现反向传播过程。

总结:你可以使用softmax实现不仅仅是二分类,还包括C分类,下一节展示深度学习编程框架,它将使你的深度学习算法更有效率。

第十课:深度学习框架

你发现当你要实现复杂的模型时,例如卷积神经网络(CNN)或者循环神经网络(RNN)或你着手的复杂模型时,你会发现越来越难操作,幸运的是,现在有很多深度学习框架,可以帮助你实现这些模型。

现在使用深度学习框架,可以使一些任务变得更高效,更实际。

市面上的一些深度学习框架:

如何选择深度学习框架的标准?
其中一个重要的条件就是编程的简便性。这有利于两个方面,开发神经网络对它进行迭代改善以及在生产环境中进行实战部署。

第二个重要标准是运行速度,特别是在大数据集上进行运算时,有些框架比起其他框架能够让你运行和训练神经网络更加高效。

还有一个标准是这个框架是否真正的开源。作为一个真正开放的框架,它不仅需要开放源码,还需要良好的管理。

编程语言、构建什么应用...

第十一课:TensorFlow

TensorFlow的基础结构。

有一个结构程序,可以用来训练神经网络。你可以使用TensorFlow来自动寻找w和b的值,来最小化代价函数的值。

TensorFlow会自动知道如何根据add和multiply等等方法分别求导,这就是为什么你只需要定义前向传播函数,它就会直到如何计算反向传播函数,或梯度,因为它已经内置了算法。
所以一旦w被声明为TensorFlow中的Variable,它的平方、乘法和加法以及减法操作都会被重载,就可以直接用运算符计算。

另外值得注意的一点是:在TensorFlow中,其中一个需要最小化的函数是训练集的函数,x会发生变化时即训练集会发生变化,那么怎么才能把训练集导入到一个TensorFlow程序中呢?

将x替换到二次项中,这样x就变成了能控制二项式的数据,通过placeholder就可以将x变成之后会赋值的东西,这是把训练数据导入代价函数的一个很方便的方法。

它之所以如此强大,是因为你只需要指定如何计算代价函数,然后一两行代码,它就会求导,使用梯度优化器或者Adam优化器或者其他优化器

代码中值得注意的是:有三行代码是在TensorFlow中比较惯用的,也有一个其他版本,这两个版本的功能是一样的。

TensorFlow程序的核心是计算代价函数,之后TensorFlow会自动求导,并计算出如何最小化代价函数,所以cost函数定义的那行代码就是让TensorFlow构建一个计算草案,计算图会执行以下操作,先取得x[0][0],然后再取得w并把w平方,然后再让x[0][0]和w的平方相乘,最终就建立起了方程并计算代价函数。

TensorFlow的好处是正如像上面一样利用前向传播来计算代价函数,TensorFlow已经内置了所有必须的后向传播方程,所以请记住训练神经网络有一套前、后向传播方程。所以对于非常复杂的函数,只要你计算了前向传播,它也能自动的使用后向传播来执行并求导,这就是你为什么不用显示的执行后向传播,这是编程框架会提高你计算效率的事情之一。

此外,更改梯度下降算法为Adam算法,也是只需要更改一行代码就可以实现。

如何系统安排超参数搜索过程!批量标准化以及如何用它来加速训练神经网络!深度学习的编程框架!

你可能感兴趣的:(吴恩达深度学习(六))