第七节,改善深层神经网络:超参数调试、正则化及梯度下降算法优化(上)
目录
这部分内容是我在看Andreg Ng深度学习视频,然后又阅读了一些文章整理后记录下来的。视频连接:http://mooc.study.163.com/smartSpec/detail/1001319001.htm
一 训练集,校验集,测试集以及偏差和方差
1.1 训练集,校验集,以及测试集
- 训练集:学习样本数据集,通过匹配一些参数来建立一个分类器。建立一种分类的方式,主要是用来训练模型的。
- 验证集:对学习出来的模型,调整分类器的参数,如在神经网络中选择隐藏单元数。验证集还用来确定网络结构或者控制模型复杂程度的参数。
- 测试集:主要是测试训练好的模型的分辨能力(识别率等)。
小数据时代七三分或者六二二分是个不错的选择,在大数据时代各个数据集的比例可能需要变成 98%: 1%: 1%,甚至训练集的比例更大。 有些时候训练集和验证集、测试集的数据有所不同时,比如训练集的图片高像素、高质量,而验证集和测试集则像素较低,那么有一条经验法则是确保验证集和测试集来自于同一分布;但由于深度学习需要大量的训练数据,为了获取更大规模的训练数据集,可能会进行网页抓取,代价是训练集数据与验证集和测试集数据有可能不是来自于同一分布。
还有一种情况,就算没有测试集也是可以的,测试集的目的是对最终所选定的神经网络系统做出无偏估计,如果不需要无偏估计也可以不设置测试集。
所以搭建训练验证集合测试集能够加速神经网络的集成,也可以更有效地衡量算法的偏差和方差,从而帮助我们更高效地选择合适的方法来优化你的算法。
1.2 偏差和方差
- 偏差:一般描述的是预测值(估计值)的期望与真实值之间的差距。偏差越大,越偏离真实数据集。(对象是单个模型, 期望输出与真实标记的差别)
- 方差:描述的是预测值的变化范围,离散程度,也就是离其期望值的距离。方差越大,预测结果数据的分布越散。(如果对象是多个模型,表示多个模型差异程度。)
- 基于偏差的误差:所谓基于偏差的误差是我们模型预期的预测与我们将要预测的真实值之间的差值。偏差是用来衡量我们的模型的预测同真实值的差异。
- 基于方差的误差:基于方差的误差描述了一个模型对给定的数据进行预测的可变性。比如,当你多次重复构建完整模型的进程时,方差是,在预测模型的不同 关系间变化的多少。
一般来说,偏差、方差和模型的复杂度之间的关系如下图所示:
越复杂的模型偏差越小,而方差越大。
我们用一个参数少的,简单的模型进行预测,会得到低方差,高偏差,通常会出现欠拟合。
而我们用一个参数多的,复杂的模型进行预测,会得到高方差,低偏差,通常出现过拟合。
实际中,我们需要找到偏差和方差都较小的点。从上图可以看出在偏差和方差都较小的点处,total Error是最少的。
1.3 例子
让我们来看一看我们在什么情况下应该怎样选择:
- 获得更多的训练实例——解决高方差
- 尝试增加正则化程度 λ——解决高方差
- 尝试减少特征的数量——解决高方差
- 尝试获得更多的特征——解决高偏差
- 尝试增加多项式特征——解决高偏差
- 尝试减少正则化程度 λ——解决高偏差
二 过度拟合和正则化
针对训练神经网络过程中偏差过大(欠拟合),或者方差过大(过拟合)我们可以采用哪些方法?
2.1 通常方式
- 深度学习在如今大数据时代可以通过构建一个更大的网络便可在不影响方差的同时减少你的偏差。
- 采用更多的数据可以在不过多影响偏差的同时减少方差。扩增数据代价比较高,而且有时无法扩增数据,但我们可以通过水平翻转、随意翻转和裁剪图片来增加训练数据 。
以上两步实际要做的工作是训练网络,选择网络或者准备更多数据,现在我们有工具可以做到仅仅减少偏差或者仅仅减少方差,不对另一方产生过多不良影响。
2.2 正则化
正则化是一种非常实用的减少方差的方法,正则化会出现偏差方差权衡问题,偏差可能会略有增加,但如果网络足够大的话,增幅通常不会太大 。
这里主要讲解以下L2规范化技术。二次代价函数,以及交叉熵代价函数,柔性最大值正则化后的形式如下:
$$C=C_0 + \frac{\lambda}{2n}\sum_{w}w^2$$
其中$C_0$为原始代价函数。第二项加入的就是所有权重(每个元素)的平方和,$λ$成为规范化参数,规范化可以当做一种寻找小的权重和最小原始代价函数之间的折中,$λ$越小,就越偏向于最小化原始代价函数,反之倾向于小的权重。
常用正则化方法来防止过拟合,因此需要思考参数的选择问题。
- $λ$越大,就会越减少过拟合现象的出现。
- $λ$ 较小时,训练集误差较小(过拟合)而交叉验证集误差较大
- 随着 $λ$ 的增加,训练集误差不断增加(欠拟合),而交叉验证集误差则是先减小后增加
2.3 弃权
利用弃权来降低过拟合。(主要应用在计算机视觉,其他领域应用较少)
假设左图存在过拟合,这就是 dropout 所要处理的,我们复制这个神经网络, dropout 会遍历网络的每一层,并概率性地设置消除神经网络中的节点,假设每个节点都以抛硬币的方式设置概率,每个节点得以保留和消除的概率都是 0.5;
设置完节点概率,我们会消除一些节点,然后删掉从该节点进出的连线,最后得到一个节点更少、规模更小的网络,然后用bcakprop 方法进行训练,这是网络节点精简后的一个版本。
对于其他样本,照旧以抛硬币的方式设置概率,保留一类节点集合,删除其他类型的节点集合,对于每一个训练样本,都将采用一个精简的后的神经网络来训练它。也许你会认为这个方法有点怪,单纯遍历节点,编码也是随机,可它真的有效。
我们怎么去理解弃权?
启发式的看,当我们弃掉不同的神经元集合时,有点像我们在训练不同的神经网络。所以,弃权过程就如同大量不同的神经网络效果的平均那样。
弃权如何实现?
对于l层,我们先生成向量dl,其维数和a1.shape一致(a1表示第l层激活函数输出列向量), dl表示 dropout 向量,然后看它是否小于某数,这个数叫做 keep_prob, 是一个具体的数,表示弃权的概率,我们假设该值为它0.8,它表示保留某个隐藏单元的概率,它的作用就是生成随机矩阵。
dl是一个矩阵,每个样本和每个隐藏单元其在 dl中的对应值为 1 的概率都是 0.8,其对应值为 0 的概率是 0.2.接下来要做的是从l层获取激活函数 al, al 含有需要计算的激活函数 al*=dl(元素相乘),它的作用就是过滤 dl 中所有等于 0 的元素,如果用python 实现的话, dl 是个布尔型数值, true 或者 false,而不是 0 或 1;乘法运算会把 true 或者 false 翻译为 1 和 0。最后我们向外扩张 a3,用它除以 keep_prob 参数(why?假设第l层有 50 层神经元,在一维上 al 等于 50,我们通过因式分解将它拆成 50Xm 维的,保留和删除它们的概率分别为 80%和 20%,这意味着最后被删除或归零的单元平均有 10 个, zˆ[l+1] = wˆ[l]*al+bˆ[l+1], 我们预期是 al减少 20%,也就是说 al中有 20%的元素被归零,为了不影响 zˆ[l+1]的期望值,我们需要用 (wˆ[l+1]*al) / 0.8,它将会修正或弥补我们所需的 20%,这样 al的期望不会变)。
dl = np.random.rand(al.shape[0],al.shape[1]) < keep_prob #dropout向量 al = np.multply(al,dl) #乘法运算会把 true 或者 false 翻译为 1 和 0。 过滤掉dl中元素为1的神经元 al = al/keep_prob
弃权有什么不稳定的因素?
对于我们已经训练好的神经网络,我们只需计算前向输出,由于弃权矩阵dl是随机的,给定一个输入,则网络的输出也会动态变化,有时候输出结果并不会太令我们满意。
2.4 利用提前停止来降低过度拟合
在运行梯度下降时,你可以绘制训练误差图或者回归代价函数 $J$ 的优化过程图,在训练集上用 0-1 记录分类误差次数,可以看到它呈单调下降的趋势;因为在训练过程中,我们希望训练误差、代价函数 $J$ 都在下降,通过 early stopping 不仅可以看到上述这些图,还可以绘 制验证集误差图,你会发现验证集误差通常会先呈下降趋势,然后在某个节点处开始上升。
early stoping 在神经网络中随机初始化$w$ 值,它的值可能都是较小的值,随着迭代增大,而它是在中间点停止迭代过程,得到一个中等大小的$w$;与L2 正则化相似,选择参数$w$范数较小的神经网络,希望神经网络过度拟合不严重。
early stopping 的学术意思是提早停止训练神经网络,一旦校验数据集上分类准确率已经饱和,就停止训练。
但也有一个缺点:不能独立处理以下两个情况,因为提早停止梯度下降,也就停止降低代价函数 J,所以代价函数可能不会比较小,这样做的话你没有采用不同的方式来解决这个问题,你需要考虑的东西就变得更复杂了。
如果不用 early stopping,另一种方法是 L2 正则化,训练神经网络的时间就可能很长,将导致参数搜索空间更容易分解,也更容易搜索, 但缺点是你必须尝试很多正则化参数 λ 的值, 也导致搜索大量 λ 值得计算代价太高。
early stopping 的优点是只运行一次梯度下降, 你可以找出 $w$的较小值,中间值和较大值, 而无需尝试 L2 正则化超参数$λ$ 的很多值。
亲爱的读者和支持者们,自动博客加入了打赏功能,陆陆续续收到了各位老铁的打赏。在此,我想由衷地感谢每一位对我们博客的支持和打赏。你们的慷慨与支持,是我们前行的动力与源泉。
日期 | 姓名 | 金额 |
---|---|---|
2023-09-06 | *源 | 19 |
2023-09-11 | *朝科 | 88 |
2023-09-21 | *号 | 5 |
2023-09-16 | *真 | 60 |
2023-10-26 | *通 | 9.9 |
2023-11-04 | *慎 | 0.66 |
2023-11-24 | *恩 | 0.01 |
2023-12-30 | I*B | 1 |
2024-01-28 | *兴 | 20 |
2024-02-01 | QYing | 20 |
2024-02-11 | *督 | 6 |
2024-02-18 | 一*x | 1 |
2024-02-20 | c*l | 18.88 |
2024-01-01 | *I | 5 |
2024-04-08 | *程 | 150 |
2024-04-18 | *超 | 20 |
2024-04-26 | .*V | 30 |
2024-05-08 | D*W | 5 |
2024-05-29 | *辉 | 20 |
2024-05-30 | *雄 | 10 |
2024-06-08 | *: | 10 |
2024-06-23 | 小狮子 | 666 |
2024-06-28 | *s | 6.66 |
2024-06-29 | *炼 | 1 |
2024-06-30 | *! | 1 |
2024-07-08 | *方 | 20 |
2024-07-18 | A*1 | 6.66 |
2024-07-31 | *北 | 12 |
2024-08-13 | *基 | 1 |
2024-08-23 | n*s | 2 |
2024-09-02 | *源 | 50 |
2024-09-04 | *J | 2 |
2024-09-06 | *强 | 8.8 |
2024-09-09 | *波 | 1 |
2024-09-10 | *口 | 1 |
2024-09-10 | *波 | 1 |
2024-09-12 | *波 | 10 |
2024-09-18 | *明 | 1.68 |
2024-09-26 | B*h | 10 |
2024-09-30 | 岁 | 10 |
2024-10-02 | M*i | 1 |
2024-10-14 | *朋 | 10 |
2024-10-22 | *海 | 10 |
2024-10-23 | *南 | 10 |
2024-10-26 | *节 | 6.66 |
2024-10-27 | *o | 5 |
2024-10-28 | W*F | 6.66 |
2024-10-29 | R*n | 6.66 |
2024-11-02 | *球 | 6 |
2024-11-021 | *鑫 | 6.66 |
2024-11-25 | *沙 | 5 |
2024-11-29 | C*n | 2.88 |

【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了