线性回归的前向传播、反向传播与数学求解详解

目录


前言

书接上文

机器学习中的距离度量与优化方法:从曼哈顿距离到梯度下降-CSDN博客文章浏览阅读579次,点赞16次,收藏4次。本文涵盖机器学习中的关键距离度量(曼哈顿、切比雪夫、余弦等)与优化技术,包括数学公式、Python代码实现及适用场景分析;详细讲解交叉验证方法(HoldOut与K折)的流程与意义;深入剖析前向传播、损失函数(如均方差)及梯度下降的数学基础(导数、偏导数、链式法则),并通过案例展示直线拟合中的误差计算与模型优化过程,为算法实践提供全面参考。 https://blog.csdn.net/qq_58364361/article/details/147238597?spm=1011.2415.3001.10575&sharefrom=mp_manage_link


 一、前向传播代码

# 导入绘图库 matplotlib.pyplot,便于绘制图形
import matplotlib.pyplot as plt
# 导入 numpy 库,用于数值计算和数组操作
import numpy as np

# 定义一个二维数据列表,包含多个点的(x, y)坐标
data = [[0.8, 1.0], [1.7, 0.9], [2.7, 2.4], [3.2, 2.9], [3.7, 2.8], [4.2, 3.8], [4.2, 2.7]]
# 将列表转换为 numpy 数组,方便切片和运算
data1 = np.array(data)
# 取出所有数据点的第1列作为自变量 x
x = data1[:, 0]
# 取出所有数据点的第2列作为因变量 y
y = data1[:, 1]

# 初始化线性模型参数,权重 w(斜率)设为0
w = 0.7
# 初始化线性模型参数,偏置 b 设为0
b = 0
# 根据当前参数计算预测值 z,即线性模型 y = wx + b
z = w * x + b
# 计算预测误差 e,即预测值 z 与真实值 y 的差
e = z - y
# 计算均方误差 eb,表示预测整体误差的大小
eb = np.mean(e ** 2)

# 创建一个图形窗口,尺寸为8x6英寸
fig = plt.figure(figsize=(8, 6))
# 在图形中添加第1个子图,位置为1行2列的第1个
ax1 = fig.add_subplot(121)
# 添加第2个子图,位置为1行2列的第2个
ax2 = fig.add_subplot(122)

# 计算直线在x=0和x=7时的y坐标,用于绘制回归线
y_low = w * 0 + b
y_high = w * 7 + b
# 在左侧子图绘制回归直线,红色,线宽为2
ax1.plot([0, 7], [y_low, y_high], 'r-', lw=2)

# 设置左侧坐标轴的x范围为0到7
ax1.set_xlim(0, 7)
# 设置左侧坐标轴的y范围为0到15
ax1.set_ylim(0, 15)
# 绘制原始数据点,蓝色圆点,大小为10
ax1.scatter(x, y, s=10, c='b', marker='o')

# 遍历所有数据点,绘制真实值与预测值之间的虚线连接,绿色,线宽1.3
for x_x, y_x, y_p in zip(x, y, z):
    ax1.plot([x_x, x_x], [y_x, y_p], 'g-', linestyle='--', lw=1.3)

# 为了绘制误差曲线,生成权重值的等差数组,范围从0到4,长度为100
w_more = np.linspace(0, 4, 100)
# 计算每个权重对应的均方误差,用于绘制误差函数曲线
eb_more = [np.mean((w_m * x + b - y) ** 2) for w_m in w_more]
# 在右侧子图绘制均方误差关于w的曲线,绿色实线,线宽为2
ax2.plot(w_more, eb_more, 'g-', lw=2)

# 设置右侧子图x轴范围为0到4
ax2.set_xlim(0, 4)
# 设置右侧子图y轴范围为0到15
ax2.set_ylim(0, 15)

# 在右侧子图上绘制当前w和对应误差eb的点,红色圆点,大小为20,确保点浮在其他元素上层
ax2.scatter(w, eb, s=20, c='r', marker='o', zorder=5)

# 显示绘制好的图形窗口
plt.show()


二、反向传播的学习率与梯度下降

从以下2个方面对反向传播的学习率与梯度下降进行介绍
1.反向传播的学习率与梯度下降理论讲解
2.编程实例与步骤
上面这2方面的内容,让大家,掌握并理解反向传播的学习率与梯度下降。


2.1 反向传播的学习率与梯度下降理论讲解

2.1.1 反向传播的学习率与梯度下降起什么作用?

反向传播的学习率与梯度下降起的作用就是对前向传播中的参数进行更新(改变参数的值(w))。


2.1.2 反向传播的概念

