梯度下降算法(1) - Python实现

  • 算法介绍
    梯度下降算法是一种利用一次导数信息求取目标函数极值的方法,也是目前应用最为广泛的局部优化算法之一。其具有实现简单、容易迁移、收敛速度较快的特征。在求解过程中,从预设的种子点开始,根据梯度信息逐步迭代更新,使得种子点逐渐向目标函数的极小值点移动,最终到达目标函数的极小值点。
    注意,沿梯度正向移动,将获取目标函数局部极大值梯度上升算法);沿梯度反向移动,将获取目标函数局部极小值梯度下降算法)。
  • 迭代公式
    设向量$\vec g_k$表示目标函数在种子点$\vec x_k$处的梯度(即一次导数)。此时,根据梯度信息的指导,可以使得种子点更加接近该向量方向的极值点(注意,目标函数真实的极值点是全方向的)。
    求取极小值,沿梯度反方向移动(即梯度下降):
    \begin{equation}\label{eq_1}
    \vec x_{k+1} = \vec x_k - {\lambda}_k \vec s_k
    \end{equation}
    求取极大值,沿梯度正方向移动(即梯度上升):
    \begin{equation}\label{eq_2}
    \vec x_{k+1} = \vec x_k + {\lambda}_k \vec s_k
    \end{equation}
    其中,$\vec s_k = \frac{\vec g_k}{\left| \vec g_k \right|}$代表归一化梯度,${\lambda}_k$代表种子点沿梯度方向移动的步长幅度参数
    很显然,对幅度参数${\lambda}_k$的设置也属于算法的一部分。最常见的有两种方法:1)线性搜寻法;2)可调步长法
    线性搜寻法中,在种子点的梯度方向上搜寻到极值点附近的步长幅度参数${\lambda}_k$,然后移动种子点至该方向的极值点处。继续计算种子点新的梯度方向,并在该方向上移动。直到种子点到达全方向的极值点处,迭代即可终止。
    可调步长法中,通常先将${\lambda}_k$设为1。然后依据上面的迭代公式(式$\ref{eq_1}$或式$\ref{eq_2}$),预先计算下一步可能的$x_{k+1}$。如果$x_{k+1}$满足接近极值点的要求,则将种子点由$x_k$移至$x_{k+1}$,并增加${\lambda}_k$值为原先的$1.2$倍;否则,不移动种子点,并将${\lambda}_k$值减小为原先的$0.5$倍。如此反复迭代计算,逐步移动种子点并改变${\lambda}_k$值至找到极值点为止。由于${\lambda}_k$值随下一步的预计算情况逐步作出调整,因此笔者也将其称为动态调整技术
    从节省计算资源的角度考虑,以下笔者将采用动态调整技术完成对梯度下降算法的示例,仅供参考!
  • Python代码实现

     1 import matplotlib.pyplot as plt
     2 import numpy
     3
     4
     5 class GD(object):
     6
     7     def __init__(self, seed=None, precision=1.E-6):
     8         self.seed = GD.get_seed(seed)                    # 梯度下降算法的种子点
     9         self.prec = precision                            # 梯度下降算法的计算精度
    10
    11         self.path = list()                               # 记录种子点的路径及相应的目标函数值
    12         self.solve()                                     # 求解主体
    13         self.display()                                   # 数据可视化展示
    14
    15     def solve(self):
    16         x_curr = self.seed
    17         val_curr = GD.func(*x_curr)
    18         self.path.append((x_curr, val_curr))
    19
    20         omega = 1
    21         while omega > self.prec:
    22             x_delta = omega * GD.get_grad(*x_curr)
    23             x_next = x_curr - x_delta                    # 沿梯度反向迭代
    24             val_next = GD.func(*x_next)
    25
    26             if numpy.abs(val_next - val_curr) < self.prec:
    27                 break
    28
    29             if val_next < val_curr:
    30                 x_curr = x_next
    31                 val_curr = val_next
    32                 omega *= 1.2
    33                 self.path.append((x_curr, val_curr))
    34             else:
    35                 omega *= 0.5
    36
    37     def display(self):
    38         print(‘Iteration steps: {}‘.format(len(self.path)))
    39         print(‘Seed: ({})‘.format(‘, ‘.join(str(item) for item in self.path[0][0])))
    40         print(‘Solution: ({})‘.format(‘, ‘.join(str(item) for item in self.path[-1][0])))
    41
    42         fig = plt.figure(figsize=(10, 4))
    43
    44         ax1 = plt.subplot(1, 2, 1)
    45         ax2 = plt.subplot(1, 2, 2)
    46
    47         ax1.plot(numpy.array(range(len(self.path))) + 1, numpy.array(list(item[1] for item in self.path)), ‘k.‘)
    48         ax1.plot(1, self.path[0][1], ‘go‘, label=‘starting point‘)
    49         ax1.plot(len(self.path), self.path[-1][1], ‘r*‘, label=‘solution‘)
    50         ax1.set(xlabel=‘$iterCnt$‘, ylabel=‘$iterVal$‘)
    51         ax1.legend()
    52
    53         x = numpy.linspace(-100, 100, 500)
    54         y = numpy.linspace(-100, 100, 500)
    55         x, y = numpy.meshgrid(x, y)
    56         z = GD.func(x, y)
    57         ax2.contour(x, y, z, levels=36)
    58
    59         x2 = numpy.array(list(item[0][0] for item in self.path))
    60         y2 = numpy.array(list(item[0][1] for item in self.path))
    61         ax2.plot(x2, y2, ‘k--‘, linewidth=2)
    62         ax2.plot(x2[0], y2[0], ‘go‘, label=‘starting point‘)
    63         ax2.plot(x2[-1], y2[-1], ‘r*‘, label=‘solution‘)
    64
    65         ax2.set(xlabel=‘$x$‘, ylabel=‘$y$‘)
    66         ax2.legend()
    67
    68         fig.tight_layout()
    69         fig.savefig(‘test_plot.png‘, dpi=500)
    70
    71         plt.show()
    72         plt.close()
    73
    74     # 内部种子生成函数
    75     @staticmethod
    76     def get_seed(seed):
    77         if seed is not None:
    78             return numpy.array(seed)
    79         return numpy.random.uniform(-100, 100, 2)
    80
    81     # 目标函数
    82     @staticmethod
    83     def func(x, y):
    84         return 5 * x ** 2 + 2 * y ** 2 + 3 * x - 10 * y + 4
    85
    86     # 目标函数的归一化梯度
    87     @staticmethod
    88     def get_grad(x, y):
    89         grad_ori = numpy.array([10 * x + 3, 4 * y - 10])
    90         length = numpy.linalg.norm(grad_ori)
    91         if length == 0:
    92             return numpy.zeros(2)
    93         return grad_ori / length
    94
    95
    96 if __name__ == ‘__main__‘:
    97     GD()

    笔者所用示例函数为:
    \begin{equation}
    f(x, y) = 5x^2 + 2y^2 + 3x - 10y + 4
    \end{equation}

  • 结果展示

