批量梯度下降 linux,梯度下降法及其Python实现

梯度降落法(gradient descent),又名最速降落法(steepest descent)是求解无束缚最优化问题最经常使用的方法,它是1种迭代方法,每步主要的操作是求解目标函数的梯度向量,将当前位置的负梯度方向作为搜索方向(由于在该方向上目标函数降落最快,这也是最速降落法名称的由来)。

梯度降落法特点:越接近目标值,步长越小,降落速度越慢。

直观上来看以下图所示:

be5421ad12a427ec3ffa7f23a9a09c98.png

这里每个圈代表1个函数梯度,最中心表示函数极值点,每次迭代根据当前位置求得的梯度(用于肯定搜索方向和与步长共同决定前进速度)和步长找到1个新的位置,这样不断迭代终究到达目标函数局部最优点(如果目标函数是凸函数,则到达全局最优点)。

下面我们将通过公式来具体说明梯度降落法

下面这个h(θ)是我们的拟合函数

e7b088eb5bfa3ee0d699c8cf6a6fdaa7.png

也能够用向量的情势进行表示:

515699cabd6a360fe82fc34d30fe096c.png

下面函数是我们需要进行最优化的风险函数,其中的每项

217555a8c3235217e8b8a1a35fc79fc1.png都表示在已有的训练集上我们的拟合函数与y之间的残差,计算其平方损失函数作为我们构建的风险函数(参见最小2乘法及其Python实现)

83290ff277a51a19bc405fe52ecb2cdc.png

这里我们乘上1/2是为了方便后面求偏导数时结果更加简洁,之所以能乘上1/2是由于乘上这个系数后对求解风险函数最优值没有影响。

我们的目标就是要最小化风险函数,使得我们的拟合函数能够最大程度的对目标函数y进行拟合,即:

e516bb171538d53ffebb9f309ff204d9.png

后面的具体梯度求解都是围绕这个目标来进行。

批量梯度降落BGD

依照传统的思想,我们需要对上述风险函数中的每一个

f7725a0abf5698891c8c963cb609ef30.png求其偏导数,得到每一个

8734367216ddf8a99b3123e3f0c93a5f.png对应的梯度

e4d51a0a118601ee02f2a29479612b5a.png

这里

ff8f287d39c31cf6931eccb9f3bed624.png表示第i个样本点

dddd7815cb48ddae9f6f6dfb2bf570e8.png的第j份量,即h(θ)中的

5f5a93be4cc686d67fd34cb6397af19b.png

接下来由于我们要最小化风险函数,故依照每一个参数

f7725a0abf5698891c8c963cb609ef30.png的负梯度方向来更新每个

f7725a0abf5698891c8c963cb609ef30.png

c40290ccea57c37f6b4d027230693451.png

这里的α表示每步的步长

从上面公式可以注意到,它得到的是1个全局最优解,但是每迭代1步,都要用到训练集所有的数据,如果m很大,那末可想而知这类方法的迭代速度!!所以,这就引入了另外1种方法,随机梯度降落。

随机梯度降落SGD

由于批量梯度降落在训练集很大的情况下迭代速度非常之慢,所以在这类情况下再使用批量梯度降落来求解风险函数的最优化问题是不具有可行性的,在此情况下,提出了——随机梯度降落

我们将上述的风险函数改写成以下情势:

54b29482fb2be2f555b10dcc94de5d26.png

其中,

4be180e8073ea3f023282a666ddae6fe.png

称为样本点

ae3d3f336fc155218af1b7b3083c9265.png的损失函数

接下来我们对每一个样本的损失函数,对每一个

f7725a0abf5698891c8c963cb609ef30.png求其偏导数,得到每一个

f7725a0abf5698891c8c963cb609ef30.png对应的梯度

7ad021c3dcdf9827609375a01d14a3eb.png

然后根据每一个参数

f7725a0abf5698891c8c963cb609ef30.png的负梯度方向来更新每个

f7725a0abf5698891c8c963cb609ef30.png

ee373558d1dd741f3de0c2e5868cc8b2.png

与批量梯度降落相比,随机梯度降落每次迭代只用到了1个样本,在样本量很大的情况下,常见的情况是只用到了其中1部份样本数据便可将θ迭代到最优解。因此随机梯度降落比批量梯度降落在计算量上会大大减少。

SGD有1个缺点是,其噪音较BGD要多,使得SGD其实不是每次迭代都向着整体最优化方向。而且SGD由于每次都是使用1个样本进行迭代,因此终究求得的最优解常常不是全局最优解,而只是局部最优解。但是大的整体的方向是向全局最优解的,终究的结果常常是在全局最优解附近。

下面是两种方法的图形展现:

e23db41f548ca5b01e306d5c0bdcb19f.png

24abcf1549c6647d06ae97348becd3c3.png

从上述图形可以看出,SGD由于每次都是用1个样本点进行梯度搜索,因此其最优化路径看上去比较盲目(这也是随机梯度降落名字的由来)。

对照其优劣点以下:

批量梯度降落:

优点:全局最优解;易于并行实现;整体迭代次数不多