反向传播是在前向传播后进行的,它是对前向传播过程中的参数进行更新的一个过程,通过最小化损失函数来优化模型参数。


2.1.3基础原理讲解

2.1.3.1 案例导入

例子:

池塘里有7只蝌蚪,它们的体积(纵坐标)和时间(横坐标)有关,蝌蚪的体积随时间的变化。

自变量是时间x(以天为单位),因变量是蝌蚪的体积y(以毫升为单位)。

那么是否可以拟合一条线,来预测在未来的某个时间点,蝌蚪的体积可能会是多少。


2.1.4 前向传播与反向传播的区别

前向传播是在参数固定后,向公式中传入参数,进行预测的一个过程。当参数值选择的不恰当时,会导致最后的预测值不符合我们的预期,于是我们就需要重新修改参数值。在前向传播实验中时,我们都是通过手动修改w值来使直线能更好的拟合散点。

反向传播是在前向传播后进行的,它是对参数进行更新的一个过程,反向传播的过程中参数会根据某些规律修改从而改变损失函数的值


2.1.5 损失函数

给出直线公式y=wx+b,令 b=0。在前向传播时,得到均方差损失函数:,根据该表达式,可以发现,损失函数是一个关于w的一元二次方程:


2.1.6 参数初始化

反向传播自己会不断的修改参数,即w,那么刚开始时,需要给w一个初始化的值(这个初始化的值可以是任意的值,不同的初始值可能会获得不同的局部最优值),初始化方式可以有随便给一个数或者让代码随机定一个,后续损失的值会根据优化算法来更新w。


2.1.7 梯度下降的概念

在机器学习中,梯度表示损失函数对于模型参数的偏导数,梯度下降是机器学习中一种常用的优化算法。

它的基本思想是在训练过程中通过不断调整参数,使损失函数(代表模型预测结果与真实结果之间的差距)达到最小值。

为了实现这一目标,梯度下降算法会计算损失函数的梯度(带方向的斜率),然后根据梯度的方向更新权重,使损失函数不断减小。

对于一个模型来说,我们可以计算每一个权重对损失函数的影响程度,然后根据损失函数的梯度来更新这些权重。通过不断重复这一过程,我们就可以找到一组使损失函数最小的权重值,从而训练出一个优秀的模型。

假设你在一个陌生的山地上,你想找到一个谷底,那么肯定是想沿着向下的坡行走,如果想尽快的走到谷底,那么肯定是要沿着最陡峭的坡下山。每走一步,都找到这里位置最陡峭的下坡走下一步,这就是梯度下降。

在这个比喻中,梯度就像是山上的坡度,告诉我们在当前位置上地势变化最快的方向。

为了尽快走向谷底,我们需要沿着最陡峭的坡向下行走,而梯度下降算法正是这样的方法。

每走一步,我们都找到当前位置最陡峭的下坡方向,然后朝着该方向迈进一小步。这样,我们就在梯度的指引下逐步向着谷底走去,直到到达谷底(局部或全局最优点)。

在机器学习中,梯度表示损失函数对于模型参数的偏导数。具体来说,对于每个可训练参数,梯度告诉我们在当前参数值下,沿着每个参数方向变化时,损失函数的变化率。

通过计算损失函数对参数的梯度,梯度下降算法能够根据梯度的信息来调整参数,朝着减少损失的方向更新模型,从而逐步优化模型,使得模型性能更好。

梯度下降算法会根据该斜率的信息来调整参数 w,使得损失函数逐步减小,从而找到使得损失最小化的参数值,优化模型的性能。


2.1.8 优化方法讲解

在损失函数关于w的表达式中,确实存在一个w,使得损失函数的值最小。下面使用三种方案,包括固定值法、斜率法、小固定值*斜率法,展示一下其不同的优化效果。


2.1.8.1 方案1:固定值法

在更新w的时候,采用旧的w减去一个固定的值的方法其公式如下所示:

固定值的弊端有两个:

  1. 当固定值的正负确定后,就意味着w的更新方向确定了,比如w>0时,且固定值为正数时,w的值是不断减小的,w<0时,固定值为负数时,w的值是不断变大的。
  2. 不能够准确的更新到令损失值最小的w值,比如最合适的w值为0.8,现在的w值为1,而固定值为0.5,那么就会跳过0.8,直接变成0.5,并且如果还没迭代完,还会变成0,-0.5,…。

也就是说,想通过该方法更新到最好的w值,要么事先算好,要么碰运气,总之效果很差。


2.1.8.2 方案2:斜率法

