python pytorch 超详细线性回归原理解析加代码实现-小白入门级

python 线性回归

答应老师做的一个系列教程,也是头一次花这吗大精力去写一篇基础的文档,里面虽然有不少的公式,但只要能顺着看下来会发现都是非常基础的公式都是特别简单的。

文章目录

  • python 线性回归
      • 计算回归任务的损失
      • 梯度下降的原理
      • 模型参数的更新过程
      • python基础库实现

学习目标:

  • 了解深度学学习的结构基本过程和原理

模型(函数): python pytorch 超详细线性回归原理解析加代码实现-小白入门级

数据集:

NO. x y
0 1 3
1 2 5
2 3 7
3 4 9

一个训练样本: 一组python pytorch 超详细线性回归原理解析加代码实现-小白入门级 例:第0组训练样本python pytorch 超详细线性回归原理解析加代码实现-小白入门级

x为输入数据,y为预测标签/目标值/希望被拟合的值

任务:寻找合适的python pytorch 超详细线性回归原理解析加代码实现-小白入门级python pytorch 超详细线性回归原理解析加代码实现-小白入门级使得python pytorch 超详细线性回归原理解析加代码实现-小白入门级可以拟合上表中的数据

  • 怎么具体描述拟合?
  • 就是让所有训练样本中每个训练的样本的python pytorch 超详细线性回归原理解析加代码实现-小白入门级值经过模型(函数)之后的输出python pytorch 超详细线性回归原理解析加代码实现-小白入门级更接近其对应的python pytorch 超详细线性回归原理解析加代码实现-小白入门级看距离的变化,距离小证明拟合的效果越好,距离越大证明拟合的越差,在这个任务里我们选择用两个数据差的平方和也就是欧式距离来作为衡量指标,也被我们称为损失,那计算距离的函数也就被称作损失函数.

计算回归任务的损失

python pytorch 超详细线性回归原理解析加代码实现-小白入门级,python pytorch 超详细线性回归原理解析加代码实现-小白入门级已知的情况下,模型(函数)可表示为
python pytorch 超详细线性回归原理解析加代码实现-小白入门级
定义一个训练样本损失的计算函数
python pytorch 超详细线性回归原理解析加代码实现-小白入门级
如果输入的数据为python pytorch 超详细线性回归原理解析加代码实现-小白入门级,其对应的目标值为python pytorch 超详细线性回归原理解析加代码实现-小白入门级则经过模型之后的损失可表示为:
python pytorch 超详细线性回归原理解析加代码实现-小白入门级
我们选择用数据集中的前三组数据来作为训练数据,为了让模型能更好的拟合所有的数据,所以希望的是所有训练样本损失变小,我们的总体损失函数python pytorch 超详细线性回归原理解析加代码实现-小白入门级可表示为

python pytorch 超详细线性回归原理解析加代码实现-小白入门级
即:
python pytorch 超详细线性回归原理解析加代码实现-小白入门级

在输入数据和模型参数python pytorch 超详细线性回归原理解析加代码实现-小白入门级已知的情况下,模型的总体损失是一个固定值

接下来转换思路,现在训练样本python pytorch 超详细线性回归原理解析加代码实现-小白入门级已知,我们的目的是求python pytorch 超详细线性回归原理解析加代码实现-小白入门级使总体损失最小,则我们将python pytorch 超详细线性回归原理解析加代码实现-小白入门级作为自变量,构建一个随着python pytorch 超详细线性回归原理解析加代码实现-小白入门级变化的而变化的损失函数,然后去搜索使这个函数值最小的python pytorch 超详细线性回归原理解析加代码实现-小白入门级的值.

python pytorch 超详细线性回归原理解析加代码实现-小白入门级已知的情况下,模型(函数)表示为
python pytorch 超详细线性回归原理解析加代码实现-小白入门级
则重新定义一个训练样本的损失计算函数
python pytorch 超详细线性回归原理解析加代码实现-小白入门级
则总体损失函数为:
python pytorch 超详细线性回归原理解析加代码实现-小白入门级
将损失函数展开为:
python pytorch 超详细线性回归原理解析加代码实现-小白入门级
python pytorch 超详细线性回归原理解析加代码实现-小白入门级替换
python pytorch 超详细线性回归原理解析加代码实现-小白入门级
python pytorch 超详细线性回归原理解析加代码实现-小白入门级替换
python pytorch 超详细线性回归原理解析加代码实现-小白入门级

梯度下降的原理

到这该思考怎么去搜索一组python pytorch 超详细线性回归原理解析加代码实现-小白入门级,为了理解的透彻我们举几个例子

