您的位置:首页 > 编程语言 > Python开发

最速下降法/梯度下降法公式推导与python实现

2017-12-18 19:42 316 查看

目录

最速下降法

1.1 最速下降法的导出

1.2 最速下降法的几个重要命题

1.3 迭代停止条件

1.4 最速下降算法步骤

各种梯度下降法

2.1 梯度下降法

2.2 梯度下降法与最速下降法的区别

2.3 随机梯度下降法(Stochastic gradient descent)

2.4 批量梯度下降法(BGD)

2.5 小批量梯度下降(Mini-Batch Gradient Descent)

1.最速下降法

1.1 最速下降法的导出

最速下降法以负梯度方向为极小化算法的方向,又称梯度法,人们经常把最速下降法和梯度下降法等同,事实上,它们是不同的,这个稍后再说。先看一下最速下降法的定义。

设函数f(x)在xk附近连续可微,gk=∇f(xk)≠0,在xk处对f进行泰勒展开有:f(x)=f(xk)+(x−xk)T∇f(xk)+o(||x−xk||)(1.1)若记x−xk=αdk,则满足dTkgk<0的方向dk是下降方向,也就是负梯度方向。当α取定之后,dTkgk的值越小,表示图中的坡越陡,函数下降得越快。



使用Cauchy-Schwartz不等式:|dTkgk|≤|dk||gk|解这个不等式,当且仅当dk=−gk时,dTkgk最小,从而称−gk时最速下降方向。

其中最速下降法的迭代格式为:xk+1=xk−αkgk

1.2 最速下降法的几个重要命题

步长应该如何选取?在做逻辑回归的时候,我们用梯度下降法来求解最优参数,当时的步长可以是人工随机取符合数据和当前情境下的步长,那在这里,步长该如何选取呢?Cauchy曾经建议使用精确线搜索( 一维线搜索)来确定步长:f(x−αk∇f(xk))=min{f(x−αf(x)):α>0}其中αk就是最优步长

利用最速下降法搜索函数f:R2→R的极小点,迭代过程中产生的迭代序列{x(k)}∞k=0,对于任意的k>0,都有xk+1−xk与xk+2−xk+1正交

利用最速下降法搜索函数f:R2→R的极小点,迭代过程中产生的迭代序列{x(k)}∞k=0,若梯度:∇f(x)≠0,则必有f(xk+1)<f(xk)

1.3 迭代停止条件

在实际中,采用数值计算的方法很难恰好得到梯度为0的结果,因此以梯度为0作为停止规则很不恰当。以下ϵ>0

(1) |f(xk+1)−f(xk)|<ϵ

(2) ||xk+1−xk||<ϵ

(3) |f(xk+1)−f(xk)||f(xk)|<ϵ

(4) ||xk+1−xk||||xk||<ϵ

(5) |f(xk+1)−f(xk)|max{1,|f(xk)|}<ϵ

(6) ||xk+1−xk||max{||xk||}<ϵ

上边的3,4式为1,2式的相对值,而5,6式是为了避免3,4式中的分母过小进行的修改。

1.4 最速下降算法步骤

A. 任取x0∈Rn,ϵ>0,令k:=0

B .计算梯度∇f(xk),如果||∇f(xk)||<ϵ(或满足其他停止条件),则算法停止,计算步长αk,使得:f(x−αk∇f(xk))=min{f(x−αf(x)):α>0}

C. 计算下一个迭代点xk+1=xk−αk∇f(xk),令k:=k+1

2.各种梯度下降法

2.1 梯度下降法

梯度下降法经常用于机器学习,深度学习领域,用来更新模型的参数,使得模型的预测误差越来越小。它的原理就是沿着负梯度方向下山:


其核心也是:xk+1=xk−a∇f(x)不断迭代更新,直到最低点。

看一下它的伪代码:

model = initialization(...)
n_epochs = ...
train_data = ...
for i in n_epochs:
train_data = shuffle(train_data)
X, y = split(train_data)
predictions = predict(X, train_data)
error = calculate_error(y, predictions)
model = update_model(model, error)


2.2 梯度下降法与最速下降法的区别

看完最速下降法,你可能觉得梯度下降法和最速下降法是一样的,但事实是,他们是有细微区别的。

梯度下降法同样认为梯度的反方向为下降最快的方向,所以沿着负梯度方向移动一定距离,目标函数也会减小,如果是凸函数,最终会达到全局最小值。同样,它的步长α也可以通过精准线搜索确定。

