梯度下降
目录
1.1概念
学习率控制大小
通过梯度指引方向:
当导函数>0时,则函数单调递增
当导函数<0时,则函数单调递减
当导函数==0时,极值点
在右半部份,w向左移动,w变小
在左半部份,w向右移动,w变大
1.2一维梯度下降
# 给定一个初始值(是什么不重要),然后根据梯度来对该值(x)进行调整。使得
# x的值令y值最小。
# 定义原函数
def f(x):
return x ** 2 - 2 * x + 1
# 定义导函数(梯度函数)
def gradient(x):
return 2 * x - 2
# 定义一个列表,来保存x的更新轨迹。
x_list = []
# 定义一个列表,来保存y的更新轨迹。
y_list = []
# 定义学习率。
eta = 0.1
# 定义x的初始值。
x = 10
# 进行循环迭代,在循环中,不管根据x的梯度值更新x,使得更新后的x值,令y值更小。
for i in range(10):
# 将x与y值加入到轨迹列表中。
x_list.append(x)
y_list.append(f(x))
# 对自变量x进行调整。(根据梯度)
x = x - eta * gradient(x)
# display(x_list)
# display(y_list)
# 绘制图像
x = np.arange(-9, 11, 0.1)
y = f(x)
plt.plot(x, y)
# 画出x,y点的移动轨迹。
plt.plot(x_list, y_list, "ro--")
# title等方法中,也同样支持latex语法。
plt.title("函数$y=x^{2} -2x + 1$")
1.3二维梯度下降
from mpl_toolkits.mplot3d import Axes3D
# 定义原函数
def f(x1, x2):
return 0.2 * (x1 + x2) ** 2 - 0.3 * x1 * x2 + 0.4
# 定义梯度函数(导函数)
def gradient_x1(x1, x2):
return 0.4 * (x1 + x2) - 0.3 * x2
def gradient_x2(x1, x2):
return 0.4 * (x1 + x2) - 0.3 * x1
# 定义学习率
eta = 1.5
# 定义x1,x2与y的轨迹列表。
x1_list = []
x2_list = []
y_list = []
# 定义初始位置
x1, x2 = 4.5, 4.5
for i in range(50):
# 轨迹列表加入相应的轨迹
x1_list.append(x1)
x2_list.append(x2)
y_list.append(f(x1, x2))
x1 = x1 - eta * gradient_x1(x1, x2)
x2 = x2 - eta * gradient_x2(x1, x2)
# display(x1_list)
# display(x2_list)
# display(y_list)
X1 = np.arange(-5, 5, 0.1)
X2 = np.arange(-5, 5, 0.1)
# 网状结构。
# X1看做一个列向量,会沿着行进行扩展。扩展的行数与X2元素的个数相同。
# X2看做一个行向量,会沿着列进行扩展。扩展的列数与X1元素的个数相同。
# 返回扩展之后的X1与X2。(经过扩展之后,X1与X2的形状是相同的。)
# meshgrid扩展的目的:经过扩展之后,我们就可以获得任意X1与X2中元素的组合。(例如Ptyhon zip)
X1, X2 = np.meshgrid(X1, X2)
Y = f(X1, X2)
fig = plt.figure()
# 创建3D绘图对象,在参数(figure)上进行绘图。
ax = Axes3D(fig)
# 绘制曲面图。
ax.plot_surface(X1, X2, Y, rstride=5, cstride=5, cmap="rainbow")
ax.plot(x1_list, x2_list, y_list, "bo--")