Lecture7:随机梯度下降算法问题及解决、dropout正则化、学习率的选择、迁移学习

news2024/11/21 1:39:09

目录

1.随机梯度下降算法问题及解决

1.1 随机梯度下降算法SGD的问题

1.2 具有动量的梯度下降算法SGD+Momentum

1.3 Nesterov加速梯度法

1.4 AdaGrad

1.5 RMSProp

1.6 融合!Adam算法

2. 学习率的选取

3. 正则化

3.1 dropout正则化

4. 迁移学习


1.随机梯度下降算法问题及解决

1.1 随机梯度下降算法SGD的问题

         回顾之前所学习的内容,训练一个神经网络的核心是一个优化问题,我们写下损失函数,定义网络权重的每一个值,损失函数告诉我们这些权重值在解决问题的时候是好是坏,我们设想在当前权重下,损失函数给了我们漂亮的等高线图,如下:

        W\_1,W\_2对应了两个参数,等高线图对应着损失值,目标是找到红色最深的区域,其对应了损失函数最小值的权重值。

        我们之前用了最简单的随机梯度下降法完成了这一步骤。但是这个方法在实际使用中会出现诸多问题: 

         随机梯度下降算法的问题之一是我们改变W_1,W_2在水平方向改变值损失函数变化的非常慢,在垂直方向改变值损失函数变化的非常快。

w_1 = w_1 -\alpha \frac{dW}{dw_1},w_2 = w_2 -\alpha \frac{dW}{dw_2}

         运行随机梯度下降算法效果如下图:

         原因正是因为这类目标函数梯度的方向并不是与最小值成一个直线,因此当我们计算梯度并沿着前进时可能一遍遍跨过这些等高线。这在高维参数中更常见,因为我们的参数可能包含百万,千万甚至上亿个。

        随机梯度下降法的另外一个问题是会出现局部极小值或鞍点:如果损失函数如下图所示,随机梯度下降法得到的最终结果会卡在中间。因为这里是局部最小值,梯度为0。

         关于鞍点,如下图,你可以设想在该点上往一个方向是向上往另一个方向是向下,在当前的位置梯度为0,在这种情况下函数将被卡在鞍点因为这里梯度为0。

1.2 具有动量的梯度下降算法SGD+Momentum

        解决局部极小值或鞍点的一个方法是加入“动量”项。

        这个思想就是保持一个不随时间变化的速度,并且我们将梯度估计添加到这个速度上。然后在这个速度的方向上步进而不是在梯度的方向上步进。

        通俗的来讲,加入惯性/速度,使得优化不容易落入局部最优解或停留在鞍点。

        同时这里有一个超参数\rho(rho),现在在每一步我们采用当前的速度然后用摩擦系数\rho来对其衰减,摩擦系数\rho通常取值0.9,我们采用当前的速度然后使用摩擦系数进行衰减之后加到梯度上,现在我们在速度向量的方向上步进而不是在原始的梯度向量。
        我们想象一下在鞍点或局部最小值点发生了什么,这就好像一个小球下山,它被赋予了速度,即使在鞍点或局部最小值点时梯度比较小,但他因为被赋予了速度速度,还是可以穿越这个局部最小值点然后继续下降。

        同时对于上图所述这种情况,一旦我们使用动量,这些Z字型的曲线曲折也会很快互相抵消,这会有效的降低我们朝敏感方向步进的步伐,而在水平方向上,我们的速度只会不断增加,实际上还会加快在水平方向上的梯度下降。

1.3 Nesterov加速梯度法

        同样还有一种叫做Nesterov加速梯度的梯度下降计算方法,有时也称之为Nesterov动量,相对于我们所说的Momentum取“混合”,它把这个顺序改变了。在普通的SGD动量中,我们估算当前位置的梯度,然后取速度和梯度的混合。但在Nesterov加速梯度中,要做的事情有一点不同,我们从红色点开始,在取得的速度的方向上进行步进(向量叠加),之后计算这个位置的梯度,随后回到初始位置将这两者混合起来。 它的公式如下:

1.4 AdaGrad

        还有一种是AdaGrad方式的梯度下降:

         核心思想是在优化的过程中需要保持一个在训练过程中的每一步的梯度的平方和的持续估计,与速度项不同的是我们现在有了一个梯度的平方和,在训练时我们会一直累加当前梯度的平方到这个梯度平方项,当我们在更新我们的参数向量时我们会除以这个梯度平方项。

         这样的放缩对如上图所述场景有什么改进呢?沿其中一个轴我们有很高的梯度而另一个轴方向却有很小的梯度,那么随着我们累加小梯度的平方我们会在最后更新参数向量时除以一个很小的数字从而加速了在小梯度维度上的学习速率;然后在另一个维度方向上由于梯度变得特别大我们会除以一个非常大的数所以我们会降低这个维度方向上的训练进度。

        不过当t(时间)越来越大的时候在训练的过程中使用AdaGrad会发生什么?

        步幅会越来越小,因为我们一直在随时间更新梯度平方的估计值,所以这个估计值随着训练过程中一直随着时间单调递增,这会导致我们的步长随着时间单调递减。在学习目标是一个凸函数的情况下这个方法效果很好,因为接近极值点时会逐渐慢下来最后到收敛,这点是(AdaGrad)在凸函数情况下的一个很好的特性。但是在非凸函数的情况下,因为我们一旦到达一个局部极值点时,使用AdaGrad会让梯度下降在这里被困住从而使得训练过程无法再进行下去。

1.5 RMSProp

         因此我们对AdaGrad有一个变体叫做RMSProp。在RMSProp中我们仍然计算梯度的平方,但是我们不累计梯度的平方,而是让平方梯度按照一定比率下降。我们看一下效果:

1.6 融合!Adam算法

         我们将这些好的效果融合到一起,得到Adam算法的雏形:

         使用Adam,我们更新第一动量和第二动量的估计值,在红框里我们让第一动量的估计值等于我们梯度的加权和(上一次迭代和这次迭代)。我们在次就有一个第二动量的动态估计值,像AdaGrad和RMSProp一样就是一个梯度平方的动态近似值。
        现在我们来看看怎么更新它们,我们使用第一动量,有点类似于速度,除以第二动量的平方根,这样的话Adam最后看起来有点像RMSProp加上动量或者看起来像动量加上第二个梯度平方,就像是合并了两者各自好的性质。

        但是这也有一个问题,在我们算法运行最开始的时候会发生什么?

        beta2一个默认值是0.99。

        开始时,我们将第二动量初始化为0,第二动量经过一步更新后,第二动量仍然非常接近0,我们在更新时除以一个接近0的数字我们在一开始得到一个很大的步长,但是这个很大很大的步长并不是因为这一步的梯度很大,只是因为我们人为地将第二动量初始化成了0。这样我们的初始化工作就彻底搞砸了。
        因此Adam算法也增加了偏置校正项来避免出现开始时得到很大步长的问题出现:

        在我们更新了第一和第二动量之后,我们构造了第一和第二动量的无偏估计,通过使用当前时间不长t,现在我们实际上在使用无偏估计来做每一步更新,而不是初始的第一和第二动量的估计值。
        Adam算法一般是我们的首选!

2. 学习率的选取

        那么怎么选择这些算法的学习率呢?

        当我们选择学习率时?有时候太高了就会导致(损失函数)爆炸,如黄色的曲线。如果学习率很小,如蓝色的曲线,它的收敛很慢。
        一个方法是我们不必在训练时都采用一个学习率,有时候人们会把学习率沿着时间衰减
,有点像是结合了上图中不同曲线的效果:在训练开始时选择一些相对较大的学习率然后在训练过程中逐渐衰减地越来越小。

        一个衰减的策略是步长衰减,比如在第10万次迭代时可以衰减一个因子然后继续训练:

\alpha =\alpha _0e^{-kt}

        还有指数衰减,这是在训练过程中持续衰减:

