梯度下降(Gradient Descent)算法是机器学习中使用非常广泛的优化算法。当前流行的机器学习库或者深度学习库都会包括梯度下降算法的不同变种实现。
本文主要以线性回归算法损失函数求极小值来说明如何使用梯度下降算法并给出python实现。若有不正确的地方,希望读者能指出。
梯度下降
梯度下降原理:将函数比作一座山,我们站在某个山坡上,往四周看,从哪个方向向下走一小步,能够下降的最快。
在求极小值时,在数据量很小的时候,可以使用矩阵求逆的方式求最优的θ值。但当数据量和特征值非常大,例如几万甚至上亿时,使用矩阵求逆根本就不现实。而梯度下降法就是很好的一个选择了。
使用梯度下降算法的步骤:
1)对θ赋初始值,这个值可以是随机的,也可以让θ是一个全零的向量。
2)改变θ的值,使得目标损失函数J(θ)按梯度下降的方向进行减少。
其中为学习率或步长,需要人为指定,若过大会导致震荡即不收敛,若过小收敛速度会很慢。
3)当下降的高度小于某个定义的值,则停止下降。
另外,对上面线性回归算法损失函数求梯度,结果如下:
在实际应用的过程中,梯度下降算法有三类,它们不同之处在于每次学习(更新模型参数)使用的样本个数,每次更新使用不同的样本会导致每次学习的准确性和学习时间不同。下面将分别介绍原理及python实现。
批量梯度下降(Batch gradient descent) "text-align: center">
梯度下降算法最终得到的是局部极小值。而线性回归的损失函数为凸函数,有且只有一个局部最小,则这个局部最小一定是全局最小。所以线性回归中使用批量梯度下降算法,一定可以找到一个全局最优解。
优点:全局最优解;易于并行实现;总体迭代次数不多
缺点:当样本数目很多时,训练过程会很慢,每次迭代需要耗费大量的时间。
随机梯度下降(Stochastic gradient descent)
随机梯度下降算法每次从训练集中随机选择一个样本来进行迭代,即:
随机梯度下降算法每次只随机选择一个样本来更新模型参数,因此每次的学习是非常快速的,并且可以进行在线更新。
随机梯度下降最大的缺点在于每次更新可能并不会按照正确的方向进行,因此可以带来优化波动(扰动)。不过从另一个方面来看,随机梯度下降所带来的波动有个好处就是,对于类似盆地区域(即很多局部极小值点)那么这个波动的特点可能会使得优化的方向从当前的局部极小值点跳到另一个更好的局部极小值点,这样便可能对于非凸函数,最终收敛于一个较好的局部极值点,甚至全局极值点。
优点:训练速度快,每次迭代计算量不大
缺点:准确度下降,并不是全局最优;不易于并行实现;总体迭代次数比较多。
Mini-batch梯度下降算法
Mini-batch梯度下降综合了batch梯度下降与stochastic梯度下降,在每次更新速度与更新次数中间取得一个平衡,其每次更新从训练集中随机选择b,b<m个样本进行学习,即:
python代码实现
批量梯度下降算法
#!/usr/bin/python #coding=utf-8 import numpy as np from scipy import stats import matplotlib.pyplot as plt # 构造训练数据 x = np.arange(0., 10., 0.2) m = len(x) # 训练数据点数目 print m x0 = np.full(m, 1.0) input_data = np.vstack([x0, x]).T # 将偏置b作为权向量的第一个分量 target_data = 2 * x + 5 + np.random.randn(m) # 两种终止条件 loop_max = 10000 # 最大迭代次数(防止死循环) epsilon = 1e-3 # 初始化权值 np.random.seed(0) theta = np.random.randn(2) alpha = 0.001 # 步长(注意取值过大会导致振荡即不收敛,过小收敛速度变慢) diff = 0. error = np.zeros(2) count = 0 # 循环次数 finish = 0 # 终止标志 while count < loop_max: count += 1 # 标准梯度下降是在权值更新前对所有样例汇总误差,而随机梯度下降的权值是通过考查某个训练样例来更新的 # 在标准梯度下降中,权值更新的每一步对多个样例求和,需要更多的计算 sum_m = np.zeros(2) for i in range(m): dif = (np.dot(theta, input_data[i]) - target_data[i]) * input_data[i] sum_m = sum_m + dif # 当alpha取值过大时,sum_m会在迭代过程中会溢出 theta = theta - alpha * sum_m # 注意步长alpha的取值,过大会导致振荡 # theta = theta - 0.005 * sum_m # alpha取0.005时产生振荡,需要将alpha调小 # 判断是否已收敛 if np.linalg.norm(theta - error) < epsilon: finish = 1 break else: error = theta print 'loop count = %d' % count, '\tw:',theta print 'loop count = %d' % count, '\tw:',theta # check with scipy linear regression slope, intercept, r_value, p_value, slope_std_error = stats.linregress(x, target_data) print 'intercept = %s slope = %s' % (intercept, slope) plt.plot(x, target_data, 'g*') plt.plot(x, theta[1] * x + theta[0], 'r') plt.show()
运行结果截图:
随机梯度下降算法
#!/usr/bin/python #coding=utf-8 import numpy as np from scipy import stats import matplotlib.pyplot as plt # 构造训练数据 x = np.arange(0., 10., 0.2) m = len(x) # 训练数据点数目 x0 = np.full(m, 1.0) input_data = np.vstack([x0, x]).T # 将偏置b作为权向量的第一个分量 target_data = 2 * x + 5 + np.random.randn(m) # 两种终止条件 loop_max = 10000 # 最大迭代次数(防止死循环) epsilon = 1e-3 # 初始化权值 np.random.seed(0) theta = np.random.randn(2) # w = np.zeros(2) alpha = 0.001 # 步长(注意取值过大会导致振荡,过小收敛速度变慢) diff = 0. error = np.zeros(2) count = 0 # 循环次数 finish = 0 # 终止标志 ######-随机梯度下降算法 while count < loop_max: count += 1 # 遍历训练数据集,不断更新权值 for i in range(m): diff = np.dot(theta, input_data[i]) - target_data[i] # 训练集代入,计算误差值 # 采用随机梯度下降算法,更新一次权值只使用一组训练数据 theta = theta - alpha * diff * input_data[i] # ------------------------------终止条件判断----------------------------------------- # 若没终止,则继续读取样本进行处理,如果所有样本都读取完毕了,则循环重新从头开始读取样本进行处理。 # ----------------------------------终止条件判断----------------------------------------- # 注意:有多种迭代终止条件,和判断语句的位置。终止判断可以放在权值向量更新一次后,也可以放在更新m次后。 if np.linalg.norm(theta - error) < epsilon: # 终止条件:前后两次计算出的权向量的绝对误差充分小 finish = 1 break else: error = theta print 'loop count = %d' % count, '\tw:',theta # check with scipy linear regression slope, intercept, r_value, p_value, slope_std_error = stats.linregress(x, target_data) print 'intercept = %s slope = %s' % (intercept, slope) plt.plot(x, target_data, 'g*') plt.plot(x, theta[1] * x + theta[0], 'r') plt.show()
运行结果截图:
Mini-batch梯度下降
#!/usr/bin/python #coding=utf-8 import numpy as np from scipy importstats import matplotlib.pyplot as plt # 构造训练数据 x = np.arange(0.,10.,0.2) m = len(x) # 训练数据点数目 print m x0 = np.full(m, 1.0) input_data = np.vstack([x0, x]).T # 将偏置b作为权向量的第一个分量 target_data = 2 *x + 5 +np.random.randn(m) # 两种终止条件 loop_max = 10000 #最大迭代次数(防止死循环) epsilon = 1e-3 # 初始化权值 np.random.seed(0) theta = np.random.randn(2) alpha = 0.001 #步长(注意取值过大会导致振荡即不收敛,过小收敛速度变慢) diff = 0. error = np.zeros(2) count = 0 #循环次数 finish = 0 #终止标志 minibatch_size = 5 #每次更新的样本数 while count < loop_max: count += 1 # minibatch梯度下降是在权值更新前对所有样例汇总误差,而随机梯度下降的权值是通过考查某个训练样例来更新的 # 在minibatch梯度下降中,权值更新的每一步对多个样例求和,需要更多的计算 for i inrange(1,m,minibatch_size): sum_m = np.zeros(2) for k inrange(i-1,i+minibatch_size-1,1): dif = (np.dot(theta, input_data[k]) - target_data[k]) *input_data[k] sum_m = sum_m + dif #当alpha取值过大时,sum_m会在迭代过程中会溢出 theta = theta- alpha * (1.0/minibatch_size) * sum_m #注意步长alpha的取值,过大会导致振荡 # 判断是否已收敛 if np.linalg.norm(theta- error) < epsilon: finish = 1 break else: error = theta print 'loopcount = %d'% count, '\tw:',theta print 'loop count = %d'% count, '\tw:',theta # check with scipy linear regression slope, intercept, r_value, p_value,slope_std_error = stats.linregress(x, target_data) print 'intercept = %s slope = %s'% (intercept, slope) plt.plot(x, target_data, 'g*') plt.plot(x, theta[1]* x +theta[0],'r') plt.show()
运行结果:
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
免责声明:本站资源来自互联网收集,仅供用于学习和交流,请遵循相关法律法规,本站一切资源不代表本站立场,如有侵权、后门、不妥请联系本站删除!
稳了!魔兽国服回归的3条重磅消息!官宣时间再确认!
昨天有一位朋友在大神群里分享,自己亚服账号被封号之后居然弹出了国服的封号信息对话框。
这里面让他访问的是一个国服的战网网址,com.cn和后面的zh都非常明白地表明这就是国服战网。
而他在复制这个网址并且进行登录之后,确实是网易的网址,也就是我们熟悉的停服之后国服发布的暴雪游戏产品运营到期开放退款的说明。这是一件比较奇怪的事情,因为以前都没有出现这样的情况,现在突然提示跳转到国服战网的网址,是不是说明了简体中文客户端已经开始进行更新了呢?
更新日志
- 凤飞飞《我们的主题曲》飞跃制作[正版原抓WAV+CUE]
- 刘嘉亮《亮情歌2》[WAV+CUE][1G]
- 红馆40·谭咏麟《歌者恋歌浓情30年演唱会》3CD[低速原抓WAV+CUE][1.8G]
- 刘纬武《睡眠宝宝竖琴童谣 吉卜力工作室 白噪音安抚》[320K/MP3][193.25MB]
- 【轻音乐】曼托凡尼乐团《精选辑》2CD.1998[FLAC+CUE整轨]
- 邝美云《心中有爱》1989年香港DMIJP版1MTO东芝首版[WAV+CUE]
- 群星《情叹-发烧女声DSD》天籁女声发烧碟[WAV+CUE]
- 刘纬武《睡眠宝宝竖琴童谣 吉卜力工作室 白噪音安抚》[FLAC/分轨][748.03MB]
- 理想混蛋《Origin Sessions》[320K/MP3][37.47MB]
- 公馆青少年《我其实一点都不酷》[320K/MP3][78.78MB]
- 群星《情叹-发烧男声DSD》最值得珍藏的完美男声[WAV+CUE]
- 群星《国韵飘香·贵妃醉酒HQCD黑胶王》2CD[WAV]
- 卫兰《DAUGHTER》【低速原抓WAV+CUE】
- 公馆青少年《我其实一点都不酷》[FLAC/分轨][398.22MB]
- ZWEI《迟暮的花 (Explicit)》[320K/MP3][57.16MB]