引言:
梯度下降算法是一种常用的优化算法,用于最小化目标函数。它在机器学习和深度学习中经常被用来更新模型的参数。在本文中,我们将使用Python实现梯度下降算法,并通过绘制等高线图和3D图表,直观地展示下降过程。
- 导入必要的库: 在开始之前,我们需要导入一些Python库。我们使用NumPy进行数值计算,Matplotlib用于绘图。以下是导入库的代码
import numpy as np import matplotlib.pyplot as plt
- 定义目标函数: 我们选择一个简单的二维函数来演示梯度下降算法,使用func函数作为我们的目标函数:
def func(x,y): return x**2 + y**2
- 计算梯度: 在梯度下降算法中,我们需要计算目标函数关于参数的梯度。对于Rosenbrock函数,我们可以使用以下代码计算梯度(也就是对x,y分别求偏导):
def grad(x,y): return 2*x, 2*y
- 实现梯度下降算法: 我们可以使用以下代码实现梯度下降算法:
# 设置初始点 x_start,y_start=15,15 theta=1e-5 # θ =10**-6 设置阈值 learning_rate=0.2 # 学习率 # 记录下初始x y值 x_history=[x_start] y_history=[y_start] z_history=[func(x_start,y_start)] #记录迭代次数 cnt=0 while True: cnt+=1 # 计算此时梯度 grad_x,grad_y=grad(x_start,y_start) '''计算梯度的范数 即 向量的长度''' grad_num=np.sqrt(grad_x**2+grad_y**2) # 梯度下降 即x-grad*learn_rate x_start-=grad_x*learning_rate y_start-=grad_y*learning_rate # 将梯度下降过程写入列表 x_history.append(x_start) y_history.append(y_start) # 判读梯度范数是否小于阈值 if grad_num<theta: print(f"一共迭代了{cnt}次") break else: continue
- 绘制等高线图和3D图表: 最后一步是绘制等高线图和3D图表,以可视化下降过程。这里是相应的代码:
#生成-20到20的500个点,用于绘制图像 x=np.linspace(-20,20,500) y=np.linspace(-20,20,500) # 绘制网格线 X, Y = np.meshgrid(x, y) Z = func(X, Y) fig=plt.figure(figsize=(8, 8)) ax = fig.add_subplot(121, projection='3d') ax.scatter(x_history, y_history, func(np.array(x_history), np.array(y_history)),c='red', marker='o', alpha=1) ax.plot_surface(X, Y, Z, cmap='viridis',alpha=0.8) # alpha设置透明度 ax.set_title("3D Plot of f(x, y) = x^2/5 + y^2/3") ax.set_xlabel("x") ax.set_ylabel("y") # 记录迭代的痕迹 scatter cs=fig.add_subplot(122) cs.contour(X,Y,Z) cs.set_xlabel('x') cs.set_ylabel('y') cs.set_title('contour') cs.scatter(x_history, y_history, func(np.array(x_history), np.array(y_history)),c='red', marker='.') plt.show()
-
下面是运行结果:文章来源:https://www.toymoban.com/news/detail-854059.html
-
完整代码:文章来源地址https://www.toymoban.com/news/detail-854059.html
# -*- coding: utf-8 -*- # @Time : 2023/8/24 20:09 # @Author :Muzi # @File : gradient_1.py # @Software: PyCharm import numpy as np import matplotlib.pyplot as plt def func(x, y): return x ** 2 + y ** 2 def grad(x, y): return 2 * x, 2 * y # 设置初始点 x_start, y_start = 15, 15 theta = 1e-5 # θ =10**-6 设置阈值 learning_rate = 0.2 # 学习率 # 记录下初始x y值 x_history = [x_start] y_history = [y_start] z_history = [func(x_start, y_start)] # 记录迭代次数 cnt = 0 while True: cnt += 1 # 计算此时梯度 grad_x, grad_y = grad(x_start, y_start) '''计算梯度的范数 即 向量的长度''' grad_num = np.sqrt(grad_x ** 2 + grad_y ** 2) # 梯度下降 即x-grad*learn_rate x_start -= grad_x * learning_rate y_start -= grad_y * learning_rate # 将梯度下降过程写入列表 x_history.append(x_start) y_history.append(y_start) # 判读梯度范数是否小于阈值 if grad_num < theta: print(f"一共迭代了{cnt}次") break else: continue x = np.linspace(-20, 20, 500) y = np.linspace(-20, 20, 500) # 绘制网格线 X, Y = np.meshgrid(x, y) Z = func(X, Y) fig = plt.figure(figsize=(8, 8)) ax = fig.add_subplot(121, projection='3d') ax.scatter(x_history, y_history, func(np.array(x_history), np.array(y_history)), c='red', marker='o', alpha=1) ax.plot_surface(X, Y, Z, cmap='viridis', alpha=0.8) # alpha设置透明度 ax.set_title("3D Plot of f(x, y) = x^2/5 + y^2/3") ax.set_xlabel("x") ax.set_ylabel("y") # 记录迭代的痕迹 scatter cs = fig.add_subplot(122) cs.contour(X, Y, Z) cs.set_xlabel('x') cs.set_ylabel('y') cs.set_title('contour') cs.scatter(x_history, y_history, func(np.array(x_history), np.array(y_history)), c='red', marker='.') plt.show()
到了这里,关于python实现梯度下降算法,并绘制等高线和3d图显示下降过程的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!