\alpha =\frac{\alpha _0 }{1+kt}

        我们可以看到这样的损失曲线,这就是因为学习率的持续衰减引起的优化:

        学习率下降这种思想很常见,但是像Adam的优化算法就很少用。另外学习率衰减是一种二阶的超参数,通常不应该一开始就用上。通常你想要让神经网络开始工作,你想要挑选一个不带学习率衰减的不错的学习率来作为开始,尝试在交叉验证中同时调学习率衰减和初始学习率等等宴他的事情你会一头雾水的。设置学习率的方法是先尝试不用衰减看看会发生什么,然后仔细观察损失曲线看看你希望在哪个地方开始衰减。
        另外,此节我们所讲的所有算法都是一阶优化算法。

        在这个一维的图中,我们有一个目标函数曲线,当前点是这个红色的点,我们在这个点上求一个梯度,我们用梯度信息来计算这个函数的线性逼近,这个相当于是对我们的函数进行的一阶泰勒逼近。我们想要找到逼近的最小值,但是这个逼近在稍大的区间内并不成立所以我们不能朝那个方向一下走太多。

        事实上,这里梯度的想法用上了函数的一阶偏导,我们其实可以用二阶逼近,如下图:

        这里我们同时考虑一阶和二阶偏导信息,现在我们对函数做一个二阶泰勒逼近,就是用一个二次函数来局部逼近我们的函数,因为是二阶函数我们可以直接逼近到我们的最小值点。这就是二阶优化的思想。
        推广到多阶,就会得到一个叫做牛顿步长的东西,计算这个海森矩阵即二阶偏导矩阵,接着求这个海森矩阵的逆以便直接走到对你的函数用二次逼近后的最小值的地方。与之前的方法相比,这种方式不用考虑学习率。

        但是这对于深度学习来说有点不切实际,因为海森矩阵的计算成本太大了,内存无法完成,因此,我们常用拟牛顿法来替代牛顿法,不是直接地去求完整的Hessian矩阵的逆,而是去逼近这个矩阵的逆,常见的是低阶逼近。
        L-BFGS就是一个二阶优化器,用Hessian矩阵来逼近,但很多深度学习的并不适应这个算法,因为这些逼近对随机的情况处理的不是很多。而且在非凸问题上表现得不是很好。

        因此在实际中Adam已经是一个很好的选择了,但如果你的计算能力足够强的话(能够承受整个批次的更新),而且你的问题中没有很多的随机性,那么L-BFGS是一个很好的选择。
        目前我们讲过的所有策略都是在减少训练误差,这写优化算法都是在通过减少训练误差来减少损失函数,但是我们并不在意训练误差,我们更在意在我们没见过的数据集的表现。我们很在意减少训练误差和测试误差之前的差距。

         现在的问题是如果我们已经很擅长优化目标函数,要怎么做来减少训练和测试之间的误差差距,以使得我们在没有讲过的数据中表现得更好呢?
        一个简单的方法就是模型集成:我们选择从不同的随机初始值上训练10个不同的模型,到了测试时,我们就会在10个模型上运行测试数据然后平均10个模型的预测结果。把这些模型加在一起能够有效避免过拟合问题。其实有时候不用独立地训练不同的模型,我们可以在训练过程中保留多个模型的快照,然后用这些模型来做集成学习,在测试阶段,我们仍然需要把这些多个快照的预测结果做平均,但我们可以在训练过程中收集这些快照。

3. 正则化

3.1 dropout正则化

        我们如何能提高单一模型的效果?正则化

        我们在模型中加入一些成分来防止训练集上的过拟合,从而使测试集上的效果得到提升。 L2正则化在神经网络中的表现不是很好,一个很好的选择是dropout正则化。

        它是这样运行的:每次在网络中正向传播时,我们在每一层随机将一部分神经元置零,每次正向传播时随机被置0的神经元都不是相同的:

         每次处理网络中的一层,我们经过一层网络算出这一层的值,随机将其中一些(激活值)置为0,然后在网络中前进。如果我们把左边这个全连接网络和右边经过dropout的版本进行对比,我们发现dropout的网络像是同样的网络变小了一号,因为我们只用到了一部分的神经元。并且每次正向传递都是不同的部分。
        这个方法为什么可取?

         一个解释是人们觉得dropout避免了特征间的相互适应,假设我们要分类判断是不是猫?可能有一个神经元学习到了有一只耳朵,一个学习到了尾巴,一个学到了输入图像有毛