原文地址:https://www.cnblogs.com/xxhbdk/p/10023110.html

时间: 2024-11-09 02:45:19

梯度下降算法(1) - Python实现的相关文章

(转)梯度下降法及其Python实现

梯度下降法(gradient descent),又名最速下降法(steepest descent)是求解无约束最优化问题最常用的方法,它是一种迭代方法,每一步主要的操作是求解目标函数的梯度向量,将当前位置的负梯度方向作为搜索方向(因为在该方向上目标函数下降最快,这也是最速下降法名称的由来).梯度下降法特点:越接近目标值,步长越小,下降速度越慢.直观上来看如下图所示: 这里每一个圈代表一个函数梯度,最中心表示函数极值点,每次迭代根据当前位置求得的梯度(用于确定搜索方向以及与步长共同决定前进速度)和

梯度下降法及其Python实现

梯度下降法(gradient descent),又名最速下降法(steepest descent)是求解无约束最优化问题最常用的方法,它是一种迭代方法,每一步主要的操作是求解目标函数的梯度向量,将当前位置的负梯度方向作为搜索方向(因为在该方向上目标函数下降最快,这也是最速下降法名称的由来). 梯度下降法特点:越接近目标值,步长越小,下降速度越慢. 直观上来看如下图所示: 这里每一个圈代表一个函数梯度,最中心表示函数极值点,每次迭代根据当前位置求得的梯度(用于确定搜索方向以及与步长共同决定前进速度

机器学习:梯度下降算法原理讲解

背景 学习机器学习时作为基础概念. 转载自: <梯度下降算法原理讲解--机器学习> 1. 概述 梯度下降(gradient descent)在机器学习中应用十分的广泛,不论是在线性回归还是Logistic回归中,它的主要目的是通过迭代找到目标函数的最小值,或者收敛到最小值. 本文将从一个下山的场景开始,先提出梯度下降算法的基本思想,进而从数学上解释梯度下降算法的原理,解释为什么要用梯度,最后实现一个简单的梯度下降算法的实例! 2. 梯度下降算法 2.1 场景假设 梯度下降法的基本思想可以类比为

简单多元线性回归(梯度下降算法与矩阵法)

多元线性回归是最简单的机器学习模型,通过给定的训练数据集,拟合出一个线性模型,进而对新数据做出预测. 对应的模型如下: n: 特征数量. 一般选取残差平方和最小化作为损失函数,对应为: M:训练样本数量. 通过最小化代价损失函数,来求得 值,一般优化的方法有两种,第一是梯度下降算法(Gradient Descent),第二种是矩阵法(The normal equations). 梯度下降算法

自适应滤波:梯度下降算法

作者:桂. 时间:2017-04-01  06:39:15 链接:http://www.cnblogs.com/xingshansi/p/6654372.html 声明:欢迎被转载,不过记得注明出处哦~ [学习笔记07] 未完待续 前言 西蒙.赫金的<自适应滤波器原理>第四版第四章:最速下降算法.优化求解按照有/无约束分类:如投影梯度下降算法((Gradient projection)便是有约束的优化求解:按照一阶二阶分类:梯度下降(Gradient descent).Newton法等:按照偏

梯度下降算法笔记

今天课上主要讲的是梯度下降算法. 上一次老师留了梯度下降算法求解线性回归的作业.大部分用java和C++实现的. 笔记也主要来自课程ppt,老师课程的ppt也主要参考的斯坦福吴恩达老师的讲义. 梯度下降法(英语:Gradient descent)是一个一阶最优化算法,通常也称为最速下降法. 要使用梯度下降法找到一个函数的局部极小值,必须向函数上当前点对应梯度(或者是近似梯度)的反方向的规定步长距离点进行迭代搜索.如果相反地向梯度正方向迭代进行搜索,则会接近函数的局部极大值点:这个过程则被称为梯度

梯度下降算法

首先定义几个符号: Xi vector[X]:input data Yi vector[Y]:output data h(X) hypothesis function 对于输入的数据给出预测值 Y is continous variation?regression problem(回归问题) Y is discrete variation?classification problem(分类问题) PART 1:线性回归 如图,蓝色的离散点是Xi,红色的线就是求出的回归函数. hypothesis

梯度下降算法的一点认识

昨天开始看Ng教授的机器学习课,发现果然是不错的课程,一口气看到第二课. 第一课 没有什么新知识,就是机器学习的概况吧. 第二课 出现了一些听不太懂的概念.其实这堂课主要就讲了一个算法,梯度下降算法.到了教授推导公式的时候感觉有点蒙,不过后来仔细想想,也大概理解了,这个算法并没有想象的晦涩.在这堂课中,梯度下降算法是为了解决线性回归问题的.视频中的例子是给你一堆训练数据,(房子面积和对应房价),如果此时给你一个没有出现过的房子面积数据,您能否给出正确的房价?解决思路是首先要看出来房子面积跟房价之

神经网络与深度学习(2):梯度下降算法和随机梯度下降算法

本文总结自<Neural Networks and Deep Learning>第1章的部分内容. 使用梯度下降算法进行学习(Learning with gradient descent) 1. 目标 我们希望有一个算法,能让我们找到权重和偏置,以至于网络的输出y(x) 能够拟合所有的训练输入x. 2. 代价函数(cost function) 定义一个Cost function (loss function, objective function): 目标函数,如下: C: 被称为二次代价函数