Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >深入机器学习的梯度优化

深入机器学习的梯度优化

作者头像
算法进阶
发布于 2022-06-02 04:36:04
发布于 2022-06-02 04:36:04
4380
举报
文章被收录于专栏:算法进阶算法进阶

简介

机器学习在选定模型、目标函数之后,核心便是如何优化(目标)损失函数。而常见的优化算法中,有梯度下降、遗传算法、模拟退火等算法,其中用梯度类的优化算法通常效率更高,而使用也更为广泛。接下来,我们从梯度下降(Gradient descent)、梯度提升(Gradient Boosting)算法中了解下“梯度”优化背后的原理。

一、梯度

我们先引出梯度的定义:

梯度是一个矢量,其方向上的方向导数最大,其大小正好是此最大方向导数

简单对于二维的情况,梯度也就是曲线上某点的切线斜率,数值就是该曲线函数的导数,如y=x^2^ ,求导dy/dx=2x

扩展到3维(多维),各点方向导数是无限多(一个平面),梯度也就是方向导数最大的方向,数值即对多元函数各参数求偏导数,如y=x^2^ + 3z^2^ ,求x偏导dy/dx=2x,求z偏导dy/dz=6z。

换句话说,沿着函数(曲线)的任意各点位置取梯度相反的方向,如y=x^2^ + 3z^2^ 的负梯度-(2x, 6z),也就是多元函数下降最快的地方,越容易找到极值。这也就是梯度下降算法的基本思想。

二、梯度下降算法

2.1 梯度下降的基本原理

梯度类的优化算法,最为常用的就是随机梯度下降,以及一些的升级版的梯度优化如“Adam”、“RMSP”等等。

如下介绍梯度下降算法的基本原理:

首先可以将损失函数J(w)比喻成一座山,我们的目标是到达这座山的山脚(即求解出最优模型参数w使得损失函数为最小值)

这时,梯度下降算法可以直观理解成一个下山的方法。

下山要做的无非就是“往下坡的方向走,走一步算一步”,而在损失函数这座山上,每一位置的下坡的方向也就是它的负梯度方向(直白点,也就是山各点位置的斜向下的方向)。每往下走到一个位置的时候,代入当前样本的特征数据求解当前位置的梯度,继续沿着最陡峭最易下山的位置再走一步。这样一步步地走下去,一直走到山脚(或者山沟沟)。

当然这样走下去,有可能我们不是走到山脚(全局最优,Global cost minimun),而是到了某一个的小山谷(局部最优,Local cost minimun),这也后面梯度下降算法的可进一步调优的地方。对应的算法步骤,直接截我之前的图:

与梯度下降一起出现的还有个梯度上升,两者原理一致,主要是术语的差异。简单来说,对梯度下降目标函数取负数,求解的是局部最大值,相应需要就是梯度提升法。

2.2 梯度下降的数学原理——泰勒展开

本节会通过泰勒展开定理,"推导"得出梯度下降