,将这些条件组合在一起来判断是不是猫。但现在加入drop之后我们判断是否是猫的时候,就是靠零散的特征来判断,这也许某种程度上抑制了过拟合。

        另一个解释是这是在单一模型中运行集成学习。

        那dropout是如何在测试集上面表现的呢?

        当我们使用了dropout后,我们把神经网络基本的运算都改变了,之前我们的神经网络里有权重w的函数f,输入x得到y,但我们选择有了一个输入z表示dropout中被置零的项(z是随机的),测试时引入一些随机性可能不是一个好主意。

        我们考虑单个神经元输出是a,然后在测试时我们得到a的值是w_1x+w_2y,在训练期间我们使用了dropout丢弃神经网络单元的概率是0.5,现在这个例子中训练期间的期望值可以算出解析解,我们将通过这四个掩码得到的值进行平均:

E(a) =\frac{1}{4}(w_1x+w_2y)+\frac{1}{4}(w_1x+0\cdot y)+\frac{1}{4}(0\cdot x+w_2y) + \frac{1}{4}(0\cdot x+0y)

         我们在测试时没有任何的随机性,而是用dropout的概率乘以这个输出现在这些期望值是一样的。

         总结起来dropout在正向传播中非常简单,只需要随机添加几行代码随机对一些节点置0。在测试时的预测函数内仅仅增加了一点点乘法。

         我们也可以采用反转dropout的方法让我们更快的运行在测试中:

         还有一种dropout相关的算法叫做dropconnect,它不是在每次正向传播中将激活函数置零而是随机将权重矩阵的一些值置零,它们有一样的效果。

4. 迁移学习

        加入不同正则策略可以帮助减小训练误差和测试误差的间隙,过拟合另外的一个原因是由于数据不够导致的。我们希望得到一个大的模型,但小数据集合时很容易过拟合,正则化是一种很好的方法,另一种方法就是迁移学习。

        迁移学习使我们不再需要超大的样本集。

        它的思想很简单,首先找到一些卷积神经网络在一个非常大的数据集训练例如ImageNet(可以解决100种物体的分类),现在你想尝试的想法是把从这个数据集训练出的提取特征的能力用到我们更感兴趣的小的数据集上(比如狗的分类),接着我们的做法是修改从最后一层的特征到最后的分类输出之间的全连接层,我们要重新随机初始化这部分矩阵,对于ImageNet它是4096乘以1000,对于我们新的分类,矩阵大小变为4096乘以C例如10或者任何一个数,重新随机初始化最后的矩阵并冻结前面层的权重,现在我们只需要训练一个线性分类器(最后一层)让它在我们的数据上收敛,当你只处理一个小的数据集的时候这会让我们的工作很完美!

        当我们的时间数据更长一些的话,我们可以试着将学习率调低(最初的网络参数可能是在ImageNet上收敛的,其泛化能力已经很强了,我们只需要它有很小的调整来适应我们的训练集)并训练更多层(自上而下)。

        当我们使用迁移学习时,可以想成是一个2乘以2的情景网格:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/80361.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

一篇文章带你了解python数据分析岗位怎么样

前言 嗨喽,大家好呀~这里是爱看美女的茜茜呐 又到了学Python时刻~ 分析目标 各城市对数据分析岗位的需求情况 不同细分领域对数据分析岗的需求情况 数据分析岗位的薪资状况 工作经验与薪水的关系 公司都要求什么掌握什么技能 岗位的学历要求高吗 不同规模的…

