(CV学习笔记)梯度下降优化算法
梯度下降法
- 梯度下降法是训练神经网络最常用的优化算法
梯度下降法(Gradient descent)是一个 ==一阶最优化算法== ,通常也称为最速下降法。要使用梯度下降法找到一个函数的 ==局部最小值==,必须想函数上当前点对应的==梯度==(或者是近似梯度)的反方向的规定部长距离点进行==迭代==搜索。
梯度下降法基于以下的观察:如果实值函数$f(x)$在a点处==可微==并且有定义,那么函数$f(x)$在点a沿着==梯度==相反的方向$-\nabla f(a)$下降最快
$$\theta = \theta -\eta \cdot \nabla _{\theta}J(\theta)$$
偏导数
对于一个多元函数,比如$f(x,y)=x^2y$,计算偏导数:
将不求的部分当做常数,其他部分求导即可。

梯度
The gradient of a scalar-valued multivariable function $f(x,y,...)$,denoted $\nabla f$,packages all its partial derivative information into a vector:

这就意味着$\nabla f$是一个向量。
梯度下降算法
在每一个点计算梯度,向梯度相反的方向移动指定的步长,到达下一个点后重复上述操作。

批处理梯度下降法
有两层循环,伪代码如下:
for i in range (nb_epochs):
#最外层循环用来不断更新参数。
sum_grad = 0 #定义变量梯度求和,注意此处应为向量,而非实数值
for x, y in data: #x是训练数据的输入,y是label
grad = gradient(loss_function, x, y, params)
#x,y,params是损失函数的参数
# params 是参数,可以是卷积核的权值或者神经网络的权值
sum_grad += grad
avg_grad = sum_grad/len(data)
#获得平均梯度
params = params - learning_rate * avg_grad
#learning_rate是步长,或称为学习率
特点
- 在==凸优化(Convex Optimization)==的情况下,一定会找到==最优解==
- 在==非凸优化==的情况下,一定能找到==局部最优解==
- 单次调整==计算量大==
- 不适合==在线(Online)==情况
随机梯度下降法
有两层循环,伪代码如下:
for i in range(nb_epochs):
np.random.shuffle(data)
for x, y in data: #x是训练数据的输入,y是label
grad = gradient(loss_function, x, y, params)
#x,y,params是损失函数的参数
# params 是参数,可以是卷积核的权值或者神经网络的权值
params = params - learning_rate * avg_grad
#learning_rate是步长,或称为学习率
与批处理相比,梯度更新在第二个循环内部,所以参数更新次数增多了。
每一次循环前有一次==shuffle==,遍历的顺序是随机的。
特点
- 适合==Online==的情况
- 通常比批处理下降法==快==(在批处理的情况下,有可能许多数据点产生的梯度是相似的,属于冗余运算,并没有实际帮助)
- 通常目标函数==震荡严重==,在神经网络优化情况下(没有全局最优解),这种震荡反而有可能让它避免被套牢在一个局部最小值,而找到更好的==局部最优解==

- 通过调整学习率,能够找到和批处理相似的局部或者全局最优解
迷你批处理梯度下降法
有三层循环,伪代码如下:
for i in range(nb_epochs):
np.random.shuffle(data)
for mini_batch in get_mini_batch(data, batch_size = 50):
#batch_size 表示mini_batch的数量
sum_grad = 0
#定义变量梯度求和,注意此处应为向量,而非实数值
for x, y in mini_batch:
#x是训练数据的输入,y是label
grad = gradient(loss_function, x, y, params)
#x,y,params是损失函数的参数
# params 是参数,可以是卷积核的权值或者神经网络的权值
sum_grad += grad
avg_grad = sum_grad/len(data)
#获得平均梯度
params = params - learning_rate * avg_grad
#learning_rate是步长,或称为学习率
特点
- 结合了批处理和随机梯度下降法的优点
- 减弱了目标函数震荡,更加==稳定==
- 易于==硬件加速==实现,常用的机器学习库都利用了这个特性提供了高性能的计算速度(mini批可能能够放入GPU显存或者内存)
- 一般的迷你批大小位==50至256==,取决于不同的应用
传统梯度下降法面临的挑战
- 传统迷你批处理不能保证能够收敛
- 当学习率太小,收敛会很慢,学习率太高,容易震荡,甚至无法收敛
- 可以按照某个公式随着训练逐渐减小学习率,但是不同数据集需要不同的学习率变化曲线,不容易估计
- 所有的参数使用同样的学习率并不合适
- 容易被套牢在马鞍点(Saddle point)

马鞍点
在马鞍点处,梯度为0,但是不是最优解。不同算法有些能够逃离,有些不能逃离。

