1、实验目的和要求
实验目的:1.理解梯度的含义及作用。
- 使用python实现梯度矢量显示。
- 使用python的3D绘图绘制梯度矢量显示的结果。
实验要求:
书写提交实验报告
2、实验环境
Python3.9
Pycharm2022
Window10
3、实验内容与过程
实验内容:
使用gradient_descent()函数求出梯度矢量,绘制出二维梯度走向分析图和使用python的Axes3D类绘制求函数f=x^3+y^3的梯度矢量的3D显示图。
# coding: utf-8
# cf.http://d.hatena.ne.jp/white_wheels/20100327/p3
import numpy as np
import matplotlib.pylab as plt
from mpl_toolkits.mplot3d import Axes3D
# 梯度
# 梯度下降法求f=x0^2+x1^2的最小值
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 numerical_gradient(f, X):
if X.ndim == 1:
return _numerical_gradient_no_batch(f, X)
else:
grad = np.zeros_like(X)
for idx, x in enumerate(X):
grad[idx] = _numerical_gradient_no_batch(f, x)
return grad
def function_2(x):
if x.ndim == 1:
return np.sum(1*x ** 3)
else:
return np.sum(1*x **3 , axis=1)
def f(x,y):
return x ** 3 + y ** 3 # 计算函数式
if __name__ == '__main__':
x0 = np.arange(-2, 2.5, 0.25)
x1 = np.arange(-2, 2.5, 0.25)
X, Y = np.meshgrid(x0, x1)
X = X.flatten()#返回一维数组
Y = Y.flatten()
grad = numerical_gradient(function_2, np.array([X, Y]))
#print(grad)
plt.figure()
#绘制量场图
plt.quiver(X, Y, -grad[0], -grad[1], angles="xy", color="#666666") # ,headwidth=10,scale=40,color="#444444")
plt.xlim([-2, 2])
plt.ylim([-2, 2])
plt.xlabel('x0')
plt.ylabel('x1')
plt.grid()#绘制网格线
plt.legend()
#动态绘制可重新
plt.draw()
plt.show()
fig = plt.figure()
ax = Axes3D(fig)
# 生成数据
x = np.arange(-2, 2, 0.3)
y = np.arange(-2, 2, 0.3)
x, y = np.meshgrid(x, y) # 初始散点数据处理成xy网格数据
z=f(x,y)
# 绘制函数图像
ax.set_xlabel('x0') # x轴
ax.set_ylabel('x1') # y轴
ax.set_zlabel('z') # f轴
ax.set_xlim(-2.5, 2.5)
ax.set_ylim(-2.5, 2.5)
ax.set_zlim(-15, 20)
# 标题名称、位置:0左下,1右上
plt.rcParams['font.sans-serif'] = ['Microsoft YaHei'] # 汉显
ax.text2D(0.3, 0.95, "函数图形", transform=ax.transAxes)
ax.plot_surface(x, y, z)
plt.show()