先从一个最简单的问题上思考,已知一个有最小值点的函数python pytorch 超详细线性回归原理解析加代码实现-小白入门级,和一个初始值python pytorch 超详细线性回归原理解析加代码实现-小白入门级,则python pytorch 超详细线性回归原理解析加代码实现-小白入门级朝着哪个方向移动会使函数值更接近最小值点.

挑一个最简单的函数
python pytorch 超详细线性回归原理解析加代码实现-小白入门级
设置初始点为
python pytorch 超详细线性回归原理解析加代码实现-小白入门级
为了走向最小值点,我们的策略就是一直将python pytorch 超详细线性回归原理解析加代码实现-小白入门级往使函数值变小的方向一点点移动,那往哪个方向移动会使用使函数值见小呢根据简单的数学知识我们知道**如果python pytorch 超详细线性回归原理解析加代码实现-小白入门级朝着梯度(导数)的方向移动则函数值会增大,所以让python pytorch 超详细线性回归原理解析加代码实现-小白入门级朝着负梯度方向移动则函数值就会变小.因此先求在python pytorch 超详细线性回归原理解析加代码实现-小白入门级处的梯度(导数)
python pytorch 超详细线性回归原理解析加代码实现-小白入门级
python pytorch 超详细线性回归原理解析加代码实现-小白入门级 因为在python pytorch 超详细线性回归原理解析加代码实现-小白入门级点处的导数python pytorch 超详细线性回归原理解析加代码实现-小白入门级大于0梯度方向朝着x轴的正轴方向,所以python pytorch 超详细线性回归原理解析加代码实现-小白入门级如果向着正半轴移动则函数值会增大,python pytorch 超详细线性回归原理解析加代码实现-小白入门级向负半轴移动函数值会减小,移动多少就由负梯度乘以一个步长来决定,通过让步长乘以负梯度的方式可以调节变量实际移动距离让python pytorch 超详细线性回归原理解析加代码实现-小白入门级点在接近最小值点也就是导数为0的点时移动的距离变小,在导数大的地方移动加快,提高收敛速度,假设步长为python pytorch 超详细线性回归原理解析加代码实现-小白入门级python pytorch 超详细线性回归原理解析加代码实现-小白入门级python pytorch 超详细线性回归原理解析加代码实现-小白入门级点开始向右侧移动python pytorch 超详细线性回归原理解析加代码实现-小白入门级,我们将这次移动之后的位置记为python pytorch 超详细线性回归原理解析加代码实现-小白入门级,则python pytorch 超详细线性回归原理解析加代码实现-小白入门级 如我们所愿函数值减小了,同理求python pytorch 超详细线性回归原理解析加代码实现-小白入门级,朝着python pytorch 超详细线性回归原理解析加代码实现-小白入门级的反向再继续更新python pytorch 超详细线性回归原理解析加代码实现-小白入门级的值,最终python pytorch 超详细线性回归原理解析加代码实现-小白入门级的值会落在最小值的附近,通过这种方式我们最后搜索到了得到了一个让python pytorch 超详细线性回归原理解析加代码实现-小白入门级贴近或者等于最小值的python pytorch 超详细线性回归原理解析加代码实现-小白入门级值.

那如果有两个自变量呢假设我们要求最小值的函数为,初始点坐标python pytorch 超详细线性回归原理解析加代码实现-小白入门级
python pytorch 超详细线性回归原理解析加代码实现-小白入门级
则在函数的初始值python pytorch 超详细线性回归原理解析加代码实现-小白入门级点的函数值python pytorch 超详细线性回归原理解析加代码实现-小白入门级,要想使三维空间中的点不断的逼近最小值那就是找,输入的二维坐标点的负梯度方向,对于多维函数,求梯度方向就是求每一个自变量的偏导数.

则用python pytorch 超详细线性回归原理解析加代码实现-小白入门级python pytorch 超详细线性回归原理解析加代码实现-小白入门级求偏导
python pytorch 超详细线性回归原理解析加代码实现-小白入门级
则在python pytorch 超详细线性回归原理解析加代码实现-小白入门级 点处的偏导数值为python pytorch 超详细线性回归原理解析加代码实现-小白入门级
python pytorch 超详细线性回归原理解析加代码实现-小白入门级
因此如果python pytorch 超详细线性回归原理解析加代码实现-小白入门级分别朝着导数方向则函数值会增大,为了让函数值减小则同理python pytorch 超详细线性回归原理解析加代码实现-小白入门级同时向这负梯度方向则可以减小,同样设置步长为python pytorch 超详细线性回归原理解析加代码实现-小白入门级,则python pytorch 超详细线性回归原理解析加代码实现-小白入门级 通过这种方式不断的更新python pytorch 超详细线性回归原理解析加代码实现-小白入门级自变量的值,最终就可以搜索到一组python pytorch 超详细线性回归原理解析加代码实现-小白入门级的值使用函数值最小.