首先引出泰勒展开原理,它是种计算函数某点的近似值的方法,通过多个多项式拟合某一函数f(x)。泰勒多项式展开的项数越多,拟合的越好

  • 1、回到我们的损失函数J,做个一阶的泰勒展开近似:(其中θ-θ0越小越近似)
  • 2 其中θ−θo是微小矢量,做一下变换,θ-θ0以λ*d替代(λ为向量长度,d为单位向量),可得:
  • 3、计算后式的向量乘积,可得:(theta为梯度与d向量的夹角)
  • 4、上式中,我们希望J(θ) 越小越好,而J(θo)为常量,所以我们希望后项越小越好,当cos(180)=-1可以取到最小值,意味着梯度与d单位向量的夹角为相反的,也就是需要d为负梯度方向:
  • 5、进一步的,将d代入式子:θ-θo = λ*d,就可以得到梯度下降公式的雏形(其中λ及1/||J'||为常数可以改写为常用的学习率α),优化后的θ也就是:

三、梯度提升算法

说到梯度提升(Gradient Boosting),要注意的是和上文谈到的梯度上升不是一个概念。

梯度提升是一种加法模型思想(Fm = Fm-1 + hm, 同上泰勒定理,hm应为负梯度),不像梯度下降直接利用负梯度更新模型参数,梯度提升是通过各弱学习器去学习拟合负梯度的,在进一步累加弱学习器,来实现损失函数J的负梯度方向优化。

梯度提升算法很像是一个“打高尔夫,不断补杆”的过程,基本思路是弱学习器一个接着学习上一个学习器的残差或负梯度(没学习好的内容),最终得到m个弱学习器h0..hm一起决策。(注:对于平方损失函数, 其负梯度刚好等于残差。我们通过直接拟合负梯度可以扩展到更为复杂的损失函数。

举个简单例子,假如我们的目标值是【100】,当第一个弱学习器h0学习目标值100,实际输出y^只有【60】,和实际y还是有偏差的,残差值y^ - y,第二个学习器h1继续学习拟合之前的残差(或者负梯度),学习剩下的【100-60】,并实际输出【50】...依次学习到第h2个弱学习器拟合之前的残差【100-60-50】,这时比较准确地输出【-10】,达到较好的拟合结果,算法结束。整个模型的表示就是Fm = h0 + h1 + h2 = 60 + 50 - 10 => 100。如下图具体算法:

后记

在优化领域,梯度优化方法无疑是简单又极有效率的,但不可避免的是它通常依赖着有监督标签,且得到的是近似最优解。不可否认,在优化的道路上,我们还有很长的一段路要走。

参考文献: https://zhuanlan.zhihu.com/p/45122093 https://zhuanlan.zhihu.com/p/82757193 https://www.zhihu.com/question/63560633

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-05-17,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 算法进阶 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Go的代码规范指南-新人必看
环境设置:*nix环境或者Mac环境,安装go语言目录,默认是usr/local/go,如果想要让代码运行,需要将项目放到usr/local/go/src目录下,如果忘记了go的配置目录,可以通过go env查看go的环境变量设置。如果不希望每次使用sudo权限执行,可以通过设置用户目录下创建~/.bashrc文件,增加 用户目录的环境变量设置比如
小诚信驿站
2019/10/01
1.9K0
Go的代码规范指南-新人必看
常用Golang工具类函数实现(二)
在使用Golang开发中,标准库提供了很多好用的函数可以帮助我们快速的实现一些功能。但是相对于其他语言来说,还是有很多好用且常用的函数或者方法,是没有被加入到标准库的,这里就需要我们自己的来实现。
KunkkaWu
2023/08/10
6250
常用Golang工具类函数实现(二)
golang struct转化成map
现在介绍的反射的方式,其中需要注意的是,反射不能够获取struct中没有被暴露出的变量(小写开头的变量)。
Java架构师必看
2021/05/14
6790
Go 每日一库之 testify
testify可以说是最流行的(从 GitHub star 数来看)Go 语言测试库了。testify提供了很多方便的函数帮助我们做assert和错误信息输出。使用标准库testing,我们需要自己编写各种条件判断,根据判断结果决定输出对应的信息。
用户7731323
2021/08/20
1.9K0
使用 Golang 正确处理五大互联网注册机构的 IP 数据
上个月,我写了一篇文章《正确处理全球五大互联网注册机构的 IP 数据》,来介绍如何处理全球五大互联网注册机构所提供的 IP 数据。
soulteary
2022/07/16
4150
使用 Golang 正确处理五大互联网注册机构的 IP 数据
Golang fasthttp实践
原计划学完Golang语言HTTP客户端实践之后,就可以继续了,没想到才疏学浅,在搜资料的时候发现除了Golang SDK自带的net/http,还有一个更牛的HttpClient实现github.com/valyala/fasthttp,据说性能是net/http的10倍,我想可能是有点夸张了,后期我会进行测试,以正视听。
FunTester
2021/10/22
4.1K0
Golang单元测试
Go提供了test工具用于代码的单元测试,test工具会查找包下以_test.go结尾的文件,调用测试文件中以 Test或Benchmark开头的函数并给出运行结果
仙人技术
2021/08/31
8250
Golang单元测试
Go语言实战笔记(二十一)| Go 单元测试
相信我们做程序员的,对单元测试都不陌生。单元测试一般是用来测试我们的代码逻辑有没有问题,有没有按照我们期望的运行,以保证代码质量。
飞雪无情
2018/08/28
7420
Go语言实战笔记(二十一)| Go 单元测试
Go 单测入门篇:Golang 单元测试基本使用
Go 语言的单元测试默认采用官方自带的测试框架,通过引入 testing 包以及 执行 go test 命令来实现单元测试功能。
Allen.Wu
2023/03/01
1.4K0
Go 单测入门篇:Golang 单元测试基本使用
golang源码阅读:test2json
go test加参数-json就能输出 json格式,下面我们用一个简单的例子看下对他进行分析,然后分析下相关源码。对于单测
golangLeetcode
2023/09/06
1880
golang源码阅读:test2json
Go每日一库之112:asynq
Asynq是一个go语言实现的分布式任务队列和异步处理库,基于redis,类似sidekiq和celery,他具有以下特点:
luckpunk
2023/09/30
1.4K0
Go单测系列2—网络测试
这是Go语言单元测试从零到溜系列教程的第1篇,介绍了如何使用httptest和gock工具进行网络测试。
luckpunk
2023/09/10
4700
常用Golang工具类函数实现(一)
在使用Golang开发中,标准库提供了很多好用的函数可以帮助我们快速的实现一些功能。但是相对于其他语言来说,还是有很多好用且常用的函数或者方法,是没有被加入到标准库的,这里就需要我们自己的来实现。
KunkkaWu
2023/08/10
6720
常用Golang工具类函数实现(一)
PHP转Go速学手册
整理了一份简要的手册,帮助大家高效的上手Go语言,主要是通过对比PHP和Go的不同点来强化理解,内容主要分为以下四部分:
用户1093396
2021/07/28
2.3K0
golang--单元测试综合实例
(2)Monster有一个Store方法,可以将一个Monster对象序列化后保存在文件中;
西西嘛呦
2020/08/26
3370
Go语言——测试与性能
​ 作为一名合格的开发者,不应该在程序开发完之后才开始写测试代码。使用 Go 语言的测试 框架,可以在开发的过程中就进行单元测试和基准测试。和 go build 命令类似,go test 命 令可以用来执行写好的测试代码,需要做的就是遵守一些规则来写测试。而且,可以将测试无缝 地集成到代码工程和持续集成系统里。
传说之下的花儿
2023/04/16
1.2K0
Go单测系列5—使用monkey打桩
这是Go语言单元测试从零到溜系列教程的第4篇,介绍了如何在单元测试中使用monkey进行打桩。
luckpunk
2025/01/18
900
Go每日一库之79:testing
testing是 Go 语言标准库自带的测试库。在 Go 语言中编写测试很简单,只需要遵循 Go 测试的几个约定,与编写正常的 Go 代码没有什么区别。Go 语言中有 3 种类型的测试:单元测试,性能测试,示例测试。下面依次来介绍。
luckpunk
2025/01/18
650
Go语言JSON 处理
struct能被转换的字段都是首字母大写的字段,但如果想要在json中使用小写字母开头的key,可以使用struct的tag来辅助反射。
王小明_HIT
2021/10/11
8920
Go test 单元测试用起来
单元测试,咱们平时也叫它单测,平时开发的时候,也需要写一些 demo 来测试我们的项目中的函数或者某个小功能
阿兵云原生
2023/02/16
2560
相关推荐
Go的代码规范指南-新人必看
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档