梯度下降原理与实现

梯度下降原理与实现

学习新的知识,我往往喜欢由点及面梳理其发展脉络,这有助于我构建一个知识体系,并不断向其中添加细节。

(一)Why choose梯度下降?

梯度下降示意图

既然深度学习本质是数学方程,很容易想到的一种方式就是凸优化,比如二次函数寻找极值点的过程。

在基于梯度的下降之前,也有过基于坐标的优化,形式上就是暴力得迭代所有可能的值。

得益于反向传播,基于梯度下降的优化才成为可能。依据梯度确定参数优化的方向,显然,相比暴力法时间复杂度更低。

(二)梯度下降理论

数学公式

θ:=θηL(θ)θ:=θ−η⋅∇L(θ)

其中ηη是学习率,θθ为待更新的参数,LL为损失函数,L(θ)∇L(θ)为多维空间中函数上升最快的方向。

推导过程

推导过程

这里直接放的李沐老师课程中的推导,有兴趣可以看看。

(三)梯度下降实现

示例代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
x_data = [1.0, 2.0, 3.0]
y_data = [2.0, 4.0, 6.0]
w = 1.0

# 模拟前向传播
def forward(x):
return x * w

# 模拟损失函数
def cost(xs, ys):
cost = 0
for x, y in zip(xs, ys):
y_pred = forward(x)
cost += (y_pred - y) ** 2
return cost / len(xs)

# 模拟自动求导
def gradient(xs, ys):
grad = 0
for x, y in zip(xs, ys):
grad += 2 * x * (x * w - y)
return grad / len(xs)

# 模拟训练过程
print('Predict (before training)', 4, forward(4))
for epoch in range(100):
cost_val = cost(x_data, y_data)
grad_val = gradient(x_data, y_data)
w -= 0.01 * grad_val
print('Epoch:', epoch, 'w=', w, 'loss=', cost_val)
print('Predict (after training)', 4, forward(4))

(四)常用梯度下降

接进行梯度下降,由于张量的高阶特性,往往会使神经网络收敛在鞍点或者说局部最优(因为一个维度上的最优点不一定是另一个维度的最优点),而非最好的结果。因此如何跳出局部最优,如何找到全局最优一直是各类梯度下降算法研究的核心。

SGD

核心就是使用随机的值进行迭代。后期的一些SGD变体,也通过添加动量等方式加快收敛速度和跳出鞍点。

pytorch中关于SGD的实现,torch.optim.SGD

Adam

Adam相较于SGD,核心就是为每个超参数添加了自适应学习率,快速收敛且无需过多调参

pytorch中关于Adam的实现,torch.optim.Adam


梯度下降原理与实现
https://mrkeanu-v.github.io/2023/11/20/梯度下降算法原理与实现/
作者
MrKeanu
发布于
2023年11月20日
许可协议