基于PyTorch的线性回归的从零开始实现

本文记录了作者学习《动手学深度学习》中线性回归从零开始实现章节的困惑与解答。包括导入库、生成数据集、读取数据、初始化参数、定义模型、损失函数和优化算法、训练等步骤,还对代码中涉及的函数和操作进行了详细解读,如梯度计算、参数更新等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

这篇文章用来记录本人在学习 《动手学深度学习》这本书时对章节( 线性回归的从零开始实现)的一些困惑、理解和解答。

任务

我们将根据带有噪声的线性模型构造一个人造数据集
我们的任务是使用这个有限样本的数据集恢复这个模型的参数

1、导入相应的库函数

import torch
import random
from d2l import torch as d2l

2、生成数据集

def synthetic_data(w, b, num_examples): 
    """生成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)

# 打印features中的第一个二维数据样本及其对应labels中的一维标签值(一个标量)
print('features:',features[0],'\nlabel:',labels[0])

d2l.set_figsize()
d2l.plt.scatter(features[:,(1)].detach().numpy(),labels.detach().numpy(),1)

代码运行结果如下:

features:tensor([1.4632,0.5511])
label:tensor([5.2498])
在这里插入图片描述

代码解读

true_w :用于设置 真实的权重,是一个包含两个元素的一维张量(即向量)。
true_b:用于设置 真实的偏置,是一个标量值。
num_examples:用于设置 样本的数量,是一个标量值。

features:用来接受synthetic_data函数生成的1000个样本的特征数据,每一个样本包含了2个特征。是一个二维张量(即矩阵)。
labels:用来接受synthetic_data函数生成的1000个样本所对应的标签。是一个二维张量(即矩阵)。

X = torch.normal(0, 1, (num_examples, len(w))):生成一个形状为 (num_examples, len(w)) 的二维张量 X,其中的元素是从均值为 0,标准差为 1 的正态分布中采样得到的。
一个样本有多个特征,每一个特征要有一个权重与之对应。
这里 len(w) 的目的是确定 X 的列数,也就是特征的数量。因为在后面的代码中,我们需要用 X 和权重向量 w 进行矩阵乘法,所以 X 的列数必须和 w 的长度相同。这就是为什么我们需要 len(w) 的原因。

y = torch.matmul(X, w) + b:用于计算每个输入样本的预测值。
由于torch.matmul(X, w)是一个矩阵和一个向量进行矩阵-向量乘法运算,得到的结果是一个向量,再把这个向量加上偏置 b ,偏置b这个常数会加到这个向量的每一个元素上,这样得出的预测值y也是一个一维张量(即向量)。

y += torch.normal(0, 0.01, y.shape):给预测值y添加一些噪声,用于模拟实际应用中可能出现的观测误差或者模型误差。
这里的 += 是直接对 y 进行加法操作,所以生成的向量噪声的每一个元素会直接加到对应的向量 y 的每个元素上。
举一个简单的例子:

import torch
a = torch.tensor([0,1])
b = torch.tensor([2,3])
# 两个向量进行相加
a +=b
print(a)

代码运行结果为:

tensor([2, 4])

return X, y.reshape((-1, 1)):这里返回的X是一个矩阵,y.reshape((-1, 1))是对向量y进行重塑,得到一个单列矩阵。

一个小困惑(来自 百川大模型 的解答):
在这里插入图片描述

torch.normal函数

用途:用于生成正太分布(也称高斯分布)的随机数。

所需参数:torch.normal(均值, 标准差, 指定输出张量的形状)。

举一个简单的例子:
生成一个形状为 (3, 3) 的张量,其中的元素是从均值为 0,标准差为 1 的正态分布中随机抽取的,代码实现如下:

import torch
# 生成一个形状为 (3, 3) 的张量,其中的元素是从均值为 0,标准差为 1 的正态分布中随机抽取的
tensor = torch.normal(0, 1, (3, 3))
print(tensor)

由于生成的是随机数,所以每次运行上述代码时,得到的张量都会有所不同。
可能的输出结果:

tensor([[ 0.5983, -0.0891, -1.5944],
[ 0.4141, 0.5653, -0.3561],
[-0.1034, 0.2961, -0.8660]])

矩阵乘法

定义:设 A 为 m×p 的矩阵,B 为 p×n 的矩阵,那么称 m×n 的矩阵C为矩阵AB的乘积,记作 C = A × B

注意事项:
1、当矩阵A的列数(column)等于矩阵B的行数(row)时,A与B可以相乘。
2、矩阵C的行数等于矩阵A的行数,C的列数等于B的列数。
3、矩阵相乘不满足交换律,即 AB ≠ BA ,除非 A 和 B 是特殊的矩阵,如单位矩阵或伴随矩阵。

举一个简单的例子:
将一个 2×3 的矩阵与一个 3×2 的矩阵相乘,得到一个 2×2 的矩阵。
在这里插入图片描述

矩阵-向量乘法

一个矩阵可以与一个向量相乘(矩阵的列数必须等于向量的长度),这在数学上被称为矩阵-向量乘法。

例如,如果你有一个 3×2 的矩阵和一个长度为 2 的向量,那么你可以将它们相乘,结果将是一个长度为 3 的向量。但是,如果你有一个 3×2 的矩阵和一个长度为 3 的向量,那么你不能将它们相乘,因为向量的长度 3 不等于矩阵的列数 2 。

在这种乘法中,向量被视为列数为1的特殊矩阵。相乘的结果是一个新的向量(长度为输入矩阵的行数)。

在机器学习和深度学习中,这种乘法常常用于将 输入特征矩阵 与 模型的权重向量 相乘,从而得到模型的预测输出。

torch.matmul函数和torch.mv函数

torch.matmul函数:用于执行两个张量之间的矩阵乘法。
也就是说,torch.matmul函数 可以处理 两个矩阵 的乘法,也可以处理 一个矩阵和一个向量 的乘法,甚至可以处理 两个向量 的点积,并支持广播机制。

标量,也称零维张量
向量,也称一维张量
矩阵,也称二维张量

广播机制:允许不同形状的张量(多维数组)进行数学运算。

举一个简单的例子:

import torch

# 创建一个 2x2 的矩阵和一个长度为 2 的向量
matrix = torch.tensor([[1, 2], [3, 4]])
vector = torch.tensor([1, 2])

# 使用 torch.matmul() 函数进行矩阵乘法
result = torch.matmul(matrix, vector)

print(result)

若没有指定输出的形状,PyTorch 默认返回一个行向量。
运行代码,结果如下:

tensor([ 5, 11])

由于 torch.matmul() 函数会将向量 vector 广播成一个 2x1 的矩阵,然后进行矩阵乘法。矩阵的第一行和向量的乘积是 1*1 + 2*2 = 5,矩阵的第二行和向量的乘积是 3*1 + 4*2 = 11。计算结果如下:
在这里插入图片描述
torch.mv函数:仅适用于一个矩阵和一个向量的乘法,并且要求矩阵的列数必须与向量的长度相等。
torch.mv 函数的参数列表如下:

torch.mv(matrix, vector) → Tensor
matrix:第一个参数,是一个二维张量,扮演矩阵的角色。
vector:第二个参数,是一个一维张量,扮演向量的角色。
举一个简单的例子:

import torch

# 创建一个 2x2 的矩阵和一个长度为 2 的向量
matrix = torch.tensor([[1, 2], [3, 4]])
vector = torch.tensor([1, 2])

# 使用 torch.mv() 函数进行矩阵-向量乘法
result = torch.mv(matrix, vector)

print(result)

运行代码,结果如下:

tensor([ 5, 11])

无论是 torch.mv 还是 torch.matmul,当它们用于执行一个矩阵和一个向量的乘法时,默认返回的都是行向量。

torch.reshape函数

torch.reshape函数:在不改变张量元素数目的情况下改变张量的形状。
torch.reshape 函数的参数列表如下:

torch.reshape(input, shape) → Tensor
input:要重塑的张量,其元素数量和元素本身不会因重塑而改变。
shape:这是一个元组,指定了输出张量的新形状。元组的每个元素表示输出张量在相应维度上的大小。

举一个简单的例子:

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值