2024.01.08 线性回归

2024-03-14 14:10
文章标签 回归 线性 08 2024.01

本文主要是介绍2024.01.08 线性回归,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

2024.01.08 线性回归

因为学习大模型的微调遇到了障碍,所以回头再快速看一遍深度学习的原理。都是一些基础内容。。。

https://zh.d2l.ai/chapter_linear-networks/linear-regression-scratch.html

线性回归原理

线性回归模型的训练过程就是最小化损失函数的过程。

1 线性回归模型

线性假设是指目标(房屋价格)可以表示为特征(面积和房龄)的加权和,如下面的式子:
p r i c e = w a r e a ⋅ a r e a + w a g e ⋅ a g e + b \mathrm{price}=w_{\mathrm{area}}\cdot\mathrm{area}+w_{\mathrm{age}}\cdot\mathrm{age}+b price=wareaarea+wageage+b
其中 w a r e a w_{\mathrm{area}} warea w a g e w_{\mathrm{age}} wage称为权重(weight),权重决定了每个特征对我们预测值的影响。 b b b称为偏置(bias)、偏移量(offset)或截距(intercept)。给定一个数据集,我们的目标是寻找模型的权重 w w w和偏置 b b b, 使得根据模型做出的预测大体符合数据里的真实价格。

而在机器学习领域,我们通常使用的是高维数据集,建模时采用线性代数表示法会比较方便。当我们的输入包含 d d d个特征时,我们将预测结果 y ^ \hat{y} y^(通常使用“尖角”符号表示 y y y的估计值)表示为:
y ^ = w 1 x 1 + … + w d x d + b \hat{y}=w_{1}x_{1}+\ldots+w_{d}x_{d}+b y^=w1x1++wdxd+b
将所有特征放到向量 x ∈ R d \mathbf{x}\in\mathbb{R}^{d} xRd中, 并将所有权重放到向量 w ∈ R d \mathbf{w}\in\mathbb{R}^{d} wRd 中, 我们可以用点积形式来简洁地表达模型:
y ^ = w ⊤ x + b \hat{y}=\mathbf{w}^\top\mathbf{x}+b y^=wx+b
其中向量 x \mathbf{x} x对应于单个数据样本的特征。用符号表示的矩阵 X ∈ R n × d \mathbf{X}\in\mathbb{R}^{n\times d} XRn×d可以很方便地引用我们整个数据集的n个样本。其中, X \mathbf{X} X的每一行是一个样本,每一列是一种特征。

对于特征集合 X \mathbf{X} X,预测值 y ^ ∈ R n \hat{\mathbf{y}}\in\mathbb{R}^{n} y^Rn可以通过矩阵-向量乘法表示为:
y ^ = X w + b \hat{\mathbf{y}}=\mathbf{X}\mathbf{w}+b y^=Xw+b

2 损失函数

损失函数(loss function)能够量化目标的实际值与预测值之间的差距。通常我们会选择非负数作为损失,且数值越小表示损失越小,完美预测时的损失为0。 回归问题中最常用的损失函数是平方误差函数。当样本 i i i的预测值为 y ^ ( i ) \hat{y}^{(i)} y^(i),其相应的真实标签为 y ( i ) y^{(i)} y(i)时, 平方误差可以定义为以下公式:
l ( i ) ( w , b ) = 1 2 ( y ^ ( i ) − y ( i ) ) 2 l^{(i)}(\mathbf{w},b)=\frac{1}{2}\left(\hat{y}^{(i)}-y^{(i)}\right)^2 l(i)(w,b)=21(y^(i)y(i))2
常数 1 2 \frac12 21不会带来本质的差别,但这样在形式上稍微简单一些 (因为当我们对损失函数求导后常数系数为1)。

由于平方误差函数中的二次方项, 估计值 y ^ ( i ) \hat{y}^{(i)} y^(i)和观测值 y ( i ) y^{(i)} y(i)之间较大的差异将导致更大的损失。 为了度量模型在整个数据集上的质量,我们需计算在训练集n个样本上的损失均值(也等价于求和)。
L ( w , b ) = 1 n ∑ i = 1 n l ( i ) ( w , b ) = 1 n ∑ i = 1 n 1 2 ( w ⊤ x ( i ) + b − y ( i ) ) 2 L(\mathbf{w},b)=\frac1n\sum_{i=1}^nl^{(i)}(\mathbf{w},b)=\frac1n\sum_{i=1}^n\frac12\Big(\mathbf{w}^\top\mathbf{x}^{(i)}+b-y^{(i)}\Big)^2 L(w,b)=n1i=1nl(i)(w,b)=n1i=1n21(wx(i)+by(i))2
在训练模型时,我们希望寻找一组参数 ( w ∗ , b ∗ ) \left(\mathbf{w^*}, b^*\right) (w,b), 这组参数能最小化在所有训练样本上的总损失。如下式:
w ∗ , b ∗ = argmin ⁡ w , b L ( w , b ) . \mathbf{w}^{*},b^{*}=\operatorname*{argmin}_{\mathbf{w},b}L(\mathbf{w},b). w,b=w,bargminL(w,b).

