最速下降法—python实现

这篇具有很好参考价值的文章主要介绍了最速下降法—python实现。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1.基本原理

最速下降法就是从一个初始点开始,逐步沿着以当前点为基准,函数值变化最快的方向走,一直走到最优解为止。那么接下来就要考虑两个问题:(1)沿着什么方向走;(2)应该走多远;

我们知道,沿着函数中某点方向导数最大的方向走下降是最快的,那么我们就得去找平行于该点梯度的方向,沿着这个方向(当为max问题)或者沿着这个方向的反方向(当为min问题)去更新当前位置。再考虑走多远呢?这时我们就要沿着梯度的方向不断迭代,直到找到收敛的迭代点为止,这个点也就是我们要求的最优解。

2.python代码实现

下面来使用最速下降法求函数

最速下降法—python实现

的最小值,其中初始点为(0,0)。

下面给出两种实现代码:

import math 
from sympy import *
x1=symbols('x1')
x2=symbols('x2')
fun=x1**2+2*x2**2-2*x1*x2-2*x2
grad1=diff(fun,x1)
grad2=diff(fun,x2)
MaxIter=100
epsilon=0.0001
iter_cnt=0
current_step_size=100
x1_value=0
x2_value=0
grad1_value=(float)(grad1.subs({x1:x1_value,x2:x2_value}).evalf())
grad2_value=(float)(grad2.subs({x1:x1_value,x2:x2_value}).evalf())
current_obj=fun.subs({x1:x1_value,x2:x2_value}).evalf()
print('iterCnt:%2d  cur_point(%3.2f,%3.2f)  cur_obj:%5.4f  grad1:%5.4f  grad2:%5.4f '
      %(iter_cnt,x1_value,x2_value,current_obj,grad1_value,grad2_value))
while(abs(grad1_value) + abs(grad2_value) >= epsilon):  
    iter_cnt += 1
    t = symbols('t')
    x1_updated = x1_value - grad1_value * t
    x2_updated = x2_value - grad2_value * t
    Fun_updated = fun.subs({x1: x1_updated, x2: x2_updated})
    grad_t = diff(Fun_updated, t)
    t_value = solve(grad_t, t)[0]  # solve grad_t == 0

    grad1_value = (float)(grad1.subs({x1: x1_value, x2: x2_value}).evalf()) 
    grad2_value = (float)(grad2.subs({x1: x1_value, x2: x2_value}).evalf()) 

    x1_value = (float)(x1_value - t_value * grad1_value)
    x2_value = (float)(x2_value - t_value * grad2_value) 

    current_obj = fun.subs({x1: x1_value, x2: x2_value}).evalf()
    current_step_size = t_value

    print('iterCnt:%2d  cur_point(%3.2f, %3.2f)  cur_obj:%5.4f  grad_1:%5.4f  grad_2 :%5.4f' 
          % (iter_cnt, x1_value, x2_value, current_obj, grad1_value, grad2_value)) 
import numpy as np
from sympy import *
import math
import matplotlib.pyplot as plt
import mpl_toolkits.axisartist as axisartist

x1, x2, t = symbols('x1, x2, t')

def func():
    return pow(x1, 2) + 2 * pow(x2, 2) - 2 * x1 * x2 - 2 * x2

def grad(data):
    f = func()
    grad_vec = [diff(f, x1), diff(f, x2)]  # 求偏导数,梯度向量
    grad = []
    for item in grad_vec:
        grad.append(item.subs(x1, data[0]).subs(x2, data[1]))
    return grad

def grad_len(grad):
    vec_len = math.sqrt(pow(grad[0], 2) + pow(grad[1], 2))
    return vec_len

def zhudian(f):
    t_diff = diff(f)
    t_min = solve(t_diff)
    return t_min

def main(X0, theta):
    f = func()
    grad_vec = grad(X0)
    grad_length = grad_len(grad_vec)  # 梯度向量的模长
    k = 0
    data_x = [0]
    data_y = [0]
    while grad_length > theta:  # 迭代的终止条件
        k += 1
        p = -np.array(grad_vec)
        # 迭代
        X = np.array(X0) + t*p
        t_func = f.subs(x1, X[0]).subs(x2, X[1])
        t_min = zhudian(t_func)
        X0 = np.array(X0) + t_min*p
        grad_vec = grad(X0)
        grad_length = grad_len(grad_vec)
        print('grad_length', grad_length)
        print('坐标', float(X0[0]), float(X0[1]))
        data_x.append(X0[0])
        data_y.append(X0[1])

    print(k)

    # 绘图
    fig = plt.figure()
    ax = axisartist.Subplot(fig, 111)
    fig.add_axes(ax)
    ax.axis["bottom"].set_axisline_style("-|>", size=1.5)
    ax.axis["left"].set_axisline_style("->", size=1.5)
    ax.axis["top"].set_visible(False)
    ax.axis["right"].set_visible(False)
    plt.title(r'$Gradient \ method - steepest \ descent \ method$')
    plt.plot(data_x, data_y,color='r',label=r'$f(x_1,x_2)=x_1^2+2 \cdot x_2^2-2 \cdot x_1 \cdot x_2-2 \cdot x_2$')
    plt.legend()
    plt.scatter(1, 1, marker=(3, 1), c=2, s=100)
    plt.grid()
    plt.xlabel(r'$x_1$', fontsize=20)
    plt.ylabel(r'$x_2$', fontsize=20)
    plt.show()

if __name__ == '__main__':
	# 给定初始迭代点和阈值
    main([0, 0], 0.00001)

求解结果是在(1,1)点时有最小值-1。

最速下降法—python实现

参考博客:

Python实现最速下降法(The steepest descent method)详细案例

Python梯度法——最速下降法文章来源地址https://www.toymoban.com/news/detail-434359.html

到了这里,关于最速下降法—python实现的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 25.4 matlab里面的10中优化方法介绍——最速下降法(matlab程序)

    1. 简述        matlab实现最速下降法 定义:沿负梯度方向进行搜索的算法(负梯度方向为最速下降方向) 算法步骤: 步0:选取初始点x0,容许误差是e=[0~1],令k=1 步1:计算目标函数的梯度gk=▽f(xk))   若 ||gk||=e,即达到误差要求,立即停止计算,并输出xk作为近似最优解。 步

    2024年02月15日
    浏览(39)
  • 【编译原理】-- 递归下降语法分析设计原理与实现(C语言实现)

    本实验基于词法分析程序实现,可参考本人前面的文章。 目录 一、目标任务 二、程序功能描述 三、主要数据结构描述 四、程序结构描述 设计方法 First集和Follow集 递归子程序框图 函数定义及函数之间的调用关系 五、程序测试 测试用例1 测试结果1 测试用例2 测试结果2 测试

    2023年04月21日
    浏览(49)
  • 机器学习:基于梯度下降算法的线性拟合实现和原理解析

    当我们需要寻找数据中的趋势、模式或关系时,线性拟合和梯度下降是两个强大的工具。这两个概念在统计学、机器学习和数据科学领域都起着关键作用。本篇博客将介绍线性拟合和梯度下降的基本原理,以及它们在实际问题中的应用。 线性拟合是一种用于找到数据集中线性

    2024年02月10日
    浏览(35)
  • 机器学习:基于梯度下降算法的逻辑回归实现和原理解析

    当涉及到二元分类问题时,逻辑回归是一种常用的机器学习算法。它不仅简单而且有效,通常是入门机器学习领域的第一步。本文将介绍逻辑回归的基本概念、原理、应用场景和代码示例。 逻辑回归是一种用于解决二元分类问题的统计学习方法。尽管其名称中包含\\\"回归\\\"一词

    2024年02月09日
    浏览(51)
  • python实现梯度下降算法,并绘制等高线和3d图显示下降过程

    引言:         梯度下降算法是一种常用的优化算法,用于最小化目标函数。它在机器学习和深度学习中经常被用来更新模型的参数。在本文中,我们将使用Python实现梯度下降算法,并通过绘制等高线图和3D图表,直观地展示下降过程。 导入必要的库: 在开始之前,我们

    2024年04月17日
    浏览(42)
  • 【python手写算法】利用梯度下降实现线性拟合

    利用梯度下降实现线性拟合,效果和sklearn LinearRegression()差不多。 学习率初始设置为0.1结果算高的,直接让我的参数变成了nan。(体会到了飞出去的感觉) 把学习率调小了之后就正常了

    2024年02月15日
    浏览(46)
  • python机器学习(五)逻辑回归、决策边界、代价函数、梯度下降法实现线性和非线性逻辑回归

    线性回归所解决的问题是把数据集的特征传入到模型中,预测一个值使得误差最小,预测值无限接近于真实值。比如把房子的其他特征传入到模型中,预测出房价, 房价是一系列连续的数值,线性回归解决的是有监督的学习。有很多场景预测出来的结果不一定是连续的,我们

    2024年02月15日
    浏览(84)
  • 【编译原理】【C语言】实验三:递归下降分析法

    C语言 实验环境:Visual Studio 2019 author:zoxiii   用高级语言实现递归下降分析程序。使用输入串i*(i+i),输出分析栈中所有内容,并给出分析结果。   自顶向下分析就是从文法的开始符触发并寻找出这样一个推导序列:推导出的句子恰好为输入符号串;或者说,能否从根节

    2023年04月21日
    浏览(40)
  • 【初学人工智能原理】【3】梯度下降和反向传播:能改(上)

    本文教程均来自b站【小白也能听懂的人工智能原理】,感兴趣的可自行到b站观看。 本文【原文】章节来自课程的对白,由于缺少图片可能无法理解,故放到了最后,建议直接看代码(代码放到了前面)。 dataset.py 事实上三种方法的效果图是差不多的,所以只放出两张图 上一

    2024年02月06日
    浏览(35)
  • 【初学人工智能原理】【4】梯度下降和反向传播:能改(下)

    本文教程均来自b站【小白也能听懂的人工智能原理】,感兴趣的可自行到b站观看。 本文【原文】章节来自课程的对白,由于缺少图片可能无法理解,故放到了最后,建议直接看代码(代码放到了前面)。 在引入b后绘制代价函数界面,看看到底是不是一个碗 在w和b两个方向

    2024年02月05日
    浏览(42)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包