在这里它就是损失函数曲线中的w点的切线,斜率还有个很好的特性,那就是当w小于最低点对应的w时,它是负的;当w大于最低点对应的w时,它是正的。

其公式如下所示:

斜率法的弊端:

当损失函数比较陡峭时,斜率值很大,会来回震荡,并且斜率值越来越大,损失函数值也会越来越大,效果也不是很理想。

2.1.8.3 方案3:小固定值*斜率法

斜率有很好的特性,但是斜率值太大了不受控制,那么是不是可以把斜率,也就是梯度的值乘以一下很小的数(小于1)。

其公式如下所示:

式子中的小固定值被称为学习率,通过改变学习率的值能调整w的更新速度,而整个式子就叫做梯度下降(Gradient Descent,GD),是一种优化函数,作用是最小化损失函数。


三、学习率与斜率法组合的反向传播模型代码

# 导入绘图库matplotlib,用于绘制图表
import matplotlib.pyplot as plt
# 导入numpy库,方便数值计算和数组操作
import numpy as np

# 定义二维数据样本列表,每个元素是一个(x, y)点
data = [[0.8, 1.0], [1.7, 0.9], [2.7, 2.4], [3.2, 2.9], [3.7, 2.8], [4.2, 3.8], [4.2, 2.7]]
# 转换为numpy数组,方便切片取值和向量化运算
data1 = np.array(data)
# 提取所有数据的自变量x(第0列)
x = data1[:, 0]
# 提取所有数据的因变量y(第1列)
y = data1[:, 1]


# 定义均方误差损失函数,输入权重w、偏置b、特征x和标签y
def loss_function(w, b, x, y):
    # 计算预测y值(线性回归模型)
    y_pred = w * x + b
    # 计算预测值与实际值的均方误差
    mse = np.mean((y - y_pred) ** 2)
    return mse


# 初始化参数:斜率w和截距b
w = -10  # 起始w值
b = 0  # 起始b值
w_o = w  # 用于迭代更新的当前w值
b_o = b  # 当前b值(本程序未更新b)
# 设置学习率,控制每次梯度下降步长
lr = 0.01
# 设置迭代总次数
epochs = 100

# 创建一行两列的子图布局,用于绘制损失函数曲线和拟合直线
fig, (ax1, ax2) = plt.subplots(1, 2)

# 循环迭代进行梯度下降优化参数
for i in range(1, epochs + 1):
    # 清空两个子图,准备绘制新一轮内容
    ax1.cla()
    ax2.cla()

    # 生成-10到10之间200个w值,用于绘制损失曲线和切线
    w_fw = np.linspace(-10, 10, 200)
    # 计算对应w的所有损失值
    sh_all = [loss_function(w1, b, x, y) for w1 in w_fw]
    # 绘制损失函数曲线,绿色线条
    ax1.plot(w_fw, sh_all, color='g', linewidth=2)

    # 计算当前参数w_o对应的损失值
    sh = loss_function(w_o, b_o, x, y)
    # 在损失曲线上标记当前w位置的损失点,红色圆点
    ax1.plot(w_o, sh, marker='o', markersize=8, color='r')

    # 计算损失函数对w的偏导数,即梯度方向
    xl = -2 * np.mean(x * y) + 2 * w_o * np.mean(x ** 2)
    # 计算当前损失值与梯度的线性切线截距
    xj = sh - w_o * xl
    # 计算在w_fw范围内切线对应的y值
    x_q = w_fw * xl + xj
    # 绘制损失函数切线,红色线条
    ax1.plot(w_fw, x_q, color='r', linewidth=2)

    # 绘制右侧散点图,展示样本点
    ax2.scatter(x, y, color='g')
    # 计算拟合直线在x=0和x=7处的y值
    y_lower = w_o * 0 + b_o
    y_upper = w_o * 7 + b_o
    # 绘制当前拟合直线,红色线条
    ax2.plot([0, 7], [y_lower, y_upper], color='r')

    # 设置损失图x轴和y轴范围,方便观察
    ax1.set_xlim(-10, 10)
    ax1.set_ylim(-800, 800)
    ax1.set_xlabel("w")
    ax1.set_ylabel("e")

    # 设置散点图x轴和y轴范围,及坐标轴标签
    ax2.set_xlim(0, 7)
    ax2.set_ylim(-15, 15)
    ax2.set_xlabel("x axis label")
    ax2.set_ylabel("y axis label")

    # 按学习率和梯度更新w值,实现梯度下降
    w_n = w_o - lr * xl
    w_o = w_n

    # 暂停0.01秒以更新图像,形成动画效果
    plt.pause(0.01)

四、数学的方法实现线性回归

