(课时一)
配置训练 验证数据集 测试数据集
训练神经网络 : layers(分层) hidden unit(隐藏单元层) learning rates 学习速率
Activation functions 各层的激活函数
创建新应用时不可能一开始就准确预测出这些信息和其他超级参数
-----》 应用型机器学习是一个高度迭代的过程(一步步尝试)
最佳决策取决于你拥有的的数据量 计算机配置中输入特征的数量 GPU or CPU 具体配置
生活中的deep learning,几乎无处不在 自然语言 计算机视觉 语言识别 结构化数据 广告到网络搜索 计算机安全 物流。。。。。
迭代 循环往复 重点
循环的效率是项目进展速度的关键
创建高质量的训练数据集 验证集 和测试集 提高效率
Data: train set hold out(简单交叉验证 验证集) cross:test set(评估)
选择最好模型
经验之各大数据集的分布
小数据时代 :70%验证集-----30%测试 训---验---测
60%-20%-20%
大数据时代 1百万数据 1万作为验证集 1万作为测试集
98%-1%-1%
过百万 99.5%--0.25%--0.25% 或者 99.5%--0.4%--0.1%
注意
训练和测试集的分布需匹配
网站上的猫照片高清可能经过了美化以及各种表情包
用户上传的猫照片分辨率低而且未经美化
误差较大
Bias variance 偏差和方差 (易学难精)第二课时
1 2 3
1.逻辑回归拟合 (欠拟合)
3、拟合一个复杂的分类(比如深度神经网络或含有隐藏单元的神经网络)分类器方差
较高 过拟合
2.复杂程度适中 拟合程度适度的分类器 适度拟合(过拟合和欠拟合中间一类)
像这样只有x1和x2两个特征的二维数据集中 我们可以绘制数据将方差和偏差可视化
在多维空间中 绘制数据和可视化分割边界无法实现 但我们可以通过几个指标来研究
方差和偏差
Cat 分类 classification
Y=1 y=0
假设 第二种假设
Train set error(训练集误差): 1% 15%
Dev set error(验证集误差):11% 16%
人的错误率: 0%
可以得出:训练集设置的很好 验证集设置相对较差 可能过度拟合了训练集某种程度上
验证集并没有充分利用交叉验证集的作用
这种情况称之为 :高方差 high variance
第二种情况
可见 算法并没有在训练集中得到很好的训练训练数据的拟合度不高(数据欠拟合)所以说他的偏差比较高 对于验证集产生的结果很合理(解释::仅比训练集多了1%)high biar(因为它甚至不能拟合训练集)
第三种情况 15%---30%
高偏差和高方差
第四重: 0.5%---1%
低偏差和低方差
方法总结 检查train set 判断偏差
从train set 到dev set过程中 判断方差
以上分析的前提是:假设基本误差很小 训练集和验证集数据来自相同分布
示例:
数据拟合低 高偏差
高偏差(线性分类器 并未拟合数据)和高方差(像红色的二次函数(或曲线)灵活度高 会产生高方差)以至于拟合了这两个错误样本和中间这些活跃数据
从两个维度看起来不太自然 高维数据中就不太牵强了
机器学习基础:
初始模型训练完成后:
High bias(评估训练集或训练数据的性能)
Y N
选择一个新网络(比如含有更多隐层或者隐藏单元的网络或 train it longer 或花更多的时间训练算法或更先进的优化算法)
Done
High variance(dev set problems)
More data(正则化来减少过拟合)
正则化: 无法实时准备足够多的数据或获取数据的成本比较高时,低成本的正则化通常有助于避免过度拟合或减少网络误差
逻辑回归 min J(w,b)
求成本函数的最小值
参数包含一些训练数据和不同数据中个体预测的损失。
w,b 是逻辑回归的两个参数 w是一个多维度参数矢量,b是实数 w平方的范数
w欧几里德范数的平方等于wj(j从1到nx)的平方和
向量参数w的欧几里德范数的平方 此方法称为L2正则化(用的比较多)
括号可以省略的原因:w通常是一个高维参数矢量,已经可以表达高偏差问题,w可能含有很多参数,我们不可能拟合所有参数,而b只是单个数字,所以w几乎涵盖所有参数,而不是b。加了参数b,其实也没什么太大影响,因为b只是众多参数中的一个。
L1正则化 w向量的L1参数 无论分母是m还是2m,都是一个比例常量,w最终会是稀疏的---》w向量有很多0.
入-------正则化参数 我们通常使用验证集或交叉验证来配置这个参数,尝试各种各样的数据,寻找最好的参数。我们要考虑训练集之间的权衡,把参数正常值设置为较小值,这样可以避免过拟合。因此入是另外一个需要调整的超级参数。
在python中 入(lambda)是一个保留字段 编代码时写成:lambd
神经网络中如何实现L2正则化
神经网络有一个成本函数,该函数中包含从w[1],b[1] 到w[l],b[l]所有参数,字母l是神经网络所含层数 损失总和 正则项
矩阵范数:矩阵中所有元素的平方求和 w是一个n[l-1] 到n[l]的多维矩阵
隐藏单元的数量 l层单元的数量
如何使用该范数实现梯度下降 用backprop计算出dw的值
L2正则化有时也被称为权重衰减 学习率α
损失总和+正则项
避免数据权值矩阵过大
直观上的理解是:如果λ设置的足够大,权重矩阵w被设置为接近0的值,就是把多隐藏单元的权重设为0,于是基本上消除了这些隐藏单元的诸多影响,这个被大大简化了的神经网络会变成一个很小的网络,小到如同一个逻辑回归单元,可是深度却很大。 结果如箭头所示。
但是λ会存在一个中间值,于是会有一个接近just right的中间值。(直观理解就是λ增加到足够大会有w接近于0,实际上是不会发生这种情况的)
我们尝试消除或至少减少许多隐藏单元的影响,最终这个网络会变得更简单,这个神经网络越来越接近逻辑回归。
我们直觉上认为大量隐藏单元被完全消除了,其实不然,实际上是所有隐藏单元依然存在,但是他们的影响变得更小了,神经网络变得更简单了。这样更不容易发生过拟合(在实际编程执行正则化时,你会实际看到一些方差减小的结果)
tan h(z)
只要z非常小,如果z只涉及少量参数,这里我们利用了双曲正切函数的线性状态,只要z的绝对值扩展变大,激活函数开始变得非线性。
如果每层都是线性的,那么整个网络就是一个线性网络,即使对于一个非常深的深层网络。因此,它不适用于非常复杂的角色,以及过度拟合数据集的非线性决策边界。
总结:如果正则化参数变得很大,参数w很小,z也会相对变小,此时忽略b的影响,因此,z会相对变小(实际上,z的取值范围很小),这个激活函数会相对呈线性,整个神经网络会计算离线性函数近的值,这个线性函数非常简单,并不是一个极复杂的高度非线性函数,不会发生过拟合
执行正则化的小建议:在增加正则化项时,应用之前定义的代价函数J,我们做过修改,增加了一项,目的是预防权重过大。如果你使用的是梯度下降函数,在调试梯度下降时,其中一部就是把代价函数J设计成这样一个函数,它代表梯度下降的调幅数量,可以看到,代价函数对于梯度下降的每个调幅都单调递减。如果你实施的是正则化函数,J已经有一个全新的定义。
理解箭头的变化过程
另一个非常实用的正则化方法--------dropout(随机失活)
假设你训练这样一个存在过拟合的神经网络
Dropout会遍历网络的每一层,并设置消除神经网络中节点的概率,假设网络中的每一层,每个节点都以抛硬币的方式设置概率,那么每个节点的得以保留或消除的概率都是0.5,设置完后,我们会消除一些节点,然后删除从该节点进出的连线,最后得到一个节点更少,规模更小的网络,然后用backprop方法进行训练。
这是网络节点精简后的一个样本,对于其它样本,我们依旧以抛硬币的方式设置概率,保留一类节点集合,删除其它类型节点集合,对于每个训练样本,我们都将采用一个精简后的神经网络来训练它。
这个方法看起来很荒唐(随机遍历删除节点),但事实证明它真的很有效。
实施dropout最常用的方法:inverted dropout (反向随机失活)
L=3 ---3层网络示范(出于完整性考虑)
例子是在某一层中实施dropout
Keep-prop:保留某个隐藏单元的概率(它意味着消除任意一个隐藏单元的概率是0.2)
它的作用是生成随机矩阵,如果对a^3进行因子分解,效果也是一样的。
d3是一个矩阵,每个样本和每个隐藏单元,其在d3中对应值为1的概率是0.8。
接下来要做的就是从第三层中获取激活函数,这里我们叫他a3。
它的作用就是过滤d3中所有等于0的元素,而各个等于0的概率只有20%,乘法运算最终把d3中相应元素归零
dropout方法,无论keep-prop的值是多少,反向随机失活(inverted dropout)方法通过除以keep-prop,确保a3的期望值不变
假设有50个网络
为了不影响z【4】的期望值:用w[4]*a[3]/0.8,他将会修正或弥补我们所需的那20%
现在你使用的是d向量,你会发现,不同的训练样本,清除不同的隐藏单元也不同,实际上如果你通过训练集多次传递数据,每次训练数据的梯度不同,随机对不同隐藏单元归零。有事却并非如此,例如:需要将相同隐藏单元归零,第一次迭代梯度下降时,把一些隐藏单元归零,第二次迭代梯度下降时,也就是第二次遍历训练集时,对不同类型的隐藏单元归零,向量d或d3用来决定第三层中那些单元归零,无论用foreprop还是backprop。
我们在测试阶段不使用dropout函数
如何在测试阶段训练算法:在测试阶段,我们已经给出了x或是想预测的变量,用的是标准计数法。
第0层的激活函数标注为测试样本x,我们在测试阶段不使用dropout函数,尤其是像下列情况
以此类推直到最后一层 预测值为Y^. 显然在测试阶段,我们并未使用dropout,自然也就不用抛硬币来决定失活概率以及要消除那些隐藏单元了。因为在测试阶段进行预测时,我们不期望输出结果是随机的。如果测试阶段应用dropout函数,预测会受到干扰,理论上,你只需要多次运行预测处理过程,每一次,不同的隐藏单元会被随机归零,预测处理遍历他们,但是计算效率低,得出的结果也几乎相同,与这个不同程序产生的结果极为相似。
Inverted dropout 函数在除以keep-prop时可以记住上一步的操作,目的是确保即使在测试阶段不执行dropout来调整数值范围,激活函数的预期结果也不会发生变化,所以没必要在测试阶段额外添加尺度参数,这与训练阶段不同
dropout 可以随机删除网络中的神经单元,做法有点疯狂,它为什么可以通过正则化发挥这么大作用呢?
第一个直观感受是:每次迭代之后,神经网络都会比以前变得更小,因此采用一个较小的神经网络好像和使用正则化的效果是一样的。
第二个直观认识:我们从单个神经元入手,
这个单元的工作就是输入并生成一些有意义的输出,
通过dropout,该单元的输入几乎被消除,有时这两个单元会被消除,有时会删除其它单元。
就是说,用紫色圈起来的这个单元,它不能依靠任何特征,因为特征都有可能被随机清除,或者说该单元的输入也都可能被随机清除,我不愿意把所有的赌注都放在一个节点上,不愿意给任何一个输入加上太多权重,因为它可能会被删除,因此该单元将通过这种方式积极地传播开,并为单元的4个输入增加一点权重,通过传播所有权重,dropout将产生收缩权重的平方范数的效果,和我们之前讲过的L2正则化类似,实施dropout的结果是他会压缩权重,并完成一些过拟合的外层正则化。
事实证明 dropout被正式地作为一种正则化的替代形式,L2对不同的权重的衰减是不同的,它取决于倍增的激活函数的大小。
总结:dropout的功能类似于L2正则化,不同的是,被应用的方式不同,dropout也会有所不同,甚至更适合用于不同的输入范围。
实施dropout的另一个细节是:
这是拥有3个输入特征的网络,其中一个要选择的参数是keep-prop,它代表每一层上保留单元的概率,所以不同层的keep-prop也可以变化
W[1]: 3*7 第二个权重矩阵是7*7 w[3]是7*3,以此类推
W[2]是最大的权重矩阵---拥有最大的参数集
为了预防矩阵的过拟合,第二层的keep-prop值应该相对较低,其它层可以高一点。
总结:如果你担心某些层比其它层更容易发生过拟合,可以把某些层的keep-prop值设置的比其它层更低,缺点是为了使用交叉验证你要搜索更多的超级的超级参数,另一种方案是在一些层上应用dropout,而有些层不用dropout,应用dropout的层只含有一个超级参数,就是keep-prop。实施dropout 在计算机视觉领域有很多成功的第一次,计算视觉中的输入量非常大,输入了太多像素,以至于没有足够的数据,所以,dropout在计算机视觉领域中应用的比较频繁。
Dropout的一大缺点就是代价函数J不再被明确定义,每次迭代,都会随机移除一些节点,如果再三检查梯度下降的性能,实际上是很难进行复查的。定义明确的代价函数J每次迭代后都会下降,因为我们所优化的代价函数j实际上并没有明确定义,或者在某种程度上很难计算,所以我们失去了调试工具,来绘制这样的图片。吴老师通常会关闭dropout函数,将keep-prop的值设为1,运行代码,确保J函数单调递减,然后再打开dropout函数。在dropout过程中,代码并未引入bug
其它方法减少神经网络中的过拟合
假设你正在拟合猫咪的图片分类,扩增训练数据代价高,但我们可以通过添加这类图片来增加训练集。例如:1.水平翻转并把它添加到训练集(训练集可以增大一倍)
2.随意裁剪
。。。。。。
注意图片中的主体必须还是猫。
因为训练集有冗余,这虽然不如我们额外收集一组新图片那么好,但是这样做节省了获取更多猫咪图片的花费
对于光学字符识别:增大训练集可以通过轻微的变形处理
所以,数据扩增可以作为正则化方法使用,实际功能上也与正则化相似
另一种常用方法叫 early-stopping
运行梯度下降时,我们可以绘制训练误差或只绘制代价函数J的优化过程,在训练集上用0-1记录分类误差次数,呈单调下降趋势。因为在训练过程中,我么希望训练误差,代价函数J都在下降。
通过early-stopping,我们不单可以绘制上面这些内容,还可以绘制验证集误差,它可以是验证集上的分类误差或验证集上的代价函数,逻辑损失或对数损失等。你会发现,验证集误差通常会先呈下降趋势,然后在某个节点处开始上升。
Early-stopping的作用是:当你还未在神经网络上运行太多迭代过程的时候,参数w接近0,因为随机初始化w值时,它的值可能都是较小的随机值,所以,在你长期训练神经网络之前,w依然很小。因为随机初始化w值时,它的值可能都是较小的随机值,在迭代过程和训练过程中,w会变得越来越大。
所以,early-stopping要做的就是在中间点停止迭代过程,我们得到一个w值中等大小的弗罗贝尼乌斯范数
与L2正则化相比,选择参数w范数较小的神经网络。
主要缺点:你不能独立地处理这两个问题,因为提早停止梯度下降,也就是停止了优化代价函数J,因为现在你不再尝试降低代价函数J,所以代价函数J的值可能不够小,同时你又希望不出现过拟合。你没有采取不同的方式来解决这两个问题,而是用一种方法同时解决两个问题,这样做的结果是:我们要考虑的东西变得更加复杂。
优点:只运行一次梯度下降,你可以找出w的较小值,中间值和较大值,而无需尝试L2正则化超级参数λ的很多值
训练神经网络,其中一个加速训练的方法是:归一化输入。
假设我们有一个训练集,它有两个输入特征,所以输入特征x是二维的。
归一化输入需要两个步骤:1.0均值化
2. 归一化方差:此图(特征x1的方差比x2的方差要大得多)
节点y的平方 是一个向量,它的每个特征都有方差
X1和x2的方差都是1
这样做的原因:首先想归一化的输入特征
代价函数
如果你使用非归一化的输入特征的代价函数图像:
这是一个非常细长狭窄的代价函数,你必须使用一个非常小的学习比率,梯度下降法可能需要多次迭代过程
归一化后:无论从哪儿开始,梯度下降法都能直接地找到最小值(对称),可以使用较大的步长
实际上,w是一个高维向量,总的直观理解是代价函数会更圆一些,而且更容易优化,前提是特征都在相同的范围内,而不是从1到1000,0到1的范围,这使得代价函数J优化起来更加简单快速。(成功例子:特征x1范围在0-1之间,x2在-1~1之间,x3在1~2之间,他们是相似范围,所以会表现得更好)
总结:特征值处于相似范围,归一化就不是很重要,反之则重要
训练神经网络,尤其是深度神经网络所面临的一个问题是:梯度消失或梯度爆炸(导数或坡度有时会变得非常大或非常小甚至以指数方式变小,这加大了训练的难度)
假设你正在训练这样一个极深的神经网络(虽然每层只有2个隐藏单元,但它可能含有更多),使用激活函数g(z)=z(线性激活函数),忽略b,b[L]=0.
Y^=1.5^(L-1)*x ,如果对于一个深度神经网络来说L值特别大,那么Y^的值也会很大,实际上它呈指数级增长,增长的比率是:1.5^L , y的值将爆炸式的增长。
相反的,如果权重是0.5
在深度神经网络中,激活函数以指数级递减
总结:
指数级递减 指数级增长,它也适用于于层数L相关的导数或梯度函数
单个神经网络可能有4个输入特征从x1到x4
b 暂时等于0
为了预防z值过大或过小,n越大,你希望wi越小,以为z是wixi的和,如果你把很多此类项相加,希望每项值更小,最合理的方法是设置wi=1/n。
n表示神经元的输入特征的数量,实际上,你要做的就是设置某层权重矩阵W
再乘以该层每个神经元的特征数量分之一
这是高斯随机变量
如果你用的是Relu激活函数,而不是1/n,方差设置为2/n效果会更好。
这里 因为l层上每个神经元都有n(l-1)个输入,如果激活函数的输入特征被0均值,标准方差,方差是1,z也会调整到相似的范围,这就没解决问题,但它确实降低了坡度消失和爆炸问题,因为它给权重矩阵w设置了合理值(它不能比1大很多,也不能比1小很多)。
在实施backprop时,有一个测试叫梯度检验,它的作用是确保backprop正确实施。
因为有时候,你虽然写下了这些方程式,却不能100%确定执行backprop的所有细节都是正确的。
为了逐步实现梯度检验,首先理解如何对计算梯度做数值逼近。
逼近误差0.0001 最优的是双边误差;
g(θ)可能是一个f导数的正确实现,在梯度检验和反向传播中使用该方法时,最终,它与运行两次单边公差的速度一样。
梯度检验可以节省很多时间,发现backprop实施过程中的bug。
如何用梯度检验调试和检验backprop的实施是否正确?
假设你的网络中有如下参数w[1]和b[1]…w[L]和b[L], 首先把所有的参数转换成一个巨大的向量数据,你要做的就是把矩阵w转换成一个向量,然后做连接运算,得到一个巨型向量θ
接着你得到w和b顺序相同的数据,
用他们来初始化大向量dθ,它与θ具有相同的维度。
现在的问题是:dθ,代价函数J的梯度或坡度有什么关系,这就是实施梯度检验的过程(grad check)。首先,我们清楚,J是超级参数θ的函数,J函数可以展开为J(θ1,θ2,θ3……);无论超级参数向量θ的维度是多少,为了实施梯度检验,你要做的就是循环执行。
采用双边误差
dθi是代价函数的偏导数,你需要对i的每个值都执行这个运算。
验证这些向量是否彼此接近。
验证方法
欧几里德范数,它是误差平方之和,然后求平方根,得到欧式距离,然后用向量长度做归一化得
分母只是预防这些向量太大或太小,分母使得这个方程式变成比率。ε值可能为10的-7次方。计算方程式的值为10的-7次方或者更小,这就很好,这就意味着导数逼近很有可能是正确的,大于10的5次方就要检查是否有bug或某一项的值太大
在神经网络上实施梯度检验的使用技巧和注意事项:
1.不要在训练中使用梯度检验,它只用于调试。为了实施梯度下降,你必须使用backprop来计算dθ,并使用backprop来计算导数,只有调试的时候,你才会计算它,来确认数值是否接近dθ,完成后,关闭梯度检验。
2.如果算法的梯度检验失败,要检查所有项,检查每一项,并试着找出bug。
3.在实施梯度检验时,如果使用正则化,请注意正则项
划线的一项一定要包括。
4.梯度检验不能与dropout同时使用,因为每次迭代过程中,dropout会随机消除隐藏单元的不同子集,难以计算dropout在梯度下降上的代价函数J,因此,dropout可作为优化代价函数J的一种方法,但是代价函数J被定义为对所有指数极大的节点子集求和,而在任何迭代过程中,这些节点都有可能被消除,所以很难计算代价函数J。
(如果你想同时使用,可以把dropout中的keep-prop设置为1,即全部保留,建议最好关闭);
5.最微妙的一点,(现实中几乎不会出现)当w和b接近0时,梯度下降的实施是正确的,在随机初始化过程中,但是,在运行梯度下降时,w和b变得更大,它会越来越不准确。