3 随机梯度下降

梯度下降最简单的用法是计算损失函数(数据集中所有样本的损失均值) 关于模型参数的导数(在这里也可以称为梯度)。 但实际中的执行可能会非常慢:因为在每一次更新参数之前,我们必须遍历整个数据集。 因此,我们通常会在每次需要计算更新的时候随机抽取一小批样本, 这种变体叫做小批量随机梯度下降(minibatch stochastic gradient descent)。

在每次迭代中,我们首先随机抽样一个小批量 B \mathcal{B} B, 它是由固定数量的训练样本组成的。 然后,我们计算小批量的平均损失关于模型参数的导数(也可以称为梯度)。 最后,我们将梯度乘以一个预先确定的正数 η \eta η,并从当前参数的值中减掉。

我们用下面的数学公式来表示这一更新过程( ∂ \partial 表示偏导数):
( w , b ) ← ( w , b ) − η ∣ B ∣ ∑ i ∈ B ∂ ( w , b ) l ( i ) ( w , b ) (\mathbf{w},b)\leftarrow(\mathbf{w},b)-\frac\eta{|\mathcal{B}|}\sum_{i\in\mathcal{B}}\partial_{(\mathbf{w},b)}l^{(i)}(\mathbf{w},b) (w,b)(w,b)BηiB(w,b)l(i)(w,b)
总结一下,算法的步骤如下: (1)初始化模型参数的值,如随机初始化; (2)从数据集中随机抽取小批量样本且在负梯度的方向上更新参数,并不断迭代这一步骤。 对于平方损失和仿射变换,我们可以明确地写成如下形式:
w ← w − η ∣ B ∣ ∑ i ∈ B ∂ w l ( i ) ( w , b ) = w − η ∣ B ∣ ∑ i ∈ B x ( i ) ( w ⊤ x ( i ) + b − y ( i ) ) , b ← b − η ∣ B ∣ ∑ i ∈ B ∂ b l ( i ) ( w , b ) = b − η ∣ B ∣ ∑ i ∈ B ( w ⊤ x ( i ) + b − y ( i ) ) . \begin{gathered} \mathbf{w}\leftarrow\mathbf{w}-\frac{\eta}{|\mathcal{B}|}\sum_{i\in\mathcal{B}}\partial_{\mathbf{w}}l^{(i)}(\mathbf{w},b)=\mathbf{w}-\frac{\eta}{|\mathcal{B}|}\sum_{i\in\mathcal{B}}\mathbf{x}^{(i)}\left(\mathbf{w}^{\top}\mathbf{x}^{(i)}+b-y^{(i)}\right), \\ \begin{aligned}b\leftarrow b-\frac\eta{|\mathcal{B}|}\sum_{i\in\mathcal{B}}\partial_bl^{(i)}(\mathbf{w},b)=b-\frac\eta{|\mathcal{B}|}\sum_{i\in\mathcal{B}}\left(\mathbf{w}^\top\mathbf{x}^{(i)}+b-y^{(i)}\right).\end{aligned} \end{gathered} wwBηiBwl(i)(w,b)=wBηiBx(i)(wx(i)+by(i)),bbBηiBbl(i)(w,b)=bBηiB(wx(i)+by(i)).
上述公式中的 w \mathbf{w} w x \mathbf{x} x都是向量。 ∣ B ∣ |\mathcal{B}| B表示每个小批量中的样本数,这也称为批量大小(batch size)。 η \eta η表示学习率(learning rate)。批量大小和学习率的值通常是手动预先指定,而不是通过模型训练得到的。 这些可以调整但不在训练过程中更新的参数称为超参数(hyperparameter)。 调参(hyperparameter tuning)是选择超参数的过程。 超参数通常是我们根据训练迭代结果来调整的, 而训练迭代结果是在独立的验证数据集(validation dataset)上评估得到的。

线性回归从零开始实现

1 构造数据集

构造一个y=Xw+b+噪声的数据集

def synthetic_data(w, b, num_examples):  #@save"""生成y=Xw+b+噪声"""X = torch.normal(0, 1, (num_examples, len(w)))y = torch.matmul(X, w) + by += torch.normal(0, 0.01, y.shape)return X, y.reshape((-1, 1))true_w = torch.tensor([2, -3.4])
true_b = 4.2
features, labels = synthetic_data(true_w, true_b, 1000)
print('features:', features[0],'\nlabel:', labels[0])

