动手学深度学习|线性神经网络:线性回归的实现

前言

线性回归模型是在目前的机器学习领域入门级的必修课,其基本框架简单易上手,基本逻辑清晰好理解,本文主要来进行介绍线性回归的基本思想与实现过程。

1.线性回归的基本思想

线性回归可以追溯到19世纪初, 它在回归的各种标准工具中最简单而且最流行。线性回归基于几个简单的假设:首先,假设自变量x和因变量y之间的关系是线性的,即y可以表示为x中元素的加权和,这里通常允许包含观测值的一些噪声;其次,我们假设任何噪声都比较正常,如噪声遵循正态分布。

在高维数据之中,我们通常表示模型如下:

其中,权重 偏置 是在模型中需要被进行预测的量。其实简而言之,线性回归的思路就是在寻找x与y之间的关系,确定具体的系数,将之前用于定性分析的"正相关"和"负相关"转为定量描述,探究到底相关程度有多少的一个问题。

基于真实值与预测值之间存在误差,我们需要设计损失函数来比较不同参数预测下的精度问题,本文中设计的误差函数为平方误差函数,表达式如下:

.

误差函数越小,则代表我们预测得到的参数越精准,换而言之,在模型训练过程中,就是为了寻找一组参数,这组参数可以最小化在所有样本上的总损失。

朝着最小化总损失的这个目标,在计算过程中,我们采用小批量随机梯度下降法 进行迭代,以寻找最优参数,算法的步骤如下: (1)初始化模型参数的值,如随机初始化 ; (2)从数据集中随机抽取小批量样本且在负梯度的方向上更新参数,并不断迭代这一步骤。 对于平方损失和仿射变换,我们可以明确地写成如下形式:

.

其中,代表小批量 中包含的样本,计算其数量后用于进行平均,代表学习率,可以简单理解为没有迭代更新所探索的步长。

在实际问题分析中,线性回归问题一般需要考虑噪声,特别的,在正态噪声(高斯噪声)下的线性回归模型便会变为:

.

其中,噪声服从正态分布,在后续 文章中我们将详细推导在高斯噪声的假设下,最小化均方误差等价于对线性模型的极大似然估计

基于上述的简单介绍,我们已经大概了解了线性回归的基本思路,就是在寻找最小化损失函数的道路上,利用小批量梯度随机下降法去寻找自变量与因变量之间的线性关系。

2.线性回归的实现

本小节将按照"生成数据集→读取数据集→初始化模型参数→定义模型→定义损失函数→定义优化算法→训练"的基本逻辑框架进行展开,逐部分拆解线性回归问题的实现。

2.1生成数据集

python 复制代码
# 生成数据集

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) + b
    y += 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)

代码解读

①本数据集中共基于标准正态分布生成了1000组随机样本;

②本次模拟中的权重真值为2与-3.4,偏置真值为4.2;

③本次模拟中的噪声为服从期望为0,方差为0.01的高斯分布的高斯噪声。

2.2读取数据集

python 复制代码
#读取数据集

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]

代码解读

①数据读取过程中采用随机读取,并无特定顺序;

②遍历过程中选择按批次遍历,每一批次中的样本数量提前预设好;

③代码中还运用了"边界保护",以解决样本总数无法被整除问题。

2.3初始化模型参数

python 复制代码
#初始化模型参数

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

代码解读

①模型参数首先进行初始化,相当于寻找一个模型进行迭代的起点;

②此处参数的设置是来自于期望为0,方差为0.01的正态分布,而参数则设置为0。

2.4定义模型

python 复制代码
#定义模型

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

代码解读

采用矩阵-向量乘法构建线性回归模型。

2.5定义损失函数

python 复制代码
#定义损失函数

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

代码解读

采用均方误差函数作为损失函数。

2.6定义优化算法

python 复制代码
#定义优化算法

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

代码解读

采用小批量随机梯度下降法作为优化迭代算法。

2.7训练

python 复制代码
#训练

lr = 0.03
num_epochs = 3
net = linreg
loss = squared_loss

for 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}')

代码解读

①设置学习率与迭代轮次之后便可以开始计算与寻找,不断更新参数后便可以得到最终结果;

②代码中可以自动更新梯度;

③最后输出每一轮次的损失函数的函数值,可以观察得到,函数值在不断变小。

3.小结

经过上述的介绍,本文便完成了对于线性回归的介绍,本专栏系列文章均参考李沐老师的《动手学深度学习(PyTorch版)》,线性回归模型逻辑清晰,是作为开始学习深度学习的入门课程。

相关推荐
hhzz1 小时前
《深度学习框架PyTorch入门与实践》系列:11-实战猫狗大战之可复用的PyTorch项目架构
人工智能·pytorch·深度学习
XLYcmy2 小时前
小红书 算法一面 四
深度学习·llm·sft·强化学习·多模态·grpo·奖励函数
玩三国杀玩的3 小时前
Pytorch-c++-CUDA
c++·pytorch·python·深度学习
l1258654 小时前
# RAG重排序实战:硅基流动bge-reranker-v2-m3在线API vs 本地CrossEncoder,一篇讲透两种方案
数据库·人工智能·python·深度学习·算法·机器学习·langchain
薛定e的猫咪5 小时前
(ICLR2026)MORL‑FB:从无奖励强化学习视角重新审视多目标强化学习
人工智能·深度学习·机器学习
问天_观心5 小时前
零基础在windows环境下的WSL使用llamafactory(一)
人工智能·windows·python·神经网络·语言模型·github·模型蒸馏
Zach_菠萝侠5 小时前
【DeepSeek Harness 研究】进化方向1:动态路由 思考、设计与实现
人工智能·深度学习·deepseek
m0_749690235 小时前
【寻迹校园 HarmonyOS NEXT 实战 01】从校园痛点到可上架 MVP:失物招领应用产品设计
人工智能·深度学习·移动开发·harmonyos·arkts·arkui·产品设计
薛定e的猫咪6 小时前
(ICLR2025) C‑MORL :基于约束优化高效挖掘 MORL 帕累托前沿
人工智能·深度学习·算法
手写码匠7 小时前
华为云Flexus+DeepSeek征文|Dify 多 Agent 故障演练实战:用混沌工程主动“搞破坏“,让智能体系统越炸越稳
人工智能·深度学习·算法·aigc