在这种马鞍点中,Adadelta较容易逃离,NAG、Rmsprop、Adagrad、Momentum都可以逃离,随机梯度下降法(SGD)无法逃离。

常见的梯度下降法
Momentu(动量法)
- 不同的dimension的变化率不一样
动量在梯度的某一纬度上的投影只想同一方向上的增强,在纬度上的指向不断变化的方向抵消
$v_t = \gamma v_{t-1}+\eta \nabla _{\theta}J(\theta)$
$\theta = \theta - v_t$
$\gamma :=0.9$
以中药碾子为例:

假设中心凹槽为曲面,那么最优值应该在中心位置:
如果不引入Momentum,那么训练过程中,移动方向会不断向两侧跳跃:

如果引入Momentum:

为什么能达到这样的效果
将曲面画作山谷形状,理想情况下是蓝色曲线的路径:

但是在传统算法,那么运动的曲线为红色曲线。如果我们将每一个点按照参数方向进行分解:

在每一点都进行分解:

可以看到,任何一点都有一个分方向与最优方向同向,另一个分方向会与下一个分方向部分抵消。这样最优方向的分向会增加,其他方向会逐渐抵消。
Nesterov accelerated gradient
- 动量+预测前方的梯度
在多个RNN任务中表现突出
$v_t = \gamma v_{t-1}+\eta \nabla {\theta}J(\theta -\gamma v{t-1})$
$\theta = \theta - v_t$

小结
上面两种优化算法都是对梯度本身的优化,整体优化,下面的几种方法将采用对参数“各个击破的方式”来实现优化。
Adagrad
- 对重要性高的参数,采用小的步长
- 对相对不重要的参数,采用大的步长
- 对稀疏数据集非常有效(文本数据)。Google在训练从Youtube识别自动识别猫采用的就是这种方法,Pennington et al训练词嵌入的GloVe也采用的这种方法
实现方法
$g_{t,i} = \nabla J(\theta _t , I)$
$\theta {t+1},I = \theta ,I- \frac{\eta}{\sqrt{G{t,ii}+\epsilon}}\cdot g_{t,i}$
关键在于分母,$G_t$是一个$d\times d$对角矩阵,d表示参数的个数。$G_{t,ii}$表示第$i$个参数位置的值
$G_{t,ii}=({\theta i})_t ^2+({\theta _i}){t-1}^2+...$
为了防止G为0,加入另外一个很小的值$\epsilon$
优势
- 无需手动调整步长
设置初始值为0.01即可
劣势
- 随着训练,步长总是越来越小
Adadelta
- 只累积过去一段时间的梯度平方值
- 完全无需设置步长
- 为了便于实现,采用类使用动量的策略:

实现方法




RMSprop
与上面两种方法几乎一致,把过去结果乘0.9,当前结果乘0.1

公式不同,思路相似
Adam
- 使用最广泛的方法
- 记录一段时间的梯度平方和(累死Adadelta和RMSprop),以及梯度的和(类似Momentum动量)
- 把优化看做铁球滚下山坡,Adam定义了一个带动量和摩擦的铁球
实现方法


更新权值采用原来的权值减去某一梯度的变形
如何选择
- 如果数据集是稀疏的,选择自适应学习率的方法会更快的收敛
- RMSprop,Adadelta,Adam的效果非常相似,大多数情况下Adam略好
小技巧
- 每一个epoch之前重新洗牌数据
- 使用Batch Normalization
- 我们一般会对训练数据做正则化,但是随着数据的前馈,后面layers的输入已经不是正则化的了,Batch Normalization就是在后面layer之间做正则化
- 使得训练可使用更大的学习率,layer参数的初始化可以更加随意
- BN还有regularization的作用,可以减少对Dropout的依赖
- Early Stopping:Early stopping (is) beautiful free lunch (NIPS 2015 Tutorial slides ,slide 63)
增加随机噪声到梯度
使得layer参数初始化更加随意
使得model可以找到新的局部最小值

