梯度下降法(BGD,SGD,MSGD)python+numpy具体实现
来源:互联网 发布:2016淘宝店好做吗 编辑:程序博客网 时间:2024/06/05 22:41
梯度下降是一阶迭代优化算法。为了使用梯度下降找到函数的局部最小值,一个步骤与当前位置的函数的梯度(或近似梯度)的负值成正比。如果相反,一个步骤与梯度的正数成比例,则接近该函数的局部最大值;该程序随后被称为梯度上升。梯度下降也被称为最陡峭的下降,或最快下降的方法。(from wikipad)
首先,大家要明白它的本质:这是一个优化算法!!!它是可以用来解决很多问题的,一般学习机器学习的朋友都会在线性回归的遇到这个名词,但是要声明的是,它和最小二乘法类似,是用于求解线性回归问题的一种方法。同时它的功能又不仅于此,它在线性回归中的意义在于通过寻找梯度最大的方向下降(或上升)来找到损失函数最小时候对应的参数值。
好了,绕来绕去的就拿线性回归的例子来和大家讲讲吧。
梯度下降方法
本质是每次迭代的时候都沿着梯度最大的地方更新参数。现在假设有函数(Rosenbrock函数:是一个用来测试最优化算法性能的非凸函数,由Howard Harry Rosenbrock在1960年提出[1]。也称为Rosenbrock山谷或Rosenbrock香蕉函数,也简称为香蕉函数)如下定义:
很明显,其最小最为
函数
在实现的过程中可以给出x, y初始值(例如设置为 0, 0) 然后计算函数在这个点的梯度,并按照梯度方向更新x, y的值。
这里给出通过梯度下降法计算上述函数的最小值对应的x 和 y
import numpy as npdef cal_rosenbrock(x1, x2): """ 计算rosenbrock函数的值 :param x1: :param x2: :return: """ return (1 - x1) ** 2 + 100 * (x2 - x1 ** 2) ** 2def cal_rosenbrock_prax(x1, x2): """ 对x1求偏导 """ return -2 + 2 * x1 - 400 * (x2 - x1 ** 2) * x1def cal_rosenbrock_pray(x1, x2): """ 对x2求偏导 """ return 200 * (x2 - x1 ** 2)def for_rosenbrock_func(max_iter_count=100000, step_size=0.001): pre_x = np.zeros((2,), dtype=np.float32) loss = 10 iter_count = 0 while loss > 0.001 and iter_count < max_iter_count: error = np.zeros((2,), dtype=np.float32) error[0] = cal_rosenbrock_prax(pre_x[0], pre_x[1]) error[1] = cal_rosenbrock_pray(pre_x[0], pre_x[1]) for j in range(2): pre_x[j] -= step_size * error[j] loss = cal_rosenbrock(pre_x[0], pre_x[1]) # 最小值为0 print("iter_count: ", iter_count, "the loss:", loss) iter_count += 1 return pre_xif __name__ == '__main__': w = for_rosenbrock_func() print(w)
如果大家想运行这个算法,建议使用默认的参数,效果还不错。不要把step_size设置过大,会出问题的(可能是实现过程有问题,请指正)。
线性回归问题
这里关于回归的前导介绍我建议大家取看周志华老师的西瓜书,介绍得通透明亮,但是周老师对线性回归问题给出的解决方法是通过最小二乘法来做的,而我们在这里要用梯度下降。
这里给出一般的定义吧~
一般的线性回归方程如下:
转换为:
这里
现在需要定义损函数,用于判断最后得到的预测参数的预测效果。常用的损失函数是均方误差:
更新公式为:
BGM(批量梯度下降法)
import numpy as npdef gen_line_data(sample_num=100): """ y = 3*x1 + 4*x2 :return: """ x1 = np.linspace(0, 9, sample_num) x2 = np.linspace(4, 13, sample_num) x = np.concatenate(([x1], [x2]), axis=0).T y = np.dot(x, np.array([3, 4]).T) # y 列向量 return x, ydef bgd(samples, y, step_size=0.01, max_iter_count=10000): sample_num, dim = samples.shape y = y.flatten() w = np.ones((dim,), dtype=np.float32) loss = 10 iter_count = 0 while loss > 0.001 and iter_count < max_iter_count: loss = 0 error = np.zeros((dim,), dtype=np.float32) for i in range(sample_num): predict_y = np.dot(w.T, samples[i]) for j in range(dim): error[j] += (y[i] - predict_y) * samples[i][j] for j in range(dim): w[j] += step_size * error[j] / sample_num for i in range(sample_num): predict_y = np.dot(w.T, samples[i]) error = (1 / (sample_num * dim)) * np.power((predict_y - y[i]), 2) loss += error print("iter_count: ", iter_count, "the loss:", loss) iter_count += 1 return wif __name__ == '__main__': samples, y = gen_line_data() w = bgd(samples, y) print(w) # 会很接近[3, 4]
SGB(随机梯度下降法)
import numpy as npdef gen_line_data(sample_num=100): """ y = 3*x1 + 4*x2 :return: """ x1 = np.linspace(0, 9, sample_num) x2 = np.linspace(4, 13, sample_num) x = np.concatenate(([x1], [x2]), axis=0).T y = np.dot(x, np.array([3, 4]).T) # y 列向量 return x, ydef sgd(samples, y, step_size=0.01, max_iter_count=10000): """ 随机梯度下降法 :param samples: 样本 :param y: 结果value :param step_size: 每一接迭代的步长 :param max_iter_count: 最大的迭代次数 :param batch_size: 随机选取的相对于总样本的大小 :return: """ sample_num, dim = samples.shape y = y.flatten() w = np.ones((dim,), dtype=np.float32) loss = 10 iter_count = 0 while loss > 0.001 and iter_count < max_iter_count: loss = 0 error = np.zeros((dim,), dtype=np.float32) for i in range(sample_num): predict_y = np.dot(w.T, samples[i]) for j in range(dim): error[j] += (y[i] - predict_y) * samples[i][j] w[j] += step_size * error[j] / sample_num # for j in range(dim): # w[j] += step_size * error[j] / sample_num for i in range(sample_num): predict_y = np.dot(w.T, samples[i]) error = (1 / (sample_num * dim)) * np.power((predict_y - y[i]), 2) loss += error print("iter_count: ", iter_count, "the loss:", loss) iter_count += 1 return wif __name__ == '__main__': samples, y = gen_line_data() w = sgd(samples, y) print(w) # 会很接近[3, 4]
MBGB(小批量梯度下降法)
import numpy as npimport randomdef gen_line_data(sample_num=100): """ y = 3*x1 + 4*x2 :return: """ x1 = np.linspace(0, 9, sample_num) x2 = np.linspace(4, 13, sample_num) x = np.concatenate(([x1], [x2]), axis=0).T y = np.dot(x, np.array([3, 4]).T) # y 列向量 return x, ydef mbgd(samples, y, step_size=0.01, max_iter_count=10000, batch_size=0.2): """ MBGD(Mini-batch gradient descent)小批量梯度下降:每次迭代使用b组样本 :param samples: :param y: :param step_size: :param max_iter_count: :param batch_size: :return: """ sample_num, dim = samples.shape y = y.flatten() w = np.ones((dim,), dtype=np.float32) # batch_size = np.ceil(sample_num * batch_size) loss = 10 iter_count = 0 while loss > 0.001 and iter_count < max_iter_count: loss = 0 error = np.zeros((dim,), dtype=np.float32) # batch_samples, batch_y = select_random_samples(samples, y, # batch_size) index = random.sample(range(sample_num), int(np.ceil(sample_num * batch_size))) batch_samples = samples[index] batch_y = y[index] for i in range(len(batch_samples)): predict_y = np.dot(w.T, batch_samples[i]) for j in range(dim): error[j] += (batch_y[i] - predict_y) * batch_samples[i][j] for j in range(dim): w[j] += step_size * error[j] / sample_num for i in range(sample_num): predict_y = np.dot(w.T, samples[i]) error = (1 / (sample_num * dim)) * np.power((predict_y - y[i]), 2) loss += error print("iter_count: ", iter_count, "the loss:", loss) iter_count += 1 return wif __name__ == '__main__': samples, y = gen_line_data() w = mbgd(samples, y) print(w) # 会很接近[3, 4]
- 梯度下降法(BGD,SGD,MSGD)python+numpy具体实现
- 批量梯度下降(BGD)、随机梯度下降(SGD)、小批量随机梯度下降(MSGD)实现过程详解
- 批量梯度下降(BGD)、随机梯度下降(SGD)、小批量随机梯度下降(MSGD)实现过程详解
- 批量梯度下降(BGD)、随机梯度下降(SGD)、小批量随机梯度下降(MSGD)实现过程详解
- 批量梯度下降BGD、随机梯度下降SGD、小批量随机梯度下降MSGD
- 批量梯度下降(BGD)、随机梯度下降(SGD)、小批量随机梯度下降(MSGD)的理解与实现
- 梯度下降法(SGD+BGD+MBGD)
- 批量梯度下降(BGD)、随机梯度下降(SGD)、小批量随机梯度下降(MSGD)
- 批量梯度下降法BGD,随机梯度下降法SGD
- 梯度下降法的三种解释(BGD,SGD,MBGD).
- 机器学习--梯度下降法(BGD、SGD、MBGD)
- machine learning - 梯度下降(bgd\sgd)
- 批处理梯度下降BGD与随机梯度下降SGD
- python实现随机梯度下降(SGD)
- 批量梯度下降算法BGD,小批量梯度下降法MBGD,随机梯度下降算法SGD的比较
- 机器学习小组知识点4&5:批量梯度下降法(BGD)和随机梯度下降法(SGD)的代码实现Matlab版
- 梯度下降、随机梯度下降(SGD)、批量梯度下降(BGD)的对比
- Machine Learning] 梯度下降法的三种形式BGD、SGD以及MBGD
- mysqld: File './mysql-bin.index' not found (Errcode: 13
- CSU 1908: The Big Escape
- LeetCode刷题(C++)——Reverse Integer(Easy)
- 多线程学习笔记(四)之线程间通信---等待唤醒机制
- 监控集群的状态
- 梯度下降法(BGD,SGD,MSGD)python+numpy具体实现
- Lecture 11: Hopfield Nets
- JAVA使用JOONE实现神经网络的官网例子
- 算法分析与设计课程07——330. Patching Array(Hard)
- 先来先服务算法(FCFS)和 短作业优先算法(SJF)
- 编码练习——Java-6-类的高级特性
- 网络名称空间netns的用法
- primefaces 推送服务报Uncaught SyntaxError: Unexpected token < in JSON at position 0
- 将1-20这二十个连续的自然数排成一圈,使任意两个相邻的自然数之和均为素数