输出:

features: tensor([-0.7715,  0.4212]) 
label: tensor([1.2321])

2 定义数据集的bach_size

def data_iter(batch_size, features, labels):num_examples = len(features)indices = list(range(num_examples))# 这些样本是随机读取的,没有特定的顺序random.shuffle(indices)for i in range(0, num_examples, batch_size):batch_indices = torch.tensor(indices[i: min(i + batch_size, num_examples)])yield features[batch_indices], labels[batch_indices]
batch_size = 10for X, y in data_iter(batch_size, features, labels):print(X, '\n', y)break

输出:

tensor([[-0.5022,  0.7038],[-0.2006, -1.7286],[-0.1174,  0.8104],[ 1.1591,  2.5481],[-0.8888, -1.1390],[-1.7663,  0.0730],[-0.3518,  0.8524],[ 1.8939, -0.9266],[ 0.6197,  0.0300],[-0.9234, -0.1029]]) tensor([[ 0.8005],[ 9.6945],[ 1.2068],[-2.1388],[ 6.2942],[ 0.4365],[ 0.5955],[11.1636],[ 5.3342],[ 2.7098]])

3 初始化模型参数w和b

w = torch.normal(0, 0.01, size=(2,1), requires_grad=True)
b = torch.zeros(1, requires_grad=True)

4 定义线性回归模型

def linreg(X, w, b):"""线性回归模型"""return torch.matmul(X, w) + b

5 定义损失函数

def squared_loss(y_hat, y):"""均方损失"""return (y_hat - y.reshape(y_hat.shape)) ** 2 / 2

6 定义优化算法

def sgd(params, lr, batch_size):"""小批量随机梯度下降"""with torch.no_grad():for param in params:param -= lr * param.grad / batch_sizeparam.grad.zero_()

7 训练

lr = 0.03
num_epochs = 3
net = linreg
loss = squared_lossfor epoch in range(num_epochs):for X, y in data_iter(batch_size, features, labels):l = loss(net(X, w, b), y)  # X和y的小批量损失# 因为l形状是(batch_size,1),而不是一个标量。l中的所有元素被加到一起,# 并以此计算关于[w,b]的梯度l.sum().backward()sgd([w, b], lr, batch_size)  # 使用参数的梯度更新参数with torch.no_grad():train_l = loss(net(features, w, b), labels)print(f'epoch {epoch + 1}, loss {float(train_l.mean()):f}')

输出:

epoch 1, loss 0.038077
epoch 2, loss 0.000137
epoch 3, loss 0.000047

误差分析:

print(f'w的估计误差: {true_w - w.reshape(true_w.shape)}')
print(f'b的估计误差: {true_b - b}')

输出:

w的估计误差: tensor([0.0002, 0.0004], grad_fn=<SubBackward0>)
b的估计误差: tensor([-0.0002], grad_fn=<RsubBackward1>)

线性回归的简洁实现

1 构造数据集

import numpy as np
import torch
from torch.utils import datadef synthetic_data(w, b, num_examples):"""生成y=Xw+b+噪声"""X = torch.normal(0, 1, (num_examples, len(w)))y = torch.matmul(X, w) + by += torch.normal(0, 0.01, y.shape)return X, y.reshape((-1, 1))true_w = torch.tensor([2, -3.4])
true_b = 4.2
features, labels = synthetic_data(true_w, true_b, 1000)

2 构造dataset迭代器

def load_array(data_arrays, batch_size, is_train=True):"""构造一个PyTorch数据迭代器"""dataset = data.TensorDataset(*data_arrays)return data.DataLoader(dataset, batch_size, shuffle=is_train)batch_size = 10
data_iter = load_array((features, labels), batch_size)

3 定义模型

from torch import nn
net = nn.Sequential(nn.Linear(2,1))

4 初始化参数

net[0].weight.data.normal_(0, 0.01)
net[0].bias.data.fill_(0)

5 定义损失函数

loss = nn.MSELoss()

6 定义优化算法

trainer = torch.optim.SGD(net.parameters(), lr=0.03)

7 训练

num_epochs = 3
for epoch in range(num_epochs):for X, y in data_iter:l = loss(net(X) ,y)trainer.zero_grad()l.backward()trainer.step()l = loss(net(features), labels)print(f'epoch {epoch + 1}, loss {l:f}')

输出

epoch 1, loss 0.000425
epoch 2, loss 0.000099
epoch 3, loss 0.000098
w = net[0].weight.data
print('w的估计误差:', true_w - w.reshape(true_w.shape))
b = net[0].bias.data
print('b的估计误差:', true_b - b)

输出

w的估计误差: tensor([0.0004, 0.0006])
b的估计误差: tensor([-9.5367e-06])

欢迎关注公众号