详解C语言中的自定义类型(结构体,枚举,联合)

目录 1. 结构体 1.1 结构的声明 1.2 结构的自引用 1.3 结构体变量的定义和初始化 1.4 结构体内存对齐 (计算结构体的大小) 1.5 结构体传参 2. 位段(结构体实现位段) 2.1 什么是位段 2.2 位段的内存分配 2.3 位段的跨平台问题 3. 枚举 …

node.js-http模块学习

目录 1.什么是 http 模块 2.进一步理解 http 模块的作用 3.用node.js创建最基本的 web 服务器 req 请求对象: res 响应对象: 解决中文乱码问题: 根据不同的url响应 不同的html页面 1.什么是 http 模块 http 模块是 Node.js 官方提供的、…

3.Nacos系列之配置管理

上文中我们学习到服务的注册&#xff0c;本文我们进行服务的调用及配置管理相关的实践 1. 服务调用实践 接着上篇文章的代码&#xff0c;我们新建模块nacos-service-consumer 在pom.xml目录下新增依赖 <dependencies><dependency><groupId>org.springfra…

Bean 作用域和生命周期 · Bean 作用域存在的问题 · Bean 六种作用域 · 执行流程 · 生命周期演示

Spring 是用来存储和读取 Bean&#xff0c;因此 Spring 中 Bean 是最核心的操作资源&#xff0c;我们需要深入学习一下 Bean 对象。 一、Bean 的作用域问题1.1 原因分析1.2 作用域定义二、Bean 的六种作用域singleton 单例作用域prototype 原型作用域request 请求作用域session…

【OpenCV学习】第16课:图像边缘提取 - Sobel算子详细剖析(图像梯度)

仅自学做笔记用,后续有错误会更改 理论 卷积的应用 - 图像边缘提取&#xff1a; 边缘是什么&#xff1a;是像素值发生跃迁的地方&#xff0c; 是图像的显著特征之一&#xff0c; 再图像特征提取丶对象检测丶模式识别等方面都有重要作用如何捕捉/提取边缘&#xff1a;对图像求…

关于LuaGC算法的演化概述

2年不用&#xff0c;就忘了&#xff0c;在这记录下。 5.0版本的双色标记清除算法 此算法中&#xff0c;每个对象会有两种标记态&#xff1a;白色和黑色&#xff1b;新创建的对象都是白色 过程&#xff1a; 1.初始化阶段&#xff1a;将root链表中的所有对象放入待检链表中&am…

0204隐函数及由参数方程所确定的函数的导数相关变化率-导数与微分

1 隐函数 定义&#xff1a;设有两个非空数集A,BA,BA,B.对于∀x∈A\forall x\in A∀x∈A&#xff0c;由二元方程F(x,y)0F(x,y)0F(x,y)0对应唯一的y∈By\in By∈B,称此对应关系是二元方程F(X,y)0F(X,y)0F(X,y)0确定的隐函数。 相应的由yf(x)yf(x)yf(x)确定的对应关系称为显函数。…

vue.js:作用域插槽的使用案例

作用域插槽的使用理解 父组件替换插槽的标签&#xff0c;但是内容是由子组件提供的。 案例需求 子组件中包含一组数据&#xff0c;比如&#xff1a;pLanguages&#xff1a;[‘Java’,‘c’,‘JavaScript’,‘python’,‘C语言’,‘Go’,‘C#’]现需要在多个页面进行操作&…

19.8 适配器概念、分类、范例与总结

一&#xff1a;适配器基本概念 把一个既有的东西进行适当的改造&#xff0c;比如增加点东西&#xff0c;或者减少点东西&#xff0c;就构成了一个适配器。 三种适配器&#xff1a;容器适配器、算法适配器、迭代适配器。 二&#xff1a;容器适配器 本章第三节学习过双端队列de…

个人有效:关于VMware虚拟机开机蓝屏问题的解决

