-
引入
在机器学习与深度学习中,对损失函数最小化时经常使用的算法就是梯度下降。当然还有很多优化算法,本文先对梯度下降与反向传播进行介绍。
-
斜率、导数 and 梯度
在介绍梯度下降之前,首先来明确梯度的概念,以及它与斜率、导数之间的区别。
-
斜率、导数
斜率我们从小学就开始接触,对于一元方程 y = k x + b y=kx+b y=kx+b 来讲,斜率就是方程图像与 x 轴夹角的正切值,也等于导数值,且各点导数值相等。
k = tan θ = y 1 − y 2 x 1 − x 2 = △ y △ x k=\tanθ=\frac{y_1-y_2}{x_1-x_2}=\frac{\triangle y}{\triangle x} k=tanθ=x1−x2y1−y2=△x△y
导数是微积分中的重要基础概念,它体现了函数图像在各点变化的快慢程度,也就是在各点切线的斜率(实际上是在某点附近的斜率近似)。
f ′ ( x ) = △ x → 0 lim f ( x + △ x ) − f ( x ) △ x = △ x → 0 lim △ y △ x f'(x)=\mathop{}_{\triangle x→ 0}^{\lim}\frac{f(x+\triangle x)-f(x)}{\triangle x}=\mathop{}_{\triangle x→ 0}^{\lim}\frac{\triangle y}{\triangle x} f′(x)=△x→0lim△xf(x+△x)−f(x)=△x→0lim△x△y
斜率与导数都是有方向的,当大于 0 时,表示函数值沿 x 轴正方向是增加的;当大于 0 时,表示函数值沿 x 轴正方向是减小的。
-
偏导数
偏导数与导数的本质是一致的,都是当自变量的变化量趋于 0 时,函数值的变化量与自变量变化量比值的极限。直观地说,偏导数也就是函数在某一点上沿 对应坐标轴正方向 的的变化率。区别在于导数面向的是一元函数,偏导数面向的是多元函数。
假设有函数 f ( x 1 , x 2 ) f(x_1,x_2) f(x1,x2),则其对于 x 1 , x 2 x_1,x_2 x1,x2 偏导数为:
∂ ∂ x 1 f ( x 1 , x 2 ) = △ x → 0 lim f ( x 1 + △ x , x 2 ) △ x \frac{\partial}{\partial x_1}f(x_1,x_2)=\mathop{}_{\triangle x→ 0}^{\lim}\frac{f(x_1+\triangle x,x_2)}{\triangle x} ∂x1∂f(x1,x2)=△x→0lim△xf(x1+△x,x2)
∂ ∂ x x f ( x 1 , x 2 ) = △ x → 0 lim f ( x 1 , x 2 + △ x ) △ x \frac{\partial}{\partial x_x}f(x_1,x_2)=\mathop{}_{\triangle x→ 0}^{\lim}\frac{f(x_1,x_2+\triangle x)}{\triangle x} ∂xx∂f(x1,x2)=△x→0lim△xf(x1,x2+△x)
-
方向导数
偏导数是关于各坐标轴的导数,而对于多元函数上的一个点来讲,它可以有无数个偏导数,并不是只有沿着坐标轴的有限个方向。就像一个人站在一个球场的中心,除了沿着球场的宽与长的两个方向可以走以外,周身 360° 都是可以面冲的方向,那么对于这无数个方向来讲的导数,就称为方向导数。
(中间红色点为出发点,蓝色为各种可以选择的方向。向上与向右的为沿着坐标轴 x,y 的方向。)如果说偏导数是函数在各坐标轴方向上的导数,那么方向导数就是函数在任意方向上的导数,是所有偏导数的集合(例如:沿 x 方向走 2 步,y 方向走 5 步,此时最终走的方向就是由 (0,0)点 指向 (2, 5)的向量做表示的方向,可以被各偏导数的线性线性表示)。
具体的,方向导数的表达式为: D f ( x 1 , x 2 ) = ∂ f ( x 1 , x 2 ) x 1 cos θ + ∂ f ( x 1 , x 2 ) x 2 sin θ D_{f(x_1,x_2)}=\frac{\partial f(x_1,x_2)}{x_1}\cosθ+\frac{\partial f(x_1,x_2)}{x_2}\sinθ Df(x1,x2)=x1∂f(x1,x2)cosθ+x2∂f(x1,x2)sinθ
-
梯度
有了以上的铺垫,那么梯度就很好理解了。
∙ \bullet ∙ 梯度的提出只为回答一个问题: 函数在变量空间的某一点处,沿着哪一个方向有最大的变化率?
∙ \bullet ∙ 梯度定义如为:函数在某一点的梯度是这样一个 向量,它的方向是在所有方向导数中,最大的方向导数的方向,它的模为方向导数的最大值。
∙ \bullet ∙ 也可以这么理解:梯度即函数在某一点最大的方向导数,沿梯度方向,函数具有最大的变化率。
那么为什么梯度是方向导数中最大的呢?
因为 D f ( x 1 , x 2 ) = ∂ f ( x 1 , x 2 ) x 1 cos θ + ∂ f ( x 1 , x 2 ) x 2 sin θ D_{f(x_1,x_2)}=\frac{\partial f(x_1,x_2)}{x_1}\cosθ+\frac{\partial f(x_1,x_2)}{x_2}\sinθ Df(x1,x2)=x1∂f(x1,x2)cosθ+x2∂f(x1,x2)sinθ
我们可以另 A = < ∂ f ( x 1 , x 2 ) x 1 , ∂ f ( x 1 , x 2 ) x 2 > A=<\frac{\partial f(x_1,x_2)}{x_1},\frac{\partial f(x_1,x_2)}{x_2}> A=<x1∂f(x1,x2),x2∂f(x1,x2)>, I = < cos θ , sin θ > I=<\cosθ,\sinθ> I=<cosθ,sinθ>
则方向导数可表示为两个向量的乘积: D f ( x 1 , x 2 ) = A ⋅ I = ∣ A ∣ ⋅ ∣ I ∣ ⋅ cos α D_{f(x_1,x_2)}=A·I=|A|·|I|·\cosα Df(x1,x2)=A⋅I=∣A∣⋅∣I∣⋅cosα
为使 D f ( x 1 , x 2 ) D_{f(x_1,x_2)} Df(x1,x2) 最大,那么 A A A 与 I I I 两个向量应平行。其中 I I I 一直在变, A A A 当点 x 1 , x 2 x_1,x_2 x1,x2 确定的时候就已经确定了,所以 A A A 就代表了当前能使 D f ( x 1 , x 2 ) D_{f(x_1,x_2)} Df(x1,x2) 最大的向量,所以我们将 A A A 称为梯度。
且值得注意的是,此时恰好 A = < ∂ f ( x 1 , x 2 ) x 1 , ∂ f ( x 1 , x 2 ) x 2 > A=<\frac{\partial f(x_1,x_2)}{x_1},\frac{\partial f(x_1,x_2)}{x_2}> A=<x1∂f(x1,x2),x2∂f(x1,x2)>,那么求梯度就相当于对各变量求偏导。
-
-
梯度下降
既然我们知道梯度是所有方向导数中最大的方向导数,具有最大的变化率,那么我们如果沿着梯度方向走,就可以最快到达函数的最大值。
而在损失函数优化的过程中,我们希望取得函数的最小值,那么自然就是沿着梯度的负方向走。
既然梯度是偏导数的集合: g r a d ( x 0 , x 1 , . . . , x n ) = < ∂ f ( x 0 , x 1 , . . . , x n ) ∂ x 0 , ∂ f ( x 0 , x 1 , . . . , x n ) ∂ x 1 , . . . , ∂ f ( x 0 , x 1 , . . . , x n ) ∂ x n > grad(x_0,x_1,...,x_n)=<\frac{\partial f(x_0,x_1,...,x_n)}{\partial x_0},\frac{\partial f(x_0,x_1,...,x_n)}{\partial x_1},...,\frac{\partial f(x_0,x_1,...,x_n)}{\partial x_n}> grad(x0,x1,...,xn)=<∂x0∂f(x0,x1,...,xn),∂x1∂f(x0,x1,...,xn),...,∂xn∂f(x0,x1,...,xn)>
参考向量运算法则,我们在每个变量轴上减小对应变量值即可:
x 1 : = x 1 − α ∂ ∂ x 1 f ( x 1 , x 2 , . . . , x n ) x_1:=x_1-α\frac{\partial}{\partial x_1}f(x_1,x_2,...,x_n) x1:=x1−α∂x1∂f(x1,x2,...,xn)
x 2 : = x 2 − α ∂ ∂ x 2 f ( x 1 , x 2 , . . . , x n ) x_2:=x_2-α\frac{\partial}{\partial x_2}f(x_1,x_2,...,x_n) x2:=x2−α∂x2∂f(x1,x2,...,xn)
…
…
…
x n : = x n − α ∂ ∂ x n f ( x 1 , x 2 , . . . , x n ) x_n:=x_n-α\frac{\partial}{\partial x_n}f(x_1,x_2,...,x_n) xn:=xn−α∂xn∂f(x1,x2,...,xn)
例:假设有损失函数 L ( x 1 , x 2 ) = x 1 2 + x 2 3 L(x_1,x_2)=x_1^2+x_2^3 L(x1,x2)=x12+x23,学习速率 α = 0.1 α=0.1 α=0.1
那么为使 L ( x 1 , x 2 ) L(x_1,x_2) L(x1,x2) 得到最小值计算梯度:
∂ f ( x 1 , x 2 ) ∂ x 1 = 2 x 1 , ∂ f ( x 1 , x 2 ) ∂ x 2 = 3 x 2 2 \frac{\partial f(x_1,x_2)}{\partial x_1}=2x_1,\frac{\partial f(x_1,x_2)}{\partial x_2}=3x_2^2 ∂x1∂f(x1,x2)=2x1,∂x2∂f(x1,x2)=3x22
假设初始参数值: x 1 = 1 , x 2 = 3 x_1=1,x_2=3 x1=1,x2=3,损失函数初始值: L ( x 1 , x 2 ) = 28 L(x_1,x_2)=28 L(x1,x2)=28
那么使用梯度下降更新
x 1 : = 1 − 0.1 ∗ 2 ∗ 1 ⟹ x 1 = 0.8 x_1:=1-0.1*2*1\Longrightarrow x_1=0.8 x1:=1−0.1∗2∗1⟹x1=0.8
x 2 : = 3 − 0.1 ∗ 3 ∗ 9 ⟹ x 2 = 0.3 x_2:=3-0.1*3*9\Longrightarrow x_2=0.3 x2:=3−0.1∗3∗9⟹x2=0.3
L ( x 1 , x 2 ) = 0. 8 2 + 0. 3 3 = 0.667 L(x_1,x_2)=0.8^2+0.3^3=0.667 L(x1,x2)=0.82+0.33=0.667
以上完成了一次梯度下降,循环进行,可将损失函数值快速降到最低点 0.
梯度下降是初始值敏感的,不同的初始“下山位置”会影响下到山底的时间与速度。为了减小初始值的影响,可以随机多个初始值进行多个模型的训练,或者调整学习速率,从中找到最优模型。
-
反向传播
反向传播与梯度下降类似,都是求梯度,并沿着负梯度方向更新参数。不同点是反向传播应用的场景是神经网络,此时需要的是 链式求导。
这篇文章讲的非常详细,反向传播,收藏记录。