导数
导数反映的是函数 f(x) 在 x 轴上某一点处沿着 x 轴正方向的变化率/变化趋势。
f′(x0)=Δx→0limΔxΔy=Δx→0limΔxf(x0+Δx)−f(x0)
偏导数
因为曲面上的每一点都有无穷多条切线,描述曲面函数的导数相当困难。偏导数就是选择其中一条切线,并求出它的斜率。
z=f(x,y)=x2+xy+y2
-
一种求出这些切线的好办法是把其他变量视为常数。例如,欲求出以上的曲面函数在点(1,1,3) 与 y=1 平面的切线。(右图为 y=1 切面)
-
我们把变量 y 视为常数,过对 x 求导:
∂x∂z=2x+y
-
得到点(1, 1, 3)的与 xOz 平面平行的切线的斜率为 3。
一般地,函数 f(x1,...,xn) 在点 (a1,...,an) 关于 xi 的偏导数定义为:
∂xi∂f(a1,…,an)=h→0limhf(a1,…,ai+h,…,an)−f(a1,…,an)
方向导数
导数和偏导数的定义中,均是沿座标轴正方向讨论函数的变化率。而方向导数则是求某一点在某一趋近方向上的导数值,反映函数在特定方向上的变化率:
梯度
梯度即函数在某一点最大的方向导数,函数沿梯度方向函数有最大的变化率,梯度的值是最大方向导数的值。
利用有限差值计算梯度
对 x 所有维度进行迭代,在每个维度上产生一个很小的变化 h,通过观察函数值变化,计算函数在该维度上的偏导数。最后,所有的梯度存储在变量 grad 中:
def eval_numerical_gradient(f, x):
"""
一个f在x处的数值梯度法的简单实现
- f是只有一个参数的函数
- x是计算梯度的点
"""
fx = f(x)
grad = np.zeros(x.shape)
h = 0.00001
it = np.nditer(x, flags=['multi_index'], op_flags=['readwrite'])
while not it.finished:
ix = it.multi_index
old_value = x[ix]
x[ix] = old_value + h
fxh = f(x)
x[ix] = old_value
grad[ix] = (fxh - fx) / h
it.iternext()
return grad
实际中用中心差值公式(centered difference formula)[f(x+h)−f(x−h)]/2h 效果较好。
代价函数的梯度
hθ(x)=θ0+θ1∗x
- 不同参数的 θi 可以拟合出不同的直线:
- 代价函数 J(θ) 随参数 θi 的变化而变化:
-
θ0,θ1 初始值不同的时候,可能会找到不同局部最小值,这个正是 梯度下降算法 的特点。
-
一般线性回归的代价函数都是凸函数,只有一个全局最优值,如下图:
梯度下降的详细算法
先决条件
-
确认优化模型的 假设函数 和 代价函数。比如对于线性回归,假设函数表示为:
hθ(x1,x2,...xn)=θ0x0+θ1x1+...+θnxn
即:
hθ(X)=Xθ
其中 θi 为模型参数,xi 为每个样本 x 的第 i 个特征值。X 为 m∗(n+1) 维的矩阵,m 代表样本的个数,n+1 代表样本的特征数,多加的1维作为偏置项。
-
对应于上面的假设函数,代价函数为:
J(θ0,θ1...,θn)=2m1j=0∑m(hθ(x0(j),x1(j),...xn(j))−y(j))2
即:
J(θ)=21(Xθ−Y)T(Xθ−Y)
其中 Y 是样本的标签值,维度为 m∗1
算法过程
-
确定当前位置的代价函数的梯度,对于 θ 向量,其梯度表达式如下:
∂θ∂J(θ)=∂θi∂J(θ0,θ1...,θn)=m1j=0∑m(hθ(x0(j),x1(j),...xn(j))−y(j))xi(j)
即:
∂θ∂J(θ)=XT(Xθ−Y)
-
用学习速率 α 乘以代价函数的梯度,得到当前位置将要下降的距离:
α∂θ∂J(θ)=α∂θi∂J(θ0,θ1...,θn)
-
同步更新所有的 θ,对于 θi,其更新表达式如下。更新完毕后继续转入步骤1。
θi=θi−α∂θi∂J(θ0,θ1...,θn)
即:
θ=θ−αXT(Xθ−Y)
代价损失中 θ 偏导数公式推导
代价损失函数对于 θi 的偏导数计算,推导如下:
假设函数:
hθ(x1,x2)=θ0x0+θ1x1
代价损失函数:
J(θ0,θ1)=2m1j=0∑m(hθ(x0(j),x1(j))−y(j))2
=2m1j=0∑m((θ0x0(j)+θ1x1(j))−y(j))2
=2m1j=0∑m((θ0x0(j)+θ1x1(j))2+y(j)2−2(θ0x0(j)+θ1x1(j))y(j))
=2m1j=0∑m(θ02x0(j)2+θ12x1(j)2+2θ0x0(j)θ1x1(j)+y(j)2−2θ0x0(j)y(j)−2θ1x1(j)y(j))
代价损失函数对于θ0 的偏导数:
∂θ0∂J(θ0,θ1)=2m1j=0∑m(2θ0x0(j)2+2x0(j)θ1x1(j)−2x0(j)y(j))
=m1j=0∑m(θ0x0(j)2+x0(j)θ1x1(j)−x0(j)y(j))
=m1j=0∑m(θ0x0(j)+θ1x1(j)−y(j))x0(j)
=m1j=0∑m(hθ(x0(j),x1(j))−y(j))x0(j)
即:
∂θ∂J(θ)=∂θi∂J(θ0,θ1...,θn)=m1j=0∑m(hθ(x0(j),x1(j),...xn(j))−y(j))xi(j)
即:
∂θ∂J(θ)=XT(Xθ−Y)
批量梯度下降(Batch Gradient Descent,BGD)
- 批量梯度下降法,就是在梯度下降的每一步中,都 使用所有的样本 来进行更新。前面的梯度下降算法过程,就是批量梯度下降法。
θi=θi−αj=0∑m(hθ(x0(j),x1(j),...xn(j))−yj)xi(j)
随机梯度下降法(Stochastic Gradient Descent,SGD)
随机梯度下降法,其实和批量梯度下降法原理类似,区别在与求梯度时没有用所有的 m 个样本的数据,而是仅仅选取一个样本 j 来求梯度。对应的更新公式是:
θi=θi−α(hθ(x0(j),x1(j),...xn(j))−yj)xi(j)
-
随机梯度下降法,和批量梯度下降法是两个极端,一个采用所有数据来梯度下降,一个用 1 个样本来梯度下降。自然各自的优缺点都非常突出。
-
对于训练速度来说,随机梯度下降法由于每次仅仅采用 1 个样本来迭代,训练速度很快,而批量梯度下降法在样本量很大的时候,训练速度不能让人满意。
-
对于准确度来说,随机梯度下降法用于仅仅用一个样本决定梯度方向,导致解很有可能不是最优。对于收敛速度来说,由于随机梯度下降法一次迭代一个样本,导致迭代方向变化很大,不能很快的收敛到局部最优解。
小批量梯度下降法(Mini-batch Gradient Descent,MBGD)
-
小批量梯度下降法是批量梯度下降法和随机梯度下降法的折衷,也就是对于 m 个样本,我们采用 x 个样本来迭代,1<x<m。
-
小批量数据的大小是一个超参数,但是一般并不需要通过交叉验证来调参。它一般由存储器的限制来决定的,比如 32,64,128 等。之所以使用2的指数,是因为在实际中许多向量化操作实现的时候,如果输入数据量是 2 的倍数,那么运算更快。
-
对应的更新公式是:
θi=θi−αj=t∑t+x−1(hθ(x0(j),x1(j),...xn(j))−yj)xi(j)
-
使用向量化操作的代码,一次计算 100 个数据 比100次计算 1 个数据要高效很多。