PyTorch入门与实战:从Tensor到自动微分与线性回归模型
文章目录
一、什么是 PyTorch?
PyTorch 是一个开源的深度学习框架,广泛应用于图像识别、自然语言处理等领域。它由 Python 编写,易学易用,非常适合机器学习开发者快速上手。
PyTorch 的三大核心特点是:
- 易于安装:支持多平台,安装过程简单。
- 灵活的 Tensor 操作:提供类似 Numpy 的多维数组,且支持 GPU 加速。
- 自动微分机制:通过反向传播自动计算梯度,让模型训练更加高效。
接下来,我将详细介绍如何安装 PyTorch、Tensor 的使用方法以及自动微分的原理和应用,最后一起动手实现一个简单的线性回归模型。
二、如何安装PyTorch?
-
安装前准备:
- 已安装
Python 3.9及以上版本; - 已安装Anaconda;
- 已安装
-
进入Pytorch官网,下滑到【install Pytorch】模块,获取安装Pytorch的pip命令。

-
Compute Platform 如何选择?
- CUDA:用于支持 NVIDIA GPU 的设备。如果你的电脑配有NVIDIA显卡,并且安装了CUDA(CUDA Toolkit版本如11.8、12.1或12.4),你可以利用GPU加速PyTorch的计算,提高训练和推理速度。
- CPU:选择CPU意味着PyTorch将仅使用你的中央处理器(CPU)进行计算。如果你没有兼容的GPU或者CUDA环境,或者你只是进行一些简单的小规模任务,可以选择CPU。
-
可以通过以下方法确认显卡是否为NVIDIA GPU:
- 按
Win + R,输入dxdiag,检查显示标签页是否有 NVIDIA 相关显卡型号

- 按
-
拷贝pip命令在cmd下运行

-
安装成功后,打开pycharm运行一个demo检查安装是否成功:
from __future__ import print_function import torch x = torch.rand(5,3) print(x)

