梯度下降法
来源:互联网 发布:百雀羚vs欧莱雅 知乎 编辑:程序博客网 时间:2024/06/06 04:50
线性回归中参数解析式的求解涉及到矩阵的求逆,当特征矩阵数据量过大,求逆是一个很耗时的过程,我们可以使用先对特征矩阵做奇异值分解(SVD)后再求广义逆
根据梯度反方向
其中
以平方损失为例,参数
批量梯度下降法(BGD)
批量梯度下降法(Batch Gradient Descent,简称BGD)是梯度下降法最原始的形式,具体思路是在更新每一参数时使用所有的样本来进行更新。BGD一定可以得到一个局部极值,在线性回归中可以得到全局最优解。
样本预测值为
代码实现
for j in range(n): for i in range(m): diff += (y[i]- np.dot(theta,x[i])) * x[i][j] theta[j] = theta[j] + alpha *1/m* diff
随机梯度下降法(SGD)
批量梯度下降法更新一个参数的时候需要用到所有样本,所以训练速度会随着样本数量增加而变得非常缓慢,随机梯度(Stochastic Gradient Decent ,简称SGD)的解决办法就是通过单个样本的损失函数对参数求偏导来更新梯度。
参数更新:
代码实现:
i = random.randint(0, m - 1)diff = y[i] - np.dot(theta, x[i])for j in range(n): theta[j] = theta[j] + alpha * diff * x[i][j]
比较图发现,SGD震荡下降,在极值点附近震荡,因为不需要用到所有样本进行更新参数,所以下降更快,但可能迭代次数会更多。
由于SGD是震荡下降,所以有可能在震荡下降过程中可能跳出次局部极值,找到全局极小值。SGD因为不需要用到所有的样本,所以更适合于做在线学习。
小批量梯度下降法(MBGD)
SGD的缺点也很明显,噪音较BGD要多,虽然整体往最优值方向移动,但每次迭代并非都向整体最优方向。
为了保证算法的训练速度,同时也保证参数训练的准确率,于是就有了小批量梯度下降法(Mini-batch Gradient Decent ,简称MBGD),抽取部分样本进行参数更新,视训练集规模人为给定抽取的样本个数,代码可参考BGD与SGD。
附录
①:若
从方程的直观意义上可定义广义逆矩阵:
②:梯度方向
③:
# coding=utf-8# !/usr/bin/pythonimport matplotlib.pyplot as pltimport matplotlib as mplimport numpy as npimport warningsimport randomnp.set_printoptions(suppress=True)np.set_printoptions(precision=1)warnings.filterwarnings("ignore")# 构造数据 样本x 目标值yN = 100xNew = []x = np.linspace(0, 6, N) + np.random.randn(N)x = np.sort(x)print(x)z = [1 for i in range(len(x))]y = 4 * x - 3 + np.random.randn(N) # 通过一次函数加入随机扰动构造值x1 = xfor i in range(len(x)): tempMat = [z[i], round(x[i], 2)] xNew.append(tempMat)x = xNewepsilon = 0.01alpha = 0.05 # 学习率error1 = 0 # 当前权重损失值error0 = 0 # 上一次权重损失值time = 0 # 迭代次数errors = [] # 损失值数组times = []n = len(x[0]) # 变量个数 考虑截距项m = len(x) # 样本数theta = [0 for i in range(n)]while True: diff = 0 # 随机梯度下降 begin # i = random.randint(0, m - 1) # diff = y[i] - np.dot(theta, x[i]) # for j in range(n): # theta[j] = theta[j] + alpha * diff * x[i][j] # 随机梯度下降 end #批量梯度下降 begin for j in range(n): for i in range(m): diff += (y[i]- np.dot(theta,x[i])) * x[i][j] theta[j] = theta[j] + alpha *1/m* diff #批量梯度下降 end error1 = 0 for i in range(m): error1 += (y[i] - (np.dot(theta, x[i]))) ** 2 / 2 # 计算损失值 errors.append(error1) times.append(time) time += 1 if abs(error1 - error0) < epsilon: break else: error0 = error1 if time == 100: # 迭代到达100次停止 break# 画图mpl.rcParams['font.sans-serif'] = [u'simHei']mpl.rcParams['axes.unicode_minus'] = Falseplt.figure(figsize=(12, 9))plt.subplot(1, 2, 1)plt.plot(times, errors, 'g-', linewidth=2)plt.title(u'损失曲线', fontsize=18)plt.xlabel(u'次数', fontsize=15)plt.ylabel(u'损失值', fontsize=15)plt.legend(loc='upper right')plt.grid()plt.subplot(1, 2, 2)plt.plot(x1, y, 'bo', linewidth=2, label=u'原始数据')x = np.arange(-2, 8)y = theta[0] + theta[1] * xplt.plot(x, y, 'r-', linewidth=2, label=u'回归模型')plt.xlabel(u'X', fontsize=15)plt.ylabel(u'Y', fontsize=15)plt.title(u'回归拟合', fontsize=18)plt.legend(loc='upper left')plt.grid()plt.show()print('Done: theta0 : %f, theta1 : %f' % (theta[0], theta[1]))
git clone代码地址:https://code.csdn.net/snippets/2552953.git
- 梯度下降法
- 梯度下降法
- 梯度下降法
- 梯度下降法
- 梯度下降法 简记
- 梯度下降法一
- 梯度下降法二
- 梯度下降法三
- 梯度下降法
- 梯度下降法实例
- 梯度下降法
- 梯度下降法
- 随机梯度下降法
- 梯度下降法
- 梯度下降法
- 梯度下降法
- 梯度下降法入门
- 梯度下降法
- numpy的newaxis使用
- zoj2849Attack of Panda Virus
- Java中的常用术语
- web前端面试题
- springMVC结合hibernate validator校验数据
- 梯度下降法
- 数据结构
- 获得各种系统路径
- 算法提高 ADV-17 统计单词数
- C/C++字符或字符串的输入
- java 动态代理 生成字节码文件
- java中的转义字符
- zcmu1507
- cf 729D Sea Battle 【模拟,贪心】