什么是梯度下降法
这样不方便理解
我们按简单的形式理解一下:
用函数y来拟合这三个点,点到y的距离误差(预测值和目标值的差距)用最小二乘法表示,得到损失函数,单单从误差就可以知道,结果越小越好
带入y,化简得到
,L是关于b的一个二次函数
L越小,说明点和线的距离误差越小,所以图中的极小值点就是最优值,
求L极小值时的b的值:
1.设置自变量的初始值----找一个点
2.计算b位置的梯度----求该点斜率(偏导)
3.计算运动的步长----学习率*梯度
4.沿梯度反方向运动----函数值变大的方向为梯度的正方向,反之减小为反方向
更新参数
这个公式先记着就行
指定一个点,求出斜率,方向为斜率的负方向,乘以一个系数epsilon(学习率),这个系数是要自己设定的.
让b更新,多次迭代(循环操作,不断更新参数b),
这样参数b就不断更新,函数y慢慢契合三个点,使得y能够表达这三个点或者更多
中的参数(权值.权重.模型参数只是叫法不同)w也是同理,这就是梯度下降法的思路.有了一个初步的思路后:
继续学习了解
梯度的概念
梯度是多维微积分中的一个概念,它描述了一个标量函数在各个方向上的最大变化率。对于一个多变量函数 𝑓(𝑥),其中 𝑥x是一个包含所有变量的向量,梯度是一个向量,其每个分量是函数相对于相应变量的偏导数。梯度的数学表达式通常写作∇𝑓(𝑥)或∂𝑓/∂𝑥。
在几何上,梯度指向函数增加最快的方向,而其大小(梯度的模)则表示在该方向上的最大变化率。在优化问题中,梯度被用来找到函数的局部最小值或最大值,因为沿着梯度的反方向(负梯度方向)可以使函数值减小,而沿着梯度方向则会使函数值增大。
在机器学习和深度学习中,梯度下降算法使用梯度来更新模型的参数,以便最小化损失函数,从而改进模型的预测性能。通过迭代地调整参数,梯度下降算法逐步逼近最优解.
学习率的概念
学习率是机器学习和深度学习中的一个重要超参数,它决定了在优化算法中参数更新的步长。在梯度下降算法中,学习率控制着模型权重沿着损失函数梯度的负方向调整的幅度。具体来说,学习率乘以梯度的负值,指导模型参数向减少损失的方向移动。学习率的大小直接影响优化过程的速度和最终模型的性能。如果学习率设置得太高,模型可能会在最优解附近震荡或跳过最优解;如果学习率太低,模型的学习速度会变慢,可能需要更多的迭代次数才能收敛.
要实现梯度下降法的步骤
准备性工作
比如导入库,设置数据集等。
import torch
import numpy as np
# 数据集
x = np.array([0.18, 0.1, 0.16, 0.08, 0.09, 0.11, 0.12, 0.17, 0.15, 0.14, 0.13])
y = np.array([0.18, 0.1, 0.16, 0.08, 0.09, 0.11, 0.12, 0.17, 0.15, 0.14, 0.13])
初始化参数
在梯度下降中,我们需要初始化的就是w和b了,
w=10
b在这里,我们就暂且不考虑。
计算损失函数
在计算损失函数时,也被用来更新损失函数的值
def loss_new(x,y,w):
return 0.5*np.sum((w*x-y)**2)
计算梯度
我们先设置梯度为0
grad=0
接下来,我们就进行梯度的计算,而这部分在后面也被我们用来更新梯度
def grad_new(x,y,w):
return np.mean((x*w-y)*w)
更新参数
根据梯度的方向来更新参数,通常是采用学习率来控制每次更新的步长。学习率越大,每次更新的步长越大,但可能会导致算法不收敛;学习率越小,每次更新的步长越小,但可能会导致算法收敛速度过慢。
在这里,我们用lr来表示学习率
w=w-lr*grad
核心部分--进行迭代
我们需要先定义迭代次数epoches=500
epoches=500
for i in range(epoches):
grad=grad_new(x,y,w)
w=w-lr*grad
loss=loss_new(x,y,w)
print(f"第{i+1}次迭代的梯度为{grad},权值为{w},损失值为{loss}")
完整代码
下面是完整代码:
import torch
import numpy as np
# 数据集
x = np.array([0.18, 0.1, 0.16, 0.08, 0.09, 0.11, 0.12, 0.17, 0.15, 0.14, 0.13])
y = np.array([0.18, 0.1, 0.16, 0.08, 0.09, 0.11, 0.12, 0.17, 0.15, 0.14, 0.13])
# lr为学习率
lr = 0.01
# w为权值
w = 10
# epoches为循环进行的次数
epoches =500
# grad为维度
grad=0
# 进行梯度的更新
def grad_new(x,y,w):
return np.mean((x*w-y)*w)
# 进行损失值的更新
def loss_new(x,y,w):
return 0.5*np.sum((w*x-y)**2)
for i in range(epoches):
grad=grad_new(x,y,w)
w=w-lr*grad
loss=loss_new(x,y,w)
print(f"第{i+1}次迭代的梯度为{grad},权值为{w},损失值为{loss}")