通过上述步骤,我们成功安装了 PyTorch,接下来我们将深入学习 Tensor 的基本操作。
三、PyTorch 核心概念:张量(Tensor)
1. 什么是张量(Tensor)?
张量(Tensor) 是 PyTorch 中的核心数据结构,它可以理解为:
- 通用的多维数组,类似于 NumPy 的
ndarray。 - 可以表示标量(0维)、向量(1维)、矩阵(2维)和高维数组(3维及以上)。
- 张量的优势在于支持 自动微分 和 GPU加速,适合机器学习和深度学习任务。
2. 张量(Tensor)的基本操作:
(1) 创建张量
你可以用以下方法创建张量:
1) 从数据创建
import torch #导入PyTorch库,用于创建和操作张量。
# 创建一个张量
data = [[1, 2], [3, 4]]
x = torch.tensor(data) #将python列表转换为张量(Tensor)
print("张量x:", x)
print("x的形状:", x.shape)
2) 随机初始化张量
# 随机生成一个 3x3 的张量
x = torch.rand(3, 3) #torch.rand() 函数是用来生成随机张量。生成的随机数取值范围在 [0, 1)之间
print("随机张量x:", x)
# 生成全零或全一的张量
zeros = torch.zeros(2, 2)
ones = torch.ones(2, 2)
print("全零张量:", zeros)
print("全一张量:", ones)
3) 从 NumPy 数组创建张量
import numpy as np
arr = np.array([[1, 2], [3, 4]])
x = torch.from_numpy(arr) # 从NumPy数组创建张量
print("NumPy转张量:", x)
(2) 张量的基本运算
1) 加减乘除
x = torch.tensor([[1, 2], [3, 4]], dtype=torch.float32) #dtype=torch.float32,用于指定Tensor的数据类型是32位浮点数,如果不指定会创建int类型的Tensor
y = torch.tensor([[5, 6], [7, 8]], dtype=torch.float32)
# 张量加法
print("x + y:\n", x + y)
# 张量乘法(按元素相乘)
print("x * y:\n", x * y)
# 张量除法
print("x / y:\n", x / y)
2) 矩阵乘法
# 矩阵乘法 (dot product)
result = torch.matmul(x, y.T) # x和y的转置相乘
print("矩阵乘法:\n", result)
3) 维度变换
通过 .view() 方法改变Tensor的维度,数据的顺序没有改变,只是重新排列成了指定的形状。
注意:使用 .view() 改变形状时,张量中的元素数量必须保持一致。
x = torch.tensor([[1, 2, 3], [4, 5, 6]]) #2行3列的张量
# 查看形状
print("原始x形状:", x.shape)
# 改变形状
x_reshaped = x.view(3, 2) # 变成3行2列
print("变形后的x:\n", x_reshaped)
代码输出结果:
原始x形状: torch.Size([2, 3])
变形后的x:
tensor([[1, 2],
[3, 4],
[5, 6]])
3. 张量与 GPU 之间的交互
PyTorch 支持使用 GPU 加速计算。要将张量移动到 GPU 上,需要以下步骤:
(1) 检查是否支持 GPU
import torch
# 检查GPU是否可用
print("GPU是否可用:", torch.cuda.is_available())
(2) 将张量移动到 GPU 上
# 创建张量
x = torch.tensor([[1, 2], [3, 4]])
# 将张量移动到GPU
if torch.cuda.is_available():
x = x.to("cuda")
print("x在GPU上:", x)
(3) 在 GPU 和 CPU 之间切换
# 张量在GPU上
x_gpu = x.to("cuda")
# 张量移动回CPU
x_cpu = x_gpu.to("cpu")
print("x移动回CPU:", x_cpu)
4. 完整代码示例
以下代码展示了张量的创建、基本操作和 GPU 使用:
import torch
# 1. 创建张量
x = torch.rand(3, 3) # 随机生成一个3x3的张量
y = torch.ones(3, 3) # 生成一个全1的张量
print("张量x:\n", x)
print("张量y:\n", y)
# 2. 张量基本运算
sum_result = x + y # 加法
mul_result = x * y # 按元素乘法
matmul_result = torch.matmul(x, y.T) # 矩阵乘法
print("加法结果:\n", sum_result)
print("矩阵乘法结果:\n", matmul_result)
# 3. 维度变换
reshaped_x = x.view(9, 1) # 改变形状
print("改变形状后的x:\n", reshaped_x)
# 4. GPU操作
if torch.cuda.is_available():
x_gpu = x.to("cuda") # 将张量移动到GPU
print("x在GPU上:", x_gpu)
x_cpu = x_gpu.to("cpu") # 再移动回CPU
print("x回到CPU:\n", x_cpu)
四、自动微分 (Autograd):梯度计算详解
1. 什么是自动梯度(Autograd)?
- PyTorch 的自动梯度(Autograd) 是实现反向传播的核心工具,用于自动计算张量(Tensor)梯度。
- 在深度学习中,梯度 用于更新模型参数,以最小化损失函数(Loss Function)。
- PyTorch 中的
requires_grad属性告诉系统:需要对张量进行梯度计算。
2. 关键概念
requires_grad属性:- 如果设置
requires_grad=True,那么 PyTorch 会自动追踪这个张量上的操作,方便计算梯度。
- 如果设置
.backward():- 调用
.backward()方法会根据前向传播的计算图,自动执行反向传播,计算出梯度。
- 调用
.grad属性:- 用于访问张量的梯度值。
3. 代码示例与解释
以下是代码,逐行讲解:
import torch # 导入PyTorch库
# 1. 创建一个张量,并指定需要计算梯度
x = torch.tensor([2.0, 3.0], requires_grad=True)
print("张量x:", x)
# 2. 定义一个函数 y,对x进行运算
y = x ** 2 + 3 * x + 1 # y = x^2 + 3x + 1
print("函数y:", y)
# 3. 计算y的和,并进行反向传播
y.sum().backward() # 调用.backward()计算梯度
print("x的梯度:", x.grad)
(1) 执行结果
张量x: tensor([2., 3.], requires_grad=True) #在python中2.或2.0表示是浮点数(float)。
函数y: tensor([11., 19.], grad_fn=<AddBackward0>)
x的梯度: tensor([7., 9.])
(2) 反向传播的详细解释
-
第一部分: 创建张量。
先创建一个一维张量(包含2个元素),
requires_grad=True表示 PyTorch 需要对x计算梯度。 -
第二部分: 运算。
- 定义一个函数,并将2个元素传给函数。
- 第一个元素:
y 1 = ( 2 ) 2 + 3 ⋅ 2 + 1 = 11 y_1 = (2)^2 +3\cdot2 +1 = 11 y1=(2)2+3⋅2+1=11 - 第二个元素:
y 2 = ( 3 ) 2 + 3 ⋅ 3 + 1 = 19 y_2=(3)^2+3\cdot3+1=19 y2=(3)2+3⋅3+1=19
- 第一个元素:
grad_fn=<AddBackward0>表示 PyTorch 已经记录了这一步的操作,用于反向传播。
- 定义一个函数,并将2个元素传给函数。
-
第三部分: 反向传播
- 使用
.sum()- 由于
.backward()只能对标量(一个数)执行反向传播。 - 如果
y是一个向量(例如多个元素),使用.sum()将其转为标量,再执行反向传播。 - 计算
y的和:
y 1 + y 2 = 11 + 19 = 30 y_1+y_2=11+19=30 y1+y2=11+19=30
- 由于
.backward():执行反向传播,自动计算梯度。x.grad:访问计算得到的梯度。x.grad存储了计算得到的梯度,即:- 计算结果为:
∂ y . s u m ∂ x i = ∂ ( x i 2 + 3 x i + 1 ) ∂ x i \frac{\partial y.sum}{\partial x_i} = \frac{\partial (x_i^2 + 3x_i + 1)}{\partial x_i} ∂xi∂y.sum=∂xi∂(xi2+3xi+1)
- 使用
- 对第一个元素:
∂ y ∂ x 1 = 2 x 1 + 3 = 2 ⋅ 2 + 3 = 7 \frac{\partial y}{\partial x_1} = 2x_1+3=2\cdot2+3=7 ∂x1∂y=2x1+3=2⋅2+3=7 - 对第二个元素:
∂ y ∂ x 2 = 2 x 2 + 3 = 2 ⋅ 3 + 3 = 9 \frac{\partial y}{\partial x_2} = 2x_2+3=2\cdot3+3=9 ∂x2∂y=2x2+3=2⋅3+3=9 - 所以,
x.grad为:tensor([7., 9.])
(3) 总结
requires_grad=True:告诉 PyTorch 需要计算梯度。.backward():执行反向传播,自动计算梯度。x.grad:访问计算得到的梯度。
4. 如何禁用梯度计算?
- 可以使用
禁用梯度计算,节省内存和计算资源。with torch.no_grad()with torch.no_grad(): x = torch.tensor([2.0, 3.0], requires_grad=True) y = x ** 2 + 3 * x + 1 print(y) # 这里不会计算梯度
五、实战一下:实现线性回归模型
让我们结合之前学到的 Tensor 和 Autograd 知识,实现一个简单的线性回归模型。
完整流程介绍:
- 数据准备:用
torch.randn生成数据,模拟线性关系的输入和输出,定义线性关系。 - 模型构建:用
torch.nn.Linear创建线性模型 y= Wx + b。 - 定义损失函数:用
torch.nn.MSELoss定义回归任务的损失。 - 优化器设置:用
torch.optim.SGD设定参数更新的优化方式。 - 训练模型:不断调整 W 和 b 以最小化损失
- 前向传播:
model(x) - 计算损失:
criterion(y_pred, y) - 反向传播:
loss.backward() - 参数更新:
optimizer.step()
- 前向传播:
- 保存和加载模型:用
torch.save和torch.load将学习到的权重和偏置保存到文件中。