到这里其实可以明确一个概念深度学习的本质就是求函数的最小值

模型参数的更新过程

好回到之前回归任务求python pytorch 超详细线性回归原理解析加代码实现-小白入门级是自变量,沿着负梯度方向不断更新python pytorch 超详细线性回归原理解析加代码实现-小白入门级使下面这个函数值最小
python pytorch 超详细线性回归原理解析加代码实现-小白入门级

接下来求函数对python pytorch 超详细线性回归原理解析加代码实现-小白入门级的导数,先将损失函数转换成未完全展开的模式.
python pytorch 超详细线性回归原理解析加代码实现-小白入门级
先观察其中一个python pytorch 超详细线性回归原理解析加代码实现-小白入门级中的分量python pytorch 超详细线性回归原理解析加代码实现-小白入门级
python pytorch 超详细线性回归原理解析加代码实现-小白入门级
然后我们观察这个定义这个分量的原函数
python pytorch 超详细线性回归原理解析加代码实现-小白入门级
要求python pytorch 超详细线性回归原理解析加代码实现-小白入门级python pytorch 超详细线性回归原理解析加代码实现-小白入门级的导数则需要求python pytorch 超详细线性回归原理解析加代码实现-小白入门级python pytorch 超详细线性回归原理解析加代码实现-小白入门级的导数,然后求python pytorch 超详细线性回归原理解析加代码实现-小白入门级python pytorch 超详细线性回归原理解析加代码实现-小白入门级的导数,通过链式求导法则最终得到

python pytorch 超详细线性回归原理解析加代码实现-小白入门级python pytorch 超详细线性回归原理解析加代码实现-小白入门级的导数
python pytorch 超详细线性回归原理解析加代码实现-小白入门级
根据
python pytorch 超详细线性回归原理解析加代码实现-小白入门级
先求
python pytorch 超详细线性回归原理解析加代码实现-小白入门级
然后根据
python pytorch 超详细线性回归原理解析加代码实现-小白入门级
求得

python pytorch 超详细线性回归原理解析加代码实现-小白入门级
所以可以算出
python pytorch 超详细线性回归原理解析加代码实现-小白入门级
同理我们去求python pytorch 超详细线性回归原理解析加代码实现-小白入门级python pytorch 超详细线性回归原理解析加代码实现-小白入门级的导数
python pytorch 超详细线性回归原理解析加代码实现-小白入门级
python pytorch 超详细线性回归原理解析加代码实现-小白入门级python pytorch 超详细线性回归原理解析加代码实现-小白入门级的导数不变,只需要再去求一下python pytorch 超详细线性回归原理解析加代码实现-小白入门级python pytorch 超详细线性回归原理解析加代码实现-小白入门级的导数
python pytorch 超详细线性回归原理解析加代码实现-小白入门级
则最终求出来的python pytorch 超详细线性回归原理解析加代码实现-小白入门级python pytorch 超详细线性回归原理解析加代码实现-小白入门级的导数为
python pytorch 超详细线性回归原理解析加代码实现-小白入门级
最终我们得到了学习参数过程中最重要的梯度计算公式
python pytorch 超详细线性回归原理解析加代码实现-小白入门级
根据总体损失的公式
python pytorch 超详细线性回归原理解析加代码实现-小白入门级
我们也就能算出python pytorch 超详细线性回归原理解析加代码实现-小白入门级python pytorch 超详细线性回归原理解析加代码实现-小白入门级的梯度
python pytorch 超详细线性回归原理解析加代码实现-小白入门级
有了更新公式之后,我们只需要设置一个初始的就可以根据梯度公式不断的更新python pytorch 超详细线性回归原理解析加代码实现-小白入门级我们设置步长python pytorch 超详细线性回归原理解析加代码实现-小白入门级

则可以写出python pytorch 超详细线性回归原理解析加代码实现-小白入门级的更新公式
python pytorch 超详细线性回归原理解析加代码实现-小白入门级
接下来我们模拟一步更新过程

根据一开始的表个我们的训练数据python pytorch 超详细线性回归原理解析加代码实现-小白入门级分别为
python pytorch 超详细线性回归原理解析加代码实现-小白入门级
假设初始值
python pytorch 超详细线性回归原理解析加代码实现-小白入门级
根据下面的这个式子去算一下损失
python pytorch 超详细线性回归原理解析加代码实现-小白入门级

python pytorch 超详细线性回归原理解析加代码实现-小白入门级带入
python pytorch 超详细线性回归原理解析加代码实现-小白入门级