在这里插入图片描述

这篇关于2024.01.08 线性回归的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/808663

相关文章

【前端学习】AntV G6-08 深入图形与图形分组、自定义节点、节点动画(下)

【课程链接】 AntV G6:深入图形与图形分组、自定义节点、节点动画(下)_哔哩哔哩_bilibili 本章十吾老师讲解了一个复杂的自定义节点中,应该怎样去计算和绘制图形,如何给一个图形制作不间断的动画,以及在鼠标事件之后产生动画。(有点难,需要好好理解) <!DOCTYPE html><html><head><meta charset="UTF-8"><title>06

线性因子模型 - 独立分量分析(ICA)篇

序言 线性因子模型是数据分析与机器学习中的一类重要模型,它们通过引入潜变量( latent variables \text{latent variables} latent variables)来更好地表征数据。其中,独立分量分析( ICA \text{ICA} ICA)作为线性因子模型的一种,以其独特的视角和广泛的应用领域而备受关注。 ICA \text{ICA} ICA旨在将观察到的复杂信号

✨机器学习笔记(二)—— 线性回归、代价函数、梯度下降

1️⃣线性回归(linear regression) f w , b ( x ) = w x + b f_{w,b}(x) = wx + b fw,b​(x)=wx+b 🎈A linear regression model predicting house prices: 如图是机器学习通过监督学习运用线性回归模型来预测房价的例子,当房屋大小为1250 f e e t 2 feet^

Science|癌症中三级淋巴结构的免疫调节作用与治疗潜力|顶刊精析·24-09-08

小罗碎碎念 Science文献精析 今天精析的这一篇综述,于2022-01-07发表于Science,主要讨论了癌症中的三级淋巴结构(Tertiary Lymphoid Structures, TLS)及其在肿瘤免疫反应中的作用。 作者类型作者姓名单位名称(中文)通讯作者介绍第一作者Ton N. Schumacher荷兰癌症研究所通讯作者之一通讯作者Daniela S. Thomm

【高等代数笔记】线性空间(一到四)

3. 线性空间 令 K n : = { ( a 1 , a 2 , . . . , a n ) ∣ a i ∈ K , i = 1 , 2 , . . . , n } \textbf{K}^{n}:=\{(a_{1},a_{2},...,a_{n})|a_{i}\in\textbf{K},i=1,2,...,n\} Kn:={(a1​,a2​,...,an​)∣ai​∈K,i=1,2,...,n

08 增删查功能

划重点: lable 标签keyup:键盘事件标签内添加样式:style使用事件修饰符:preventforEach :遍历 数组indexOf: 可以返回要查询的某个字符串值在整个字符串中首次出现的位置下标findIndex:返回传入一个测试条件(函数)符合条件数组的首个元素的位置splice:向/从数组中添加/删除项目,然后返回被删除后的新的项目数组 黑椒蟹 一对: <!DOCTYPE

2021-08-14 react笔记-1 安装、环境搭建、创建项目

1、环境 1、安装nodejs 2.安装react脚手架工具 //  cnpm install -g create-react-app 全局安装 2、创建项目 create-react-app [项目名称] 3、运行项目 npm strat  //cd到项目文件夹    进入这个页面  代表运行成功  4、打包 npm run build

用Python实现时间序列模型实战——Day 14: 向量自回归模型 (VAR) 与向量误差修正模型 (VECM)

一、学习内容 1. 向量自回归模型 (VAR) 的基本概念与应用 向量自回归模型 (VAR) 是多元时间序列分析中的一种模型,用于捕捉多个变量之间的相互依赖关系。与单变量自回归模型不同,VAR 模型将多个时间序列作为向量输入,同时对这些变量进行回归分析。 VAR 模型的一般形式为: 其中: ​ 是时间  的变量向量。 是常数向量。​ 是每个时间滞后的回归系数矩阵。​ 是误差项向量,假

GUI编程08:画笔paint

本节内容视频链接:10、画笔paint_哔哩哔哩_bilibilihttps://www.bilibili.com/video/BV1DJ411B75F?p=10&vd_source=b5775c3a4ea16a5306db9c7c1c1486b5 package com.yundait.lesson03;import java.awt.*;import java.awt.event.Wind

带头结点的线性链表的基本操作

持续了好久,终于有了这篇博客,链表的操作需要借助图像模型进行反复学习,这里尽可能的整理并记录下自己的思考,以备后面复习,和大家分享。需要说明的是,我们从实际应用角度出发重新定义了线性表。 一. 定义 从上一篇文章可以看到,由于链表在空间的合理利用上和插入、删除时不需要移动等优点,因此在很多场合下,它是线性表的首选存储结构。然而,它也存在某些实现的缺点,如求线性表的长度时不如顺序存储结构的