python实现最速下降法求二元函数极值并绘制3D图像

目标

原函数: f(x) = 2x1x1 + x2x2 -2x1*x2 - 4x1 + 4
起始点 为(0,0)
精度 :误差要求小于 10**(-3)

过程:
在这里插入图片描述

直接上代码看注释吧()

import numpy as np
import math
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D


def f(x):
    return 2*x[0]**2 + x[1]**2 - 2*x[0]*x[1]-4*x[0]+4   

def step(x):      # 计算每次迭代的步长,H为该函数的hessian矩阵
    H = np.matrix([[4, -
<think>嗯,用户想在PyCharm里用梯度下降法多元函数的极小值,那我得一步步指导他们。首先,我需要解释梯度下降法的基本原理,这样他们理解代码时会更容易。然后,得考虑如何用Python实现,特别是多元函数的情况。可能需要用到numpy来处理向量和矩阵运算,因为多元函数的变量是多个的,用数组更方便。 接下来,要确定代码的结构。首先定义目标函数,比如一个例子函数,比如f(x) = x₁² + 2x₂² + 2x₃²,或者其他合适的例子。然后计算梯度,这里要说明梯度是各个偏导数组成的向量。手动计算梯度的话,用户可能容易理解,但如果是更复杂的函数,可能需要自动微分,但这里为了简单,可能先手动写出梯度函数。 然后,初始化参数,比如学习率、迭代次数、收敛阈值等。初始的选择也很重要,可以随机或者固定。在迭代过程中,需要计算当前的梯度和更新参数,同时检查梯度的大小是否小于阈值来决定是否停止循环。 要注意代码中的变量维度是否正确,特别是向量运算,避免出现形状错误。可能需要在代码中加入打印语句,显示每次迭代的结果,方便调试。此外,学习率的选择会影响收敛,可能需要提醒用户如果结果不收敛,可以调整学习率或者增加迭代次数。 用户可能遇到的问题包括梯度计算错误、学习率过大或过小导致震荡或不收敛,还有代码中的语法错误,比如numpy数组的操作不正确。需要提醒他们检查梯度函数是否正确,以及参数的更新是否正确。 最后,测试代码时可以用一个已知极小值的函数,比如二次函数,这样容易验证结果是否正确。例如,例子中的函数极小值在原,所以结果应该接近(0,0,0)。可能还需要展示输出结果,说明迭代过程中的损失变化,让用户更直观地理解过程。 总结下来,步骤应该是:导入库、定义函数和梯度、初始化参数、迭代更新、检查收敛、输出结果。同时,扩展部分可以提到随机梯度下降、动量法等其他优化方法,让用户有进一步学习的空间。还要注意代码的格式和注释,确保在PyCharm中能够顺利运行。</think>在PyCharm中实现梯度下降法多元函数极小值的步骤如下,我们将以二元函数$f(x,y) = x^2 + 2y^2$为例进行说明: --- ### 一、梯度下降法原理 1. **核心思想**:沿着负梯度方向迭代更新参数 2. **更新公式**: $$ \theta_{k+1} = \theta_k - \alpha \nabla f(\theta_k) $$ 其中$\alpha$为学习率,$\nabla f$为梯度 --- ### 二、代码实现步骤 #### 1. 导入所需库 ```python import numpy as np ``` #### 2. 定义目标函数 ```python def objective_function(x): return x[0]**2 + 2*x[1]**2 # f(x,y)=x²+2y² ``` #### 3. 计算梯度(手动推导) ```python def compute_gradient(x): return np.array([2*x[0], 4*x[1]]) # 梯度∇f=(2x,4y) ``` #### 4. 梯度下降参数设置 ```python learning_rate = 0.1 # 学习率 max_iter = 100 # 最大迭代次数 epsilon = 1e-6 # 收敛阈值 x_init = np.array([5.0, 3.0]) # 初始(5,3) ``` #### 5. 迭代过程 ```python x = x_init.copy() history = [] for i in range(max_iter): grad = compute_gradient(x) x_new = x - learning_rate * grad # 记录迭代过程 history.append({ 'iter': i+1, 'x': x.copy(), 'f(x)': objective_function(x), 'grad': grad }) # 收敛判断 if np.linalg.norm(grad) < epsilon: break x = x_new ``` #### 6. 输出结果 ```python print(f"极小值: ({x[0]:.6f}, {x[1]:.6f})") print(f"函数值: {objective_function(x):.6f}") print(f"经过 {len(history)} 次迭代后收敛") ``` --- ### 三、完整代码示例 ```python import numpy as np def objective_function(x): return x[0]**2 + 2*x[1]**2 def compute_gradient(x): return np.array([2*x[0], 4*x[1]]) # 参数设置 learning_rate = 0.1 max_iter = 100 epsilon = 1e-6 x_init = np.array([5.0, 3.0]) # 梯度下降 x = x_init.copy() history = [] for i in range(max_iter): grad = compute_gradient(x) x_new = x - learning_rate * grad history.append({ 'iter': i+1, 'x': x.copy(), 'f(x)': objective_function(x), 'grad': grad }) if np.linalg.norm(grad) < epsilon: break x = x_new # 输出结果 print(f"极小值: ({x[0]:.6f}, {x[1]:.6f})") print(f"函数值: {objective_function(x):.6f}") print(f"经过 {len(history)} 次迭代后收敛") ``` --- ### 四、关键说明 1. **学习率选择**:过大容易震荡,过小收敛慢(建议尝试0.01-0.3) 2. **收敛判断**:除了梯度范数,也可用参数变化量或函数值变化量 3. **高维扩展**:对于n元函数$f(x_1,x_2,...,x_n)$,梯度应为$\nabla f = (\frac{\partial f}{\partial x_1},...,\frac{\partial f}{\partial x_n})$ --- ### 五、扩展建议 1. 添加可视化模块绘制收敛曲线 2. 实现自适应学习率(如Adam优化器) 3. 添加动量项(Momentum)加速收敛 4. 对不可导函数使用次梯度方法 在PyCharm中运行时,可以通过调试模式观察变量变化,使用科学模式查看数组值,这对理解算法过程非常有帮助。
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值