(CV学习笔记)梯度下降优化算法的更多相关文章
- 梯度下降优化算法综述与PyTorch实现源码剖析
现代的机器学习系统均利用大量的数据,利用梯度下降算法或者相关的变体进行训练.传统上,最早出现的优化算法是SGD,之后又陆续出现了AdaGrad.RMSprop.ADAM等变体,那么这些算法之间又有哪些 ...
- 采用梯度下降优化器(Gradient Descent optimizer)结合禁忌搜索(Tabu Search)求解矩阵的全部特征值和特征向量
[前言] 对于矩阵(Matrix)的特征值(Eigens)求解,采用数值分析(Number Analysis)的方法有一些,我熟知的是针对实对称矩阵(Real Symmetric Matrix)的特征 ...
- Introduction to 3D Game Programming with DirectX 12 学习笔记之 --- Direct12优化
原文:Introduction to 3D Game Programming with DirectX 12 学习笔记之 --- Direct12优化 第一章:向量代数 1.向量计算的时候,使用XMV ...
- 机器学习实战(Machine Learning in Action)学习笔记————08.使用FPgrowth算法来高效发现频繁项集
机器学习实战(Machine Learning in Action)学习笔记————08.使用FPgrowth算法来高效发现频繁项集 关键字:FPgrowth.频繁项集.条件FP树.非监督学习作者:米 ...
- 机器学习实战(Machine Learning in Action)学习笔记————07.使用Apriori算法进行关联分析
机器学习实战(Machine Learning in Action)学习笔记————07.使用Apriori算法进行关联分析 关键字:Apriori.关联规则挖掘.频繁项集作者:米仓山下时间:2018 ...
- 机器学习实战(Machine Learning in Action)学习笔记————02.k-邻近算法(KNN)
机器学习实战(Machine Learning in Action)学习笔记————02.k-邻近算法(KNN) 关键字:邻近算法(kNN: k Nearest Neighbors).python.源 ...
- [ML学习笔记] 朴素贝叶斯算法(Naive Bayesian)
[ML学习笔记] 朴素贝叶斯算法(Naive Bayesian) 贝叶斯公式 \[P(A\mid B) = \frac{P(B\mid A)P(A)}{P(B)}\] 我们把P(A)称为"先 ...
- logistic回归梯度上升优化算法
# Author Qian Chenglong from numpy import * from numpy.ma import arange def loadDataSet(): dataMat = ...
- Effective STL 学习笔记 31:排序算法
Effective STL 学习笔记 31:排序算法 */--> div.org-src-container { font-size: 85%; font-family: monospace; ...
随机推荐
- WDN302国产化网络存储控制模块
WDN302是一款网络存储控制模块,实现对NAS和IP-SAN的混合支持,通过以太网对海量存储的访问,实现数据的存储.共享.恢复和防丢失. 飞腾 FT1500A/16处理器,主频 1.5GHz: 支持 ...
- 24端口以太网FPGA的开发板
板卡架构 板载FPGA(K7-325T)处理24端口10/100/1000M以太网数据: FPGA外挂4Gbit的DDR3颗粒,最大支持800MHz: 板载CPU进行系统配置.管理,并与客户端软件通信 ...
- 用实战玩转pandas数据分析(一)——用户消费行为分析(python)
CD商品订单数据的分析总结.根据订单数据(用户的消费记录),从时间维度和用户维度,分析该网站用户的消费行为.通过此案例,总结订单数据的一些共性,能通过用户的消费记录挖掘出对业务有用的信息.对其他产 ...
- iOS 面试秘籍全套
栏目将持续更新--请iOS的小伙伴关注! (答案不唯一,仅供参考,文章最后有福利) iOS面试题大全(上) iOS面试题大全(下) 目录: iOS面试题:Run Loop iOS面试题:性能优化 ...
- VSCode 微信小程序扩展开发
写在前面 为什么要开发这个扩展呢,是因为微信开发者工具自身不支持页面引入组件的跳转,人工根据引入组件路径查看对应代码的方式,效率偏低.就形如这样的json文件,引入了多个组件,比如要查看 " ...
- apk动态调试
android.os.Debug类提供了isDebuggerConnected()用于检测是否有调试器链接: AndroidManifest的application节点中加入android:debug ...
- MyBatis简单的CRUD操作
Dao接口 package com.ttpfx.dao; import com.ttpfx.domain.User; import java.util.List; public interface U ...
- Github 1.9K Star的数据治理框架-Amundsen
Amundsen的使命,整理有关数据的所有信息,并使其具有普遍适用性. 这是Amundsen官网的一句话,对于元数据的管理工作,复杂且繁琐.可用的工具很多各有千秋,数据血缘做的较好的应该是Apache ...
- Docker的深入浅出
定义: Docker是一个虚拟环境容器,可以将你的开发环境.代码.配置文件等一并打包到这个容器中,并发布和应用到任意平台中. 原理: docker底层使用了LXC来实现,LXC将linux进程沙盒化, ...
- Kafka又出问题了!
写在前面 估计运维年前没有祭拜服务器,Nginx的问题修复了,Kafka又不行了.今天,本来想再睡会,结果,电话又响了.还是运营,"喂,冰河,到公司了吗?赶紧看看服务器吧,又出问题了&quo ...