文章目录前言禁用Hyper-V等服务Device 服务等启动相关是否需要VMware最新版本电脑虚拟化问题启用或关闭windows功能的设置关于VMware虚拟机的卸载参考前言 搜了海量文章&#xff0c;实操过大部分的方法&#xff0c;一顿折腾、最后莫名其妙的能跑了…。~~两天来急痛攻心&#xf…

Hot100-寻找重复数

1 前言 给定一个包含 n 1 个整数的数组 nums &#xff0c;其数字都在 [1, n] 范围内&#xff08;包括 1 和 n&#xff09;&#xff0c;可知至少存在一个重复的整数。 假设 nums 只有 一个重复的整数 &#xff0c;返回 这个重复的数 。 1.1 暴力解法 两次for循环&#xff1a…

spring——AOP面向切面编程—— 一般切面的 AOP 开发

一般切面的 AOP 开发 当我们在使用 Spring AOP 开发时&#xff0c;若没有对切面进行具体定义&#xff0c;Spring AOP 会通过 Advisor 为我们定义一个一般切面(不带切点的切面)&#xff0c;然后对目标对象(Target)中的所有方法连接点进行拦截&#xff0c;并织入增强代码。 工程依…

Pytest----测试脚本上传git代码仓库

【原文链接】Pytest----测试脚本上传git代码仓库 在企业实战中&#xff0c;自动化测试脚本也要放在代码管理平台的&#xff0c;可以选择第三方公共的git代码托管平台&#xff0c;比如github、gitee等&#xff0c;当然也可以在企业内部搭建gitlab作为代码托管平台&#xff0c;他…

蓝桥杯模拟赛习题练习(一)

题目来源&#xff1a;第十四届蓝桥杯模拟赛第一期 注&#xff1a;代码都是自己写的&#xff0c;不是参考答案&#xff01; 1. 二进制位数 问题描述&#xff1a; 十进制整数2在十进制中是1位数&#xff0c;在二进制中对应10 &#xff0c;是2位数。 十进制整数22在十进制中是2位…

Linux系统调用实现简析

1. 前言 限于作者能力水平&#xff0c;本文可能存在的谬误&#xff0c;因此而给读者带来的损失&#xff0c;作者不做任何承诺。 2. 背景 本篇基于 Linux 4.14 ARM 32 glibc-2.31 进行分析。 3. 系统调用的实现 3.1 系统调用的发起 3.1.1 起于用户空间 我们随意挑选一个…

python学习之:妙用魔法函数 __dict___来调用对象中的方法,或者 python文件中的方法

文章目录场景原始写法升级写法面向对象的写法总结场景 原始写法 假设现在有一个文件 tool.py我想在外部输入一个 字符串 就调用这个字符串对应的函数如果你不是用 __dict__ 这个好用的函数&#xff0c;那么你大概率会以下面的方式去写 main 函数&#xff0c;给很多 if但是如果…

网络安全观察报告 态势总览

执行摘要 从 1987 年 9 月 14 日&#xff0c;中国向世界发出第一封电子邮件 到如今&#xff0c;中国的互联网发展已过去整整 31 个年头。从消费互联、产业互联到万物互联&#xff0c;互联网正在加速改变我们的交流方式和交易方式&#xff0c;一次次 004.重塑了国家的经济形态和…

创建型 - 单例模式(Singleton pattern)

单例模式&#xff08;Singleton Pattern&#xff09;&#xff1a;确保一个类有且只有一个实例&#xff0c;并提供一个全局访问点。 文章目录懒汉式-线程不安全饿汉式-线程安全懒汉式-线程安全双重校验锁-线程安全静态内部类实现枚举实现实现方式总结使用场景JDK懒汉式-线程不安…

论文(world、WPS)插入参考文献引用详细教程

一、参考资料 如何在WPS中添加论文参考文献 【Word】怎样给论文添加引用参考文献 word添加各种引用 二、相关介绍 1. 参考文献的标注 参考文献的标注分为全部引用、局部引用、间接引用。 1.1 全部引用&#xff08;直接引用&#xff09; 需要双引号&#xff0c;无论冒号…