从以下2个方面对数学的方法实现线性回归进行介绍
1.数学的方法实现线性回归算法理论讲解
2.编程实例与步骤
上面这2方面的内容,让大家,掌握并理解数学的方法实现线性回归算法。


4.1 线性回归是什么?

定义:

线性回归是一种用于建立自变量与因变量之间关系的统计方法。

它假设因变量(或响应变量)与一个或多个自变量(或预测变量)之间的关系是线性的。

其主要目标是通过拟合一个线性模型来预测因变量的数值。


4.2 线性回归方程是什么?

公式:

线性回归模型可以表示为:

Y=β_0+β_1X_1+β_2X_2+...+β_nX_n+ε

其中:

Y是因变量

X_1,X_2,...,X_n是自变量

β_0,β_1,...,β_n是模型的系数,表示自变量对因变量的影响。

ε是误差项,表示模型无法解释的随机误差

4.3 散点输入

算法实现需要的数据,一些散点,将它们绘制在一个二维坐标中,其分布如下图所示:

4.4 求w/b数学解

有了散点的坐标后,就可以通过数学的方式来实现线性回归。我们给出直线公式y=wx+b,在之前的实验中,我们得到了其损失函数的表达式:

利用数学的方法寻找损失函数的最小值,也就是求损失函数的最值问题,求函数的最值问题可以转换为对损失函数的各个未知量进行求导的问题,从而得到合适的w和b的值。

首先令损失函数对w求导,并且等于零,计算公式为:

对b求导,并且等于零,计算公式为:

b参数相对比较简单,所以先对b进行求导,根据链式求导法则,求导后使其等于零,得到结果:

对比该式的左右两侧系数,将左右两侧都除以-2,并分开各项,得到结果:

由于b为常数,所以可知:

,得到结果:

左右两侧交换,得到结果:

两侧同时除以n,除以n得到y的均值,得到b的表达式为:

得到了b的表达式,接下来计算w的表达式,即对w进行求导,根据链式求导法则,求导后并使其等于零,得到结果:

对比该式的左右两侧系数,将两侧都除以-2,得到结果:

带入到公式中,得到:

乘进去后整理顺序,并将各项分开,可以得到:

w提出,可以得到w的表达式为:

由于

整理分子分母,得到:

整理后得到w,b的表达式:

#数学方法实现线性回归
#导入包
import numpy as np
import matplotlib.pyplot as plt
#散点输入
data=[[0.8,1.0],
      [1.7,0.9],
      [2.7,2.4],
      [3.2,2.9],
      [3.7,2.8],
      [4.2,3.8],
      [4.2,2.7]]
#转换为Numpy 数组
data=np.array(data)
#提取x_data 和y_data
x_data=data[:,0]
y_data=data[:,1]
w=0
b=0
#2.数据求解w/b
def math_linear_regression_train(x_data, y_data):
    
        #求x_bar y_bar求均值
        x_bar=np.mean(x_data)
        y_bar=np.mean(y_data)
        numerator=0.0
        denominator=0.0
         #计算参数w 的分子、分母
        #zip一个一个拿出输入参数(x_data,y_data)的值
        for x_i,y_i in zip(x_data,y_data):
            numerator=numerator+(x_i-x_bar)*(y_i-y_bar)
            denominator =denominator+(x_i-x_bar)**2
        #计算w值
        if denominator!=0:
            w=numerator/denominator
            #计算b
            b=y_bar-w*x_bar
            return w,b
        else:
            return 0,0
        
w,b=math_linear_regression_train(x_data, y_data)
#画图
plt.figure("show figure")
plt.xlim(0,5)
plt.ylim(0,5)
plt.xlabel('x axis label')
plt.ylabel('x axis label')
plt.scatter(x_data,y_data,marker='.',c='b')
#绘制直线
y_lower=w*0+b
y_upper=w*5+b
plt.plot([0,5],[y_lower,y_upper],color='r',linewidth=3)
plt.show()

总结

        本文通过代码实例和理论讲解,详细介绍了线性回归模型的前向传播过程,包括数据的准备、模型预测及误差计算,并通过绘图展示了预测结果与误差的变化;随后深入解析了反向传播中学习率和梯度下降的原理,阐述了梯度下降算法如何利用损失函数的梯度不断优化模型参数,配合代码演示了梯度下降的动态过程和损失函数的切线变化;最后,文章介绍了线性回归的数学实现方法,推导了参数w和b的解析解,并用代码实现了基于数学公式的线性回归拟合,通过图形直观展示了拟合效果,全面帮助读者理解线性回归模型从理论到实践的完整流程。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

夜松云

请投喂云云喵,谢谢喵!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值