缺点:当样本数目很多时,训练进程会很慢,每次迭代需要耗费大量的时间。

随机梯度降落:

优点:训练速度快,每次迭代计算量不大

缺点:准确度降落,其实不是全局最优;不容易于并行实现;整体迭代次数比较多。

============ 分割分割 =============

上面我们讲授了甚么是梯度降落法,和如何求解梯度降落,下面我们将通过Python来实现梯度降落法。

# _*_ coding: utf⑻ _*_

# 作者: yhao

# 博客: http://blog.csdn.net/yhao2014

# 邮箱: yanhao07@sina.com

# 训练集

# 每一个样本点有3个份量 (x0,x1,x2)

x = [(1, 0., 3), (1, 1., 3), (1, 2., 3), (1, 3., 2), (1, 4., 4)]

# y[i] 样本点对应的输出

y = [95.364, 97.217205, 75.195834, 60.105519, 49.342380]

# 迭代阀值,当两次迭代损失函数之差小于该阀值时停止迭代

epsilon = 0.0001

# 学习率

alpha = 0.01

diff = [0, 0]

max_itor = 1000

error1 = 0

error0 = 0

cnt = 0

m = len(x)

# 初始化参数

theta0 = 0

theta1 = 0

theta2 = 0

while True:

cnt += 1

# 参数迭代计算

for i in range(m):

# 拟合函数为 y = theta0 * x[0] + theta1 * x[1] +theta2 * x[2]

# 计算残差

diff[0] = (theta0 + theta1 * x[i][1] + theta2 * x[i][2]) - y[i]

# 梯度 = diff[0] * x[i][j]

theta0 -= alpha * diff[0] * x[i][0]

theta1 -= alpha * diff[0] * x[i][1]

theta2 -= alpha * diff[0] * x[i][2]

# 计算损失函数

error1 = 0

for lp in range(len(x)):

error1 += (y[i]-(theta0 + theta1 * x[i][1] + theta2 * x[i][2]))**2/2

if abs(error1-error0) < epsilon:

break

else:

error0 = error1

print ' theta0 : %f, theta1 : %f, theta2 : %f, error1 : %f' % (theta0, theta1, theta2, error1)

print 'Done: theta0 : %f, theta1 : %f, theta2 : %f' % (theta0, theta1, theta2)

print '迭代次数: %d' % cnt

结果(截取部份):

theta0 : 2.782632, theta1 : 3.207850, theta2 : 7.998823, error1 : 7.508687

theta0 : 4.254302, theta1 : 3.809652, theta2 : 11.972218, error1 : 813.550287

theta0 : 5.154766, theta1 : 3.351648, theta2 : 14.188535, error1 : 1686.507256

theta0 : 5.800348, theta1 : 2.489862, theta2 : 15.617995, error1 : 2086.492788

theta0 : 6.326710, theta1 : 1.500854, theta2 : 16.676947, error1 : 2204.562407

theta0 : 6.792409, theta1 : 0.499552, theta2 : 17.545335, error1 : 2194.779569

theta0 : 74.892395, theta1 : ⑴3.494257, theta2 : 8.587471, error1 : 87.700881

theta0 : 74.942294, theta1 : ⑴3.493667, theta2 : 8.571632, error1 : 87.372640

theta0 : 74.992087, theta1 : ⑴3.493079, theta2 : 8.555828, error1 : 87.045719

theta0 : 75.041771, theta1 : ⑴3.492491, theta2 : 8.540057, error1 : 86.720115

theta0 : 75.091349, theta1 : ⑴3.491905, theta2 : 8.524321, error1 : 86.395820

theta0 : 75.140820, theta1 : ⑴3.491320, theta2 : 8.508618, error1 : 86.072830

theta0 : 75.190184, theta1 : ⑴3.490736, theta2 : 8.492950, error1 : 85.751139

theta0 : 75.239442, theta1 : ⑴3.490154, theta2 : 8.477315, error1 : 85.430741

theta0 : 97.986390, theta1 : ⑴3.221172, theta2 : 1.257259, error1 : 1.553781

theta0 : 97.986505, theta1 : ⑴3.221170, theta2 : 1.257223, error1 : 1.553680

theta0 : 97.986620, theta1 : ⑴3.221169, theta2 : 1.257186, error1 : 1.553579

theta0 : 97.986735, theta1 : ⑴3.221167, theta2 : 1.257150, error1 : 1.553479

theta0 : 97.986849, theta1 : ⑴3.221166, theta2 : 1.257113, error1 : 1.553379

theta0 : 97.986963, theta1 : ⑴3.221165, theta2 : 1.257077, error1 : 1.553278

Done: theta0 : 97.987078, theta1 : ⑴3.221163, theta2 : 1.257041

迭代次数: 3443

可以看到最后收敛到稳定的参数值。

注意:这里在选取alpha和epsilon时需要谨慎选择,可能不适的值会致使最后没法收敛。

参考文档:

随机梯度降落(Stochastic gradient descent)和 批量梯度降落(Batch gradient descent

)的公式对照、实现对照

随机梯度降落法

python实现梯度降落算法

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值