【深度学习】网络训练的原理:什么是梯度下降?学习率的作用是什么?
对于输入 x x x,通过某个网络后给出预测的结果 y y y,但是其正确结果为 y ^ \hat y y^,预测结果和真实结果之间的差距我们称之为损失 L L L
这里要注意,衡量二者之间的差距的方法有很多,如曼哈顿距离( L 1 L_1 L1范数)、欧氏距离( L 2 L_2 L2范数)等,为考虑一般性,我们设为function C C C,它可以是任意衡量二者之间的差距的函数
显然这个误差值是与网络的参数有关的,因为网络参数决定了网络输出值,即 L ( θ ) = C ( y , y ^ ) L(\theta)=C(y,\hat y) L(θ)=C(y,y^),那么此时我们就需要调整网络的参数,我们训练网络的核心思想就是 使网络输出的结果 y y y 能够尽可能接近真实值 y ^ \hat y y^,即我们的优化目标是:
a r g m i n θ L ( θ ) \mathop{\mathrm{arg~min}}\limits_{\theta}~{L(\theta)} θarg min L(θ)
简单的说,我们想求能使函数 L ( θ ) L(\theta) L(θ)函数值最小的 θ \theta θ值:
- 如果它是个一元函数,例如 L ( θ ) = θ 2 L(\theta)=\theta^2 L(θ)=θ2(这个其实就相当于 y ( x ) = x 2 y(x)=x^2 y(x)=x2,换换表示而已),对于一元函数求最值,一般方法就是对自变量求导使其导函数为0,求出驻点和极值点,对比极值的大小得到最小值
- 如果它是个多元函数,此时 θ \theta θ就是个向量,例如 L ( θ ) = θ 1 2 + θ 2 2 L(\theta)=\theta_1^2+\theta_2^2 L(θ)=θ12+θ22(同理,相当于 z ( x , y ) = x 2 + y 2 z(x,y)=x^2+y^2 z(x,y)=x2+y2),对于多元函数求最值,一般方法就是对多个自变量分别求偏导使其偏导函数为0,求出驻点和极值点,对比极值的大小得到最小值
驻点的定义:使一阶导数等于0的点,这里的导数也就是“导函数”
上面的两种方法都提到了一样东西:导数和梯度,我们需要深入理解一下这到底是个什么东西
首先来看导数,给定函数 f ( x ) f(x) f(x) 在特定点 x 0 x_0 x0 处的导数定义为 f ′ ( x 0 ) = lim Δ x → 0 f ( x 0 + Δ x ) − f ( x 0 ) Δ x f'(x_0)=\lim_{\Delta x\to0}\frac{f(x_0+\Delta x)-f(x_0)}{\Delta x} f′(x0)=limΔx→0Δxf(x0+Δx)−f(x0),表示在该点处的瞬间变化率(也叫瞬间斜率),如果这个值越大,就表明其上升趋势越强劲。当这个值为0时,就达到了这个函数的“强弩之末”,即达到了极值点。
注意导数值反映的是函数的 上升 趋势,那么它所指的方向也就是 能使函数值增长的自变量的变化方向
举一个非常简单的例子: y = x 2 y=x^2 y=x2,是个一元函数,那么 x x x变化的方向就是一维的,要么正要么负
其导函数 y ′ = 2 x y'=2x y′=2x,在 x 0 = 1 x_0=1 x0=1时其导函数值为 2 2 2,那么其导数方向就是 2 2 2所指的方向(即 x x x轴正半轴), x x x沿着这个方向走的时候函数值是增长的;同理,在 x 0 = − 1 x_0=-1 x0=−1时其导函数值为 − 2 -2 −2,那么其导数方向就是 − 2 -2 −2所指的方向(即 x x x轴负半轴), x x x沿着这个方向走的时候函数值是增长的。
当自变量不只有一个时(即多元函数),就引入了梯度这个概念:给定多元函数 f ( x 1 , x 2 , ⋯ , x n ) f(x_1,x_2,\cdots,x_n) f(x1,x2,⋯,xn),在特定点 ( x 1 ( 0 ) , x 2 ( 0 ) , ⋯ , x n ( 0 ) ) (x_1^{(0)},x_2^{(0)},\cdots,x_n^{(0)}) (x1(0),x2(0),⋯,xn(0)) 处的梯度值为:
∣ ∣ ∇ f ∣ ∣ = ( ∂ f ∂ x 1 ( x 1 ( 0 ) ) ) 2 + ( ∂ f ∂ x 2 ( x 2 ( 0 ) ) ) 2 + ⋯ + ( ∂ f ∂ x n ( x n ( 0 ) ) ) 2 ||\nabla f||=\sqrt{\bigl(\frac{\partial f}{\partial x_1}(x_1^{(0)})\bigr)^2+\bigl(\frac{\partial f}{\partial x_2}(x_2^{(0)})\bigr)^2+\cdots+\bigl(\frac{\partial f}{\partial x_n}(x_n^{(0)})\bigr)^2} ∣∣∇f∣∣=(∂x1∂f(x1(0)))2+(∂x2∂f(x2(0)))2+⋯+(∂xn∂f(xn(0)))2
和导数一样,反映了在该点处的瞬间变化率(也叫瞬间斜率),如果这个值越大,就表明其上升趋势越强劲。这里我的说法有问题,实际上导数就梯度的特殊情况,我这么写是为了方便理解
梯度方向为:
∇ f = ( ∂ f ∂ x 1 ( x 1 ( 0 ) ) , ∂ f ∂ x 2 ( x 2 ( 0 ) ) , ⋯ , ∂ f ∂ x n ( x n ( 0 ) ) ) \nabla f=\bigl(\frac{\partial f}{\partial x_1}(x_1^{(0)}),\frac{\partial f}{\partial x_2}(x_2^{(0)}),\cdots,\frac{\partial f}{\partial x_n}(x_n^{(0)})\bigr) ∇f=(∂x1∂f(x1(0)),∂x2∂f(x2(0)),⋯,∂xn∂f(xn(0))),当 ( x 1 , x 2 , ⋯ , x n ) (x_1,x_2,\cdots,x_n) (x1,x2,⋯,xn)沿着这个方向走的时候,函数值是增加的
总结一下:对于函数的某个特定点,它的梯度就表示:从该点出发函数值增长最为迅猛的方向(direction of greatest increase of a function)
既然梯度方向是函数值增加的方向,那么自变量沿着这个方向走下去,函数值就会越来越大。反之,梯度的反方向就是函数值减小的方向,沿着梯度的反方向走下去,函数值就会越来越小
再思考我们一开始提出的优化问题,想要使网络输出的结果 y y y 能够尽可能接近真实值 y ^ \hat y y^,我们就需要 a r g m i n θ L ( θ ) \mathop{\mathrm{arg~min}}\limits_{\theta}~{L(\theta)} θarg min L(θ),即求能使函数 L ( θ ) L(\theta) L(θ)函数值最小的 θ \theta θ值,但是通常我们的损失函数都极其复杂,想要通过代数方法寻找其解析解是不可能的
那么,我们为 θ \theta θ给定一个初始的特定值,不断求其梯度,并使 θ \theta θ不断沿着梯度方向的反方向(即 − ∇ L -\nabla L −∇L)变化,就能使函数 L ( θ ) L(\theta) L(θ)的值越来越小,直至我们找到我们所需的最小值,这就是所谓的“梯度下降”
梯度下降:让自变量沿着梯度的反方向变化,使损失函数值不断下降
在之前的内容中,只说明自变量沿着梯度方向的反方向变化,就能使函数值越来越小,那么变化的具体大小是多少呢?这就与梯度值和超参数学习率有关。
之前的内容也写到了,没有单位化的梯度方向实际就是函数对各个自变量在某个特定点的偏导数值,那么如何进行梯度下降?
一个最朴素的想法就是让自变量沿着梯度方向下降一个单位长度,即:
θ i = θ i − 1 ∣ ∣ ∇ L ∣ ∣ ∂ L ∂ θ i ( θ i ( i − 1 ) ) \theta_i=\theta_i-\frac{1}{||\nabla L||}\frac{\partial L}{\partial \theta_i}(\theta_i^{(i-1)}) θi=θi−∣∣∇L∣∣1∂θi∂L(θi(i−1))
而由于 ∣ ∣ ∇ L ∣ ∣ ||\nabla L|| ∣∣∇L∣∣对任一 θ i \theta _i θi都是定值,甚至可以去掉这个用于单位化的定值,方向仍不受影响:
θ i ( k ) = θ i ( k ) − ∂ L ∂ θ i ( θ i ( k − 1 ) ) \theta_i^{(k)}=\theta_i^{(k)}-\frac{\partial L}{\partial \theta_i}(\theta_i^{(k-1)}) θi(k)=θi(k)−∂θi∂L(θi(k−1)),其中 k k k表示第 k k k次迭代
然而仔细一想就会有问题,参数过大的变化则会导致训练震荡,而且有可能跳过极小值点,导致发散,比如下图这样
因此引入学习率 α \alpha α,用以限制每次沿梯度方向走的距离
至此,就有了基本梯度下降方法进行网络参数训练的完全体形态:
- 求损失函数关于参数自变量的导数: ∂ L ( θ 0 , θ 1 , ⋯ , θ n ) ∂ θ j \frac{\partial L(\theta_0,\theta_1,\cdots,\theta_n)}{\partial \theta_j} ∂θj∂L(θ0,θ1,⋯,θn),代入具体的样本值 x x x和标签 y y y即可求出具体的导数值
- 利用上述导数值对参数 θ j , j = 1 , 2 , ⋯ , n \theta_j,j=1,2,\cdots,n θj,j=1,2,⋯,n进行更新: θ j = θ j − α ⋅ ∂ L ( θ 0 , θ 1 , ⋯ , θ n ) ∂ θ j \theta_j=\theta_j-\alpha\cdot \frac{\partial L(\theta_0,\theta_1,\cdots,\theta_n)}{\partial \theta_j} θj=θj−α⋅∂θj∂L(θ0,θ1,⋯,θn)
- 重复1和2的过程,直至 θ j \theta_j θj基本不再变化(此时也意味着 ∂ L ( θ 0 , θ 1 , ⋯ , θ n ) ∂ θ j ≈ 0 \frac{\partial L(\theta_0,\theta_1,\cdots,\theta_n)}{\partial \theta_j}\approx0 ∂θj∂L(θ0,θ1,⋯,θn)≈0)
总的来说,目标函数的梯度只是指明了下降的方向,而学习率则决定了每次迭代下降的距离多少。过小的学习率,则会导致训练时间过长,收敛慢;而过大的学习率则会导致训练震荡,而且有可能跳过极小值点,导致发散。
当然,以上讲的就是最初版本的梯度下降,在这之后的研究当中,衍生出了许多改进版的梯度下降,这个在以后的内容中详细介绍
【深度学习】网络训练的原理:什么是梯度下降?学习率的作用是什么?相关推荐
- 深度学习网络训练中出现nan的原因分析
报错: nan:Not a Number 该错误导致的后果:造成训练准确率的断崖式下跌 错误原因分析: 1)在loss函数中出现nan 出现原因:一般是因为tf中的log函数输入了'负数'或'0'值( ...
- python深度学习第三讲——用python写神经网络梯度下降(手写字符识别mnist)
机器学习使用训练数据进行学习.使用训练数据进行学习,严格来说,就是针对训练数据计算损失函数的值,找出使该值尽可能小的参数.因此,计算损失函数时必须将所有的训练数据作为对象.也就是说,如果训练数据有10 ...
- 深度学习网络训练技巧
(改了点) 转载请注明:炼丹实验室 新开了一个专栏,为什么叫炼丹实验室呢,因为以后会在这个专栏里分享一些关于深度学习相关的实战心得,而深度学习很多人称它为玄学,犹如炼丹一般.不过即使是炼丹也是可以摸索 ...
- 深度学习-网络训练技巧
1.深度学习的一些基本概念,学习率.batch.epoch.optimizer.评价函数(损失函数)等 1.1 学习率(Learning Rate) 学习率:是控制模型学习效率(步长)的权重. 学习率 ...
- 踩坑实录——多光谱影像(.tif)输入深度学习网络训练
项目场景: 从github下载了fastercnn_Resnet50的目标识别网络,尝试把多光谱影像数据集(.tif)输入进去进行训练,由于本人是刚接触深度学习的小白,网上又没有找到相关教程,只能一边 ...
- 深度学习 网络训练技巧
网络训练技巧: 1.数据增强:缩放.随机位置截取.翻卷.随机旋转.亮度.对比度.颜色变化等方法. 2.学习率衰减:随着训练的进行不断的减小学习率. 例如:一开始学习率0.01,在10000步后降为0. ...
- 机器学习(深度学习)中的反向传播算法与梯度下降
这是自己在CSDN的第一篇博客,目的是为了给自己学习过的知识做一个总结,方便后续温习,避免每次都重复搜索相关文章. 一.反向传播算法 定义:反向传播(Backpropagation,缩写为BP)是&q ...
- 零基础入门深度学习 | 第二章:线性单元和梯度下降
北京 | 高性能计算之GPU CUDA课程11月24-26日3天密集学习 快速带你晋级阅读全文> 无论即将到来的是大数据时代还是人工智能时代,亦或是传统行业使用人工智能在云上处理大数据的时代,作 ...
- 【深度学习】PyTorch 中的线性回归和梯度下降
作者 | JNK789 编译 | Flin 来源 | analyticsvidhya 我们正在使用 Jupyter notebook 来运行我们的代码.我们建议在Google Colaborat ...
- 没有独立显卡,虚拟的显卡,能进行深度学习网络训练吗
好像不能 什么也没有,检测不出来显卡 虚拟机检测不出来显卡的原因是装了tensorflow和tensorflow-gpu.把tensorflow卸载了,重新装一次tensorflow-GPU即可
最新文章
- Chapter2 消息总线 ConfigClient配置自动刷新
- 谈钱太俗!难道开源软件只能讲道义?
- C# 代理做为函数参数的时候
- mysql 5.6.23 源码包安装报错_CentOS6.5_64bit下编译安装MySQL-5.6.23
- 前端学习(1848)vue之电商管理系统电商系统的开发模式和技术选型
- vs编写windows服务和调用webservice
- 搜索算法-三个简单的小问题
- Spring boot(6) 数据访问
- java的if else if_java,if else和if else if else区别?
- Masonry详解(转)
- MIUI ROM for Milestone 刷机教程
- JAVA版商城 B2B2C商城 多用户入驻商城 直播带货商城 新零售商城 o2o商城 拼团商城 分销商城 直播商城 短视频商城 VR商城 社交电商 分销商城 saas商城spring cloud商城
- java 读取小数位数_java如何获取一个double的小数位数
- 中国的开源之夏来了!
- UninstallToo卸载软件
- 安卓查看内存读写测试软件_关于手机运行内存的四大误区,你信了几个?
- Echarts之饼图
- RV-LINK:GDB 使用 RV-LINK 仿真器调试 RISC-V 程序
- Ubuntu20.04安装cuda10.1
- pytorch apex +ddp 分布式训练+数据优化