各位帅哥美女大家好!!!
俗话讲温故而知新,在AI技术日新月异的今天,很荣幸为大家分享一些AI相关的内容。也欢迎各位积极留言讨论。
梯度下降(Gradient Descent)是机器学习和深度学习中最常用的优化算法之一,通过迭代地调整参数来减少误差,梯度下降帮助模型从初始状态逐渐学习到数据中的复杂模式。在最近一年的研究论文中,梯度下降及其各种变体继续扮演着重要的角色,特别是在机器学习和深度学习领域。由于数据量和计算复杂度的不断增加,梯度下降算法,及其改进版本,得到了广泛的研究和应用。以下是从arxiv搜索关键字为“Gradient Descent 2024”得到的部分截图。
希望这篇文章能够帮助大家理解梯度下降的概念与思想,尽量以直观的形式来让大家了解梯度下降算法的过程和工作原理。我们开始吧!
1. 梯度是什么,为啥要下降?
梯度下降的核心思想是:在当前位置计算损失函数的梯度(即方向和大小),然后沿着梯度的反方向进行参数更新,以期望在迭代过程中损失函数的值逐渐减小。
想象你作为一个盲人,正在一座山上,你的目标是以最快的方式下山到达山谷。可很遗憾,你的眼睛并看不见,手中只有一根拐杖来探测前方的道路,所以你需要一步步地找到下山的最佳路线。在这种情况下,梯度下降就像是你每一步都用拐杖来感受前方的坡度,然后决定往哪个方向迈步,以便每一步都尽可能地朝山下走。
梯度下降主要用于解决那些可以通过迭代优化参数来最小化或最大化目标函数的问题。这些问题广泛存在于各类机器学习任务中,包括但不限于:
-
线性回归:
在房价预测模型中,可以使用线性回归来估计房价与房屋特征(如面积、房间数、位置等)之间的关系。通过梯度下降算法,可以找到最佳的权重参数,使得模型预测的价格与实际价格之间的均方误差最小。
-
分类任务:
在电子邮件分类(垃圾邮件与非垃圾邮件)中,逻辑回归常用来预测一个电子邮件是否为垃圾邮件。通过梯度下降调整模型参数,优化分类的准确性。
-
图像识别:
在图像识别任务中,如使用卷积神经网络(CNN)来识别和分类数字图像(例如,MNIST数据集中的手写数字)。梯度下降用于训练网络,通过最小化实际输出和预期输出之间的差异来不断调整网络中的权重和偏置。
-
深度学习:
在自然语言处理(NLP)中,比如使用BERT或Transformer模型进行文本情感分析。这些模型通常包含数百万甚至数十亿的参数,梯度下降算法用于在大量文本数据上训练这些模型,以优化它们的表现。
2. 数学基础先搞清
梯度下降的数学基础主要涉及计算和应用函数的梯度来寻找函数的最小值点。这个过程可以从以下几个核心概念理解:
-
梯度
梯度是一个向量,指明了多变量函数在给定点上增长最快的方向。在数学上,对于一个函数 𝑓(𝑥1,𝑥2,...,𝑥𝑛),其梯度由该函数对每个变量的偏导数组成,表示为:
-
梯度方向
梯度指示函数值增加最快的方向;相对应地,梯度的反方向则是函数值减少最快的方向。
-
参数更新规则
参数按以下规则更新,以实现函数值的减小:
其中:
3. 举个简单的例子
假设我们有一些二维数据点(𝑥𝑖,𝑦𝑖),这些点大致分布在一条二次曲线上。我们的目标是找到这条曲线的最佳拟合,使得数据点到直线的距离最小。我们可以用一个二次函数来拟合这些数据点:
,
是模型预测的输出,𝑤1,𝑤1和𝑤0分别是二次函数的三个系数。
我们希望最小化预测值与真实值之间的误差,可以使用均方误差(MSE)作为损失函数
对于每个参数 𝑤0,𝑤1,𝑤2,我们分别计算损失函数的偏导数:
假设我们有以下数据点:(1,1),(2,4),(3,9),(4,16),(5,25)。这些点显然分布在一条二次曲线上。
初始化𝑤0=0,𝑤1=0,𝑤2=0,选择学习率𝛼=0.001
以下为代码实现:
import numpy as np
x_values = np.array([1, 2, 3, 4, 5])
y_values = np.array([1, 4, 9, 16, 25])
N = 5
w0, w1, w2 = 0, 0, 0
alpha = 0.001
iterations = 20
for _ in range(iterations):
# 计算预测值
y_pred = w2 * x_values**2 + w1 * x_values + w0
# 计算偏导
dL_dw0 = (2/N) * np.sum(y_pred - y_values)
dL_dw1 = (2/N) * np.sum((y_pred - y_values) * x_values)
dL_dw2 = (2/N) * np.sum((y_pred - y_values) * x_values**2)
# 更新参数
w0 -= alpha * dL_dw0
w1 -= alpha * dL_dw1
w2 -= alpha * dL_dw2
loss = np.mean((y_pred - y_values) ** 2)
print(f'Iteration {_+1}: w0={w0}, w1={w1}, w2={w2}, Loss={loss}')
print(f'Final Parameters: w0={w0}, w1={w1}, w2={w2}')
第一次迭代:
更新参数:
通过多次迭代,𝑤0,𝑤1和𝑤2会逐渐接近真实的最优值。
round
|
𝑤0
|
𝑤1
|
𝑤2
|
1
|
0.011
|
0.042
|
0.154
|
2
|
0.022
|
0.090
|
0.392
|
3
|
0.035
|
0.143
|
0.621
|
...
|
...
|
...
|
...
|
10
|
0.051
|
0.214
|
0.945
|
...
|
...
|
...
|
...
|
100
|
0.026
|
0.181
|
0.957
|