深度学习基础 - 梯度下降
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步
通常在线性回归的情况是这样
我们用
y
y
y表示训练样本里面的标注,也就是实际值也就是正确答案我们把它当作真实值,用带戴帽子的
y
^
\hat{y}
y^ 的表示模型计算的出来的预测值。我们当然希望模型计算出来的和越接近越好。
y
y
y和
y
^
\hat{y}
y^的接近程度如何表达呢?也就是单个样本的误差e如何表示?
e
=
1
2
(
y
−
y
^
)
2
e=\frac{1}{2}(y-\hat{y})^2
e=21(y−y^)2
多个2好计算
训练数据中所有样本的误差的和用大写的E来表示
计算如下
E
=
e
(
1
)
+
e
(
2
)
+
e
(
3
)
+
.
.
.
+
e
(
n
)
E=e^{(1)}+e^{(2)}+e^{(3)}+...+e^{(n)}
E=e(1)+e(2)+e(3)+...+e(n)
整个成常用的符号如下
E
=
e
(
1
)
+
e
(
2
)
+
e
(
3
)
+
.
.
.
+
e
(
n
)
=
∑
i
=
1
n
e
(
i
)
=
1
2
∑
i
=
1
n
(
y
(
i
)
−
y
^
(
i
)
)
2
\begin{aligned} E&=e^{(1)}+e^{(2)}+e^{(3)}+...+e^{(n)} \\ &=\sum_{i=1}^{n}e^{(i)} \\ &=\frac{1}{2}\sum_{i=1}^{n}(y^{(i)}-\hat{y}^{(i)})^2 \end{aligned}
E=e(1)+e(2)+e(3)+...+e(n)=i=1∑ne(i)=21i=1∑n(y(i)−y^(i))2
术语描述是MSE(mean square error)均方差损失函数
所有标记数据的 模型预测结果和真实值的差值的平方 的均值。
如果放到我们的代码里,式子就变成下面的样子
θ
n
e
w
=
θ
o
l
d
−
η
∇
E
(
θ
)
\mathrm{\theta}_{new}=\mathrm{\theta}_{old}-\eta\nabla{E(\mathrm{\theta})}
θnew=θold−η∇E(θ)
为你准备了反向传播在梯度下降中的应用。这里的E,在反向传播这里变成了L,字符换了下。
您可能还想知道
梯度下降法中负梯度方向是最速下降方向的原因