感觉它们都是移动单位步长,沿着下降最多的方向移动,但对于梯度下降法,如果是:△nsd=argminv(∇f(x)Tv∣∥v∥<=1),梯度下降法使用的是欧式范数||v||,也就是说,梯度下降法是最速下降法的一个特列,是最速下降法使用欧式范数的一种特例。更加详细的看这里:梯度下降法和最速下降法的细微差别

2.3 随机梯度下降法(Stochastic gradient descent)

随机梯度下降法是梯度下降法个一个变体,简称SGD,它对每个样本都会更新一次参数。正因如此,它会消耗更多的计算量,在大数据集上,训练得也会很慢。如果一连遇到比较多的噪声数据,频繁更新也会导致找不到正确的方向到达最低点。



如图所示,它的晃动会比较明显,但有可能只使用一部分样本,就能到底最低点了。

SGD 的另一个好处是, 可以使用在线学习 [online learning]. 也就是说, 在模型训练好之后, 只要有新的数据到来, 模型都可以利用新的数据进行再学习, 更新参数,以适应新的变化.

每个样本都会计算一次损失,更新公式如下:θ′j=θj+(yi−hθ(xi))xij

def sgd(alpha, x, y, numIterations):
m = x.shape[0]
theta = np.ones(2)

#随机序列化,选样本
idx = np.random.permutation(y.shape[0])
x,y = x[idx], y[idx]

for j in range(numIterations):
for i in idx:
single_hypothesis = np.dot(x[i],theta)
single_loss = y[i] - single_hypothesis
gradient = np.dot(x[i].transpose(), single_loss)
theta += alpha*gradient
return theta


2.4 批量梯度下降法(BGD)

BGD会对每个训练样本都计算误差,但是更新参数是等所有的样本误差都计算完之后才更新的。也就是说,等计算完所有的训练样本的损失之后,模型的参数才更新一次。

整个训练集遍历完才更新参数,意味着损失(误差),或者说下降的方向更加稳定,同时需要的计算量也会更小。但也会因为最后才更新参数,训练模型的时候,整个训练集都要存在内存上,在大数据集上,训练的速度也会很慢。



如图所示,虽然很慢,但迭代的方向基本都是正确的,不会发生非常大的偏移,迭代起来较稳定。

遍历整个训练集,所以需要累加:θ′j=θj+1m∑i=1m(yi−hθ(xi))xij

批量梯度下降的python代码

def bgd(alpha, x, y, numIterations):
m = x.shape[0]
theta = np.ones(2)

x_train = x.transpose()
for iteration in range(0, numIterations):
hypothesis = np.dot(x, theta)
loss = y - hypothesis

gradient = np.dot(x_train, loss)/m
theta +=alpha*gradient #所有数据完了之后,更新一次

return theta


2.4 小批量梯度下降(Mini-Batch Gradient Descent)

我们从上面两种梯度下降法可以看出,其各自均有优缺点,那么能不能在两种方法的性能之间取得一个折衷呢?即,算法的训练过程比较快,而且也要保证最终参数训练的准确率,而这正是小批量梯度下降法(Mini-batch Gradient Descent,简称MBGD)的初衷。

它的主要想法就是取一小批量的样本,然后计算梯度的平均值,这样既能减小梯度的方差,更新参数的速度也不会那么慢。

在训练的时候,也不需要把所有的训练样本都读取到内存中。

而每一批取多少,就是一个超参数的选择了,这应该怎么选呢?

给两个建议:

1. 一般选择32左右。如果不行,可以在10到一百中选择,可以自己设一个跨度试一下。

2. 用不同的批次,看一下验证误差和训练时间的学习曲线。

小批量梯度下降python代码实现

def mbgd(alpha, x, y, numIterations,minibatches):
m = x.shape[0]
theta = np.ones(2)

for j in range(numIterations):
idx = np.random.permutation(y.shape[0])
x, y = x[idx], y[idx]
mini = np.array_split(range(y.shape[0]), minibatches)

for i in mini:
mb_hypothesis = np.dot(x[i],theta)
mb_loss = y[i] - mb_hypothesis
gradient = np.dot(x[i].transpose(), mb_loss)/minibatches
theta += alpha*gradient
return theta


参考

A Gentle Introduction to Mini-Batch Gradient Descent and How to Configure Batch Size

ML之梯度下降算法

详解梯度下降法的三种形式BGD、SGD以及MBGD

最优化学习笔记(四)——最速下降法

梯度下降法和最速下降法的细微差别

最优化理论与方法-袁亚湘

最优化选讲-董云达(郑州大学出版社)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: