使用梯度下降法求二次函数极值问题

没有调学习率


import numpy as np
import matplotlib.pylab as plt


def _numerical_gradient_no_batch(f, x):  #求函数的梯度值
    h = 1e-4  # 0.0001
    grad = np.zeros_like(x)
    for idx in range(x.size):
        tmp_val = x[idx]
        x[idx] = float(tmp_val) + h
        fxh1 = f(x)  # f(x+h)
        x[idx] = tmp_val - h
        fxh2 = f(x)  # f(x-h)
        grad[idx] = (fxh1 - fxh2) / (2 * h)
        x[idx] = tmp_val  # 还原值
    return grad

def gradient_descent(f, init_x, lr=0.01, step_num=100):   #梯度下降法
    x = init_x            #初始化
    x_history = []        #记录寻优过程中的值

    for i in range(step_num):
        x_history.append( x.copy() )

        grad = _numerical_gradient_no_batch(f, x)   #计算函数梯度
        x -= lr * grad              #沿着梯度方向下降,空学习率控制每次下降的多少

    return x, np.array(x_history)


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

init_x = np.array([-3.0, 4.0])        #从(-3,4)开始搜索

lr = 0.1        #学习率为0.1
step_num = 20    #共搜索20步
x, x_history = gradient_descent(function_2, init_x, lr=lr, step_num=step_num)  #梯度下降法
#输出结果
print(x)   #结果很接近最小值(0,0)
print(x_history)
#画出历史值
x_=x_history[:,0]
y_=(x_+1)**2-1

print(x_)
print(y_)
plt.plot(x_history[:,0],(x_history[:,0]+1)**2-1 ,'o')
plt.xlim(-4,0)
plt.ylim(-2, 5)
plt.xlabel("X0")
plt.ylabel("y")
plt.show()

结果如下

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
下面是使用最速下降法解Beale函数的收敛路径的MATLAB代码: ```matlab % 定义Beale函数 f = @(x) (1.5 - x(1) + x(1).*x(2)).^2 + (2.25 - x(1) + x(1).*x(2).^2).^2 + (2.625 - x(1) + x(1).*x(2).^3).^2; % 计算梯度 grad_f = @(x) [2*(1.5-x(1)+x(1)*x(2))*(x(2)-1)+2*(2.25-x(1)+x(1)*x(2)^2)*(x(2)^2-1)+2*(2.625-x(1)+x(1)*x(2)^3)*x(2)^3; ... 2*(1.5-x(1)+x(1)*x(2))*x(1)+4*(2.25-x(1)+x(1)*x(2)^2)*x(1)*x(2)+6*(2.625-x(1)+x(1)*x(2)^3)*x(1)*x(2)^2]; % 初始点 x0 = [-4.5, 4.5]; % 最大迭代次数 max_iter = 100; % 步长 alpha = 0.01; % 收敛精度 epsilon = 1e-6; % 初始化 iter = 0; x = x0; % 记录收敛路径 path = x; % 迭代 while (iter < max_iter) % 计算梯度 g = grad_f(x); % 计算下降方向 d = -g; % 计算步长 t = alpha; % 检查步长是否合法 while (f(x+t*d) > f(x)) t = t/2; end % 更新x x = x + t*d; % 记录收敛路径 path = [path; x]; % 检查收敛精度 if (norm(g) < epsilon) break; end % 更新迭代次数 iter = iter + 1; end % 输出结果 disp('最优解:'); disp(x); disp('最优值:'); disp(f(x)); disp('收敛路径:'); disp(path); ``` 该程序包括以下几个步骤: 1. 定义Beale函数和梯度函数; 2. 定义初始点、最大迭代次数、步长和收敛精度; 3. 初始化迭代次数和x; 4. 记录收敛路径; 5. 迭代,直到收敛或达到最大迭代次数; 6. 计算梯度; 7. 计算下降方向; 8. 计算步长; 9. 更新x; 10. 记录收敛路径; 11. 检查收敛精度; 12. 更新迭代次数; 13. 输出结果。 在这个程序中,我们使用最速下降法来解Beale函数的最优解,并记录了收敛路径。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值