可视化梯度下降
从小学4年级的数学课开始解释线性回归
从线性回归到逻辑回归解决分类问题
梯度下降背后的原理
白话关于熵、信息熵、香农熵的一些事
flyfish
从简单开始
函数是
y
=
(
x
−
5
)
2
+
2
y=(x-5)^2+2
y=(x−5)2+2
红叉表示梯度下降的起点
x
=
0.5050505050505051
x=0.5050505050505051
x=0.5050505050505051
y
=
22.204570962146718
y=22.204570962146718
y=22.204570962146718
x轴代表的是我们待学习的参数θ(theta),y轴代表的是损失函数的值(即Loss值),
曲线y代表的是损失函数。我们的目标是希望损失函数的值最小。可以通过求导数的方式,达到一元二次方程的最小值点,使得导数为0即可。
代码里用theta 来表示 θ \theta θ,用eta 来表示学习率 η \eta η
完成的代码实现
import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(0, 10, 100) #从0到6选取100个点
y = ( x -5) ** 2 + 2 #我们自己定义的损失函数
plt.scatter(x[5], y[5], color='r',marker='x')#我们随机选择的起点
print(x[5], y[5])#0.5050505050505051 22.204570962146718
plt.plot(x, y,color='g')
plt.xlabel('theta', fontsize=10)
plt.ylabel('loss function', fontsize=10)
plt.show()
#定义损失函数
def J(theta):
return (theta-5)**2 + 2
#损失函数的梯度,因为是单一变量,这里可以说是损失函数的导数
def dJ(theta):
return 2 * (theta - 5)
#初始点
theta = x[5]
theta_record = [theta]
#超参数-步长,也叫学习率
eta = 0.1
#在计算机中处理关于0的问题,由于精度或者学习率的设置无法得到导数的结果是0,只能是近似0.
epsilon = 1e-6
while True:
gradient = dJ(theta) #求导数
last_theta = theta #上一个theta的值
theta = theta - eta * gradient #得到一个新的theta
theta_record.append(theta)
if(abs(J(theta) - J(last_theta)) < epsilon):
break #处理0的问题终止循环
plt.plot(x,J(x),color="g")
plt.plot(np.array(theta_record),J(np.array(theta_record)),'-.',color='r',marker='o')
plt.show()
print(len(theta_record)) #38
那么梯度下降算法怎么实现呢?通过上面的代码总结如下:
- 函数1:待优化的函数 f ( x ) f(x) f(x),即代码中的 J ( t h e t a ) J(theta) J(theta),它可以根据给定的输入返回函数值。
- 函数2:待优化函数的导数 g ( x ) g(x) g(x),即代码中的 d J ( t h e t a ) dJ(theta) dJ(theta),它可以根据给定的输入返回函数的导数值。
- 变量x:保存当前优化过程中的参数值,优化开始时该变量将被初始化成某个数值,优化过程中这个变量会不断变化,直到它找到最小值。
- 变量grad:保存变量 x x x点处的梯度值。即代码中的 g r a d i e n t gradient gradient
- 变量step:表示沿着梯度下降方向行进的步长,也被称为学习率,即代码中的 e t a eta eta。
整个程序运行如下,当 x = 5 x=5 x=5时找到了最小值,实际计算 x = 4.998833044392905 x=4.998833044392905 x=4.998833044392905找到了最小值,共找了38步。
为什么学习率是我们要调整的参数呢?
我们把学习率设置成不同的值,看图就能找到原因
当学习率eta = 0.001 ,计算步骤是2824步,你的机器要浪费资源了。
看点多的都连成线了
当学习率eta = 0.9 ,计算步骤是38步
在这篇文章中,以不同的学习率展示梯度下降,这里是以逻辑回归为例,动画展示梯度下降,包括三维图形。
动画实现采用Python的matplotlib和celluloid。内部的实现最多也就是使用numpy,为了理解内部运行原始不使用sklearn库。
从小学4年级的数学课开始解释线性回归
从线性回归到逻辑回归解决分类问题
线性部分是 y = w x + b y=wx+b y=wx+b 的情况
线性部分是
y
=
w
0
x
0
+
w
1
x
1
y=w_0x_0+w_1x_1
y=w0x0+w1x1 的情况
等高线的方式展示
再来一张图看看三维图如何映射到等高线的
代码实现
import matplotlib.pyplot as plt
import numpy as np
fig = plt.figure()
ax = fig.gca(projection='3d')
X = np.arange(-10, 10, 0.1)
Y = np.arange(-10, 10, 0.1)
X, Y = np.meshgrid(X, Y)
Z = (X ** 2 + Y ** 2)
ax.plot_surface(X, Y, Z, rstride=1, cstride=1, alpha=0.3)
# ax.contour(X, Y, Z, zdir='x', offset=-10)
# ax.contour(X, Y, Z, zdir='y', offset=10 )
ax.contour(X, Y, Z, zdir='z', offset=4)
#zdir 三维到二维的投影,zdir = 'z', offset = 4 表示投影到xoy平面上,z = 4
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_zlabel('Z')
plt.show()