1. 数据准备:生成人工数据集
目标:生成符合线性关系的数据,模拟真实任务中的输入和输出。
代码:
import torch
# 生成随机输入数据 x,包含 100 个样本,每个样本有 1 个特征
x = torch.randn(100, 1) # 形状为 [100, 1]
# 人工生成线性关系数据 y = 3 * x + 2,加上随机噪声
y = 3 * x + 2 + torch.randn(100, 1) * 0.5 # 噪声控制在0.5范围内
print("输入数据 x 的前5个样本:\n", x[:5])
print("输出数据 y 的前5个样本:\n", y[:5])
解释:
y = 3 * x + 2 + torch.randn(100, 1) * 0.5:为什么要加上随机噪声?- 加入随机噪声的目的是模拟真实世界的数据特性,在现实中,数据往往会受到各种因素的干扰,很少完全符合一个精确的数学模型,加入随机噪声可以让模型更健壮(more robust),更贴近实际应用场景。
- 它可以帮助防止过拟合(Overfitting),提高模型的泛化能力。
- 噪声的幅度可以通过参数(如
* 0.5)调整,具体取决于任务需求。
x[:5]):Tensor的切片操作:- 类似于 Python 中对列表的切片,
x[:5]表示从第 0 行开始(默认)到第 5 行(不包括第 5 行),即取出第 0 行到第 4 行的数据。 - 如果
x是二维张量,x[:5]会取前 5 行的所有列。
- 类似于 Python 中对列表的切片,
执行结果:
输入数据 x 的前5个样本:
tensor([[-0.4322],
[ 0.0967],
[ 1.2571],
[-0.3540],
[-1.4387]])
输出数据 y 的前5个样本:
tensor([[0.5902],
[2.1607],
[6.5485],
[1.6901],
[-1.3721]])
2. 模型构建
目标:搭建一个具有一个输入和一个输出的线性模型。
代码:
import torch.nn as nn
# 定义一个线性模型:1个输入特征 -> 1个输出特征
model = nn.Linear(1, 1)
# 打印模型的初始权重和偏置
print("初始权重:", model.weight)
print("初始偏置:", model.bias)
解释:
nn.Linear(1, 1):创建一个线性模型,表示 y=Wx+by = Wx + b,其中 WW 是权重,bb 是偏置。- PyTorch 会随机初始化权重和偏置。
执行结果:
初始权重: Parameter containing:
tensor([[0.1041]], requires_grad=True)
初始偏置: Parameter containing:
tensor([0.1812], requires_grad=True)
3. 定义损失函数和优化器
目标:定义模型优化所需的工具,包括损失函数(评估模型预测的好坏)和优化器(用于更新模型参数)。
代码:
import torch.optim as optim
# 定义损失函数:均方误差(Mean Squared Error)
criterion = nn.MSELoss()
# 定义优化器:随机梯度下降(Stochastic Gradient Descent),学习率为 0.01
optimizer = optim.SGD(model.parameters(), lr=0.01)
解释:
-
nn.MSELoss():均方误差损失,衡量预测值与真实值之间的差异:
MSE = 1 n ∑ i = 1 n ( y ^ i − y i ) 2 \text{MSE} = \frac{1}{n} \sum_{i=1}^n (\hat{y}_i - y_i)^2 MSE=n1i=1∑n(y^i−yi)2 -
optim.SGD:随机梯度下降法,用于更新模型参数以最小化损失函数。
4. 训练模型
目标:通过前向传播、损失计算和反向传播的循环,让模型学会拟合数据。
代码:
# 训练模型
for epoch in range(200): # 共训练200次
# 前向传播:预测输出
y_pred = model(x)
# 计算损失
loss = criterion(y_pred, y)
# 梯度清零(PyTorch 中梯度是累加的,必须每轮清零)
optimizer.zero_grad()
# 反向传播:计算梯度
loss.backward()
# 更新参数
optimizer.step()
# 每20轮打印一次损失
if (epoch + 1) % 20 == 0:
print(f'Epoch {epoch+1}, Loss: {loss.item()}')
# 打印学习到的权重和偏置
print(f"学习到的权重:{model.weight.item()}, 偏置:{model.bias.item()}")
解释:
- 前向传播:输入数据
x通过模型得到预测值y_pred。 - 计算损失:用损失函数衡量预测值
y_pred和真实值y的差距。 - 反向传播:调用
loss.backward(),根据损失值计算梯度。 - 更新参数:调用
optimizer.step()使用梯度更新权重和偏置。
执行结果:
Epoch 20, Loss: 0.5156
Epoch 40, Loss: 0.2573
...
Epoch 200, Loss: 0.0101
学习到的权重:3.005, 偏置:2.002
5. 保存和加载模型
目标:将训练好的模型保存到文件,便于以后使用。
代码:
# 保存模型参数
torch.save(model.state_dict(), 'linear_regression.pth')
print("模型已保存到 'linear_regression.pth'")
# 加载模型参数
loaded_model = nn.Linear(1, 1) # 重新创建模型
loaded_model.load_state_dict(torch.load('linear_regression.pth')) # 加载保存的参数
loaded_model.eval() # 切换到评估模式
print("加载的模型权重:", loaded_model.weight)
print("加载的模型偏置:", loaded_model.bias)
解释:
torch.save():保存模型的参数到文件。torch.load():从文件中加载模型参数。eval():切换到评估模式(与训练模式不同,评估模式会关闭 Dropout 等功能)。
六、总结与展望
在本篇文章中,我们从 PyTorch 的基础概念入手,逐步学习了 Tensor 的基本操作、自动微分机制,并通过实战实现了一个简单的线性回归模型。接下来,你可以尝试更复杂的网络结构,如 CNN 和 RNN,或在真实数据集上进行实战项目,进一步提升技能。

1343

被折叠的 条评论
为什么被折叠?