接下来计算损失函数对python pytorch 超详细线性回归原理解析加代码实现-小白入门级的梯度
python pytorch 超详细线性回归原理解析加代码实现-小白入门级

python pytorch 超详细线性回归原理解析加代码实现-小白入门级

接下来使用更新公式对python pytorch 超详细线性回归原理解析加代码实现-小白入门级进行更新
python pytorch 超详细线性回归原理解析加代码实现-小白入门级
接下来我们将新的参数带入进损失函数
python pytorch 超详细线性回归原理解析加代码实现-小白入门级

可喜可贺损失变小了,接下来就是重复上面的步骤设置学习次数,学习到损失几乎不再下降为止.

接下来用python的基础库模拟出这个过程

python基础库实现

先初始化需要用到的变量

# 训练数据
train_data = [1,2,3]
# 训练标签
train_label = [3,5,7]
# 测试数据
test_data = [4]
# 测试标签
test_label = [9]
# 初始化权重
w = 1
b = 0
# 迭代次数/训练次数
iter = 10000
# 设置步长
lamb = 0.01

然后定义模型

# 回归模型
def f(x):
    return w*x + b

定义用到的损失函数

# 计算一个样本的损失函数
def L(data,label):
    return (data-label)**2

# 总体损失函数
def Loss(x,y):
    loss = 0
    k = len(x)
    for i in range(k):
        loss += L(f(x[i]),y[i])
    return loss

定义计算梯度函数

# 计算梯度
def gradient(w,b,x,y):
    dw,db = 0,0
    k = len(x)
    for i in range(k):
        dw += 2*(w*x[i]+b-y[i])*x[i]
        db += 2*(w*x[i]+b-y[i])
    return dw,db

训练部分

# 训练
for i in range(iter):
    dw,db = gradient(w,b,train_data, train_label)
    w = w - lamb*dw
    b = b - lamb*db

最后加上绘图代码最终的完整代码如下

import matplotlib.pyplot as plt
import numpy as np

# 训练数据
train_data = [1,2,3]
# 训练标签
train_label = [3,5,7]
# 测试数据
test_data = [4]
# 测试标签
test_label = [9]
# 初始化权重
w = 1
b = 0
# 迭代次数/训练次数
iter = 1000
# 设置步长
lamb = 0.01

# 回归模型
def f(x):
    return w*x + b
# f = lambda x: w*x + b

# 计算一个样本的损失函数
def L(data,label):
    return (data-label)**2

# 总体损失函数
def Loss(x,y):
    loss = 0
    k = len(x)
    for i in range(k):
        loss += L(f(x[i]),y[i])
    return loss

# 计算梯度
def gradient(w,b,x,y):
    dw,db = 0,0
    k = len(x)
    for i in range(k):
        dw += 2*(w*x[i]+b-y[i])*x[i]
        db += 2*(w*x[i]+b-y[i])
    return dw,db

# 训练
for i in range(iter):
    dw,db = gradient(w,b,train_data, train_label)
    w = w - lamb*dw
    b = b - lamb*db

# 打开网格
plt.grid()
# 绘制训练集点
plt.scatter(train_data,train_label,c='blue')
# 回执测试集点
plt.scatter(test_data,test_label,c='red')

#设置绘图范围
plt.xlim([0,5])
plt.ylim([0,10])

#绘制拟合直线
x = np.linspace(0,5,1000)
y = f(x)
plt.scatter(x,y,c='black',s=1)
plt.show()

#打印学习之后的w,b值
print('w=',w)
print('b=',b)

最终拟合的直线结果如下

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3NKJSXxi-1676598212013)(C:\Users\86176\Desktop\Figure_1.png)]

w= 2.000148389025502
b= 0.9996626768662412

稍微变动一下数据让数据不都在一条线上,看一下最终的拟合结果会是什么样的

# 训练数据
train_data = [1,1.5,3]
# 训练标签
train_label = [3,5,7]
# 测试数据
test_data = [4]
# 测试标签
test_label = [9]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2H4PwPNz-1676598212014)(C:\Users\86176\Desktop\Figure_2.png)]

w= 1.846223184751381
b= 1.6152357121183563

版权声明:本文为博主作者:浩浩的科研笔记原创文章,版权归属原作者,如果侵权,请联系我们删除!

原文链接:https://blog.csdn.net/chrnhao/article/details/129078852

共计人评分,平均

到目前为止还没有投票!成为第一位评论此文章。

(0)
xiaoxingxing的头像xiaoxingxing管理团队
上一篇 2024年1月16日
下一篇 2024年1月16日

相关推荐