【深度学习基础 2】 PyTorch 框架
目录
一、 PyTorch 简介
二、安装 PyTorch
三、PyTorch 常用函数和操作
3.1 创建张量(Tensor)
3.2 基本数学运算
3.3 自动求导(Autograd)
3.4 定义神经网络模型
3.5 训练与评估模型
3.6 使用模型进行预测
四、注意事项
五、完整训练示例代码
一、 PyTorch 简介
PyTorch 是由 Facebook 开发的开源深度学习框架,以动态计算图(Dynamic Computational Graph)著称,允许在运行时即时定义和修改模型结构,便于调试和研究。它支持 GPU 加速,并拥有丰富的生态系统,适用于自然语言处理、计算机视觉等众多领域。
主要特点:
-
动态计算图:每次运行时构建计算图,便于调试和灵活性高。
-
自动求导(Autograd):支持自动求导,便于梯度计算与反向传播。
-
模块化设计:通过
torch.nn
提供丰富的神经网络层及模块,方便构建复杂模型。 -
丰富的生态:支持 torchvision、torchtext 等扩展库,加速模型开发和实验。
二、安装 PyTorch
可参考YOLO系列环境配置及训练_yolo环境配置-CSDN博客 中pytorch的安装方法,以下简要概括:(以安装CPU版本为例)
pip install torch torchvision
安装后,可以通过以下代码验证安装及查看版本:
import torch
print("PyTorch 版本:", torch.__version__)
CPU版本安装成功的输出示例为:
PyTorch 版本: 1.13.0
三、PyTorch 常用函数和操作
3.1 创建张量(Tensor)
与TensorFlow一样,在 PyTorch 中的张量类似于 NumPy 的数组,同时支持 GPU 加速。
例如:
import torch
# 创建标量、向量和矩阵
scalar = torch.tensor(5)
vector = torch.tensor([1, 2, 3])
matrix = torch.tensor([[1, 2], [3, 4]])
print("标量:", scalar)
print("向量:", vector)
print("矩阵:\n", matrix)
样例输出:
标量: tensor(5)
向量: tensor([1, 2, 3])
矩阵:
tensor([[1, 2],
[3, 4]])
3.2 基本数学运算
PyTorch 同样提供了基本的数学运算,例如:
a = torch.tensor(3.0)
b = torch.tensor(2.0)
print("加法:", torch.add(a, b))
print("乘法:", torch.mul(a, b))
# 矩阵乘法
mat1 = torch.tensor([[1, 2]])
mat2 = torch.tensor([[3], [4]])
print("矩阵乘法:\n", torch.matmul(mat1, mat2))
样例输出:
加法: tensor(5.)
乘法: tensor(6.)
矩阵乘法:
tensor([[11]])
3.3 自动求导(Autograd)
PyTorch 的 autograd 功能可以自动计算梯度,非常适合神经网络反向传播的实现。
例如:
# 定义一个需要计算梯度的张量
x = torch.tensor(2.0, requires_grad=True)
# 定义函数 y = x³ + 2x + 1
y = x**3 + 2*x + 1
# 反向传播,计算 dy/dx
y.backward()
print("dy/dx:", x.grad)
样例输出:
dy/dx: tensor(14.)
3.4 定义神经网络模型
PyTorch 提供了 torch.nn
模块来构建神经网络模型。例如下面使用一个简单的全连接层构建模型:
import torch.nn as nn
import torch.optim as optim
# 定义一个简单的神经网络
class SimpleNet(nn.Module):
def __init__(self):
super(SimpleNet, self).__init__()
self.fc = nn.Linear(784, 10) # 输入 784 维,输出 10 维(例如手写数字分类)
def forward(self, x):
out = self.fc(x)
return out
# 实例化模型并打印模型结构
model = SimpleNet()
print(model)
样例输出:
SimpleNet(
(fc): Linear(in_features=784, out_features=10, bias=True)
)
3.5 训练与评估模型
在3.4的基础上,我们继续完善构建。
例如:
# 假设我们有一个批次的输入数据(如手写数字图像,已展平为784维向量)
batch_size = 32
dummy_input = torch.randn(batch_size, 784) # 随机生成一批数据
dummy_labels = torch.randint(0, 10, (batch_size,)) # 随机生成对应的标签
# 定义损失函数和优化器
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=0.001)
# 前向传播
outputs = model(dummy_input)
loss = criterion(outputs, dummy_labels)
print("初始损失:", loss.item())
# 反向传播和优化
optimizer.zero_grad()
loss.backward()
optimizer.step()
# 再次输出损失(注意:仅作为示例,损失值可能不会明显下降)
outputs_after = model(dummy_input)
loss_after = criterion(outputs_after, dummy_labels)
print("更新后损失:", loss_after.item())
样例输出:
初始损失: 2.280543327331543
更新后损失: 2.2781271934509277
注意: 损失值会受到随机数据和权重初始化的影响,实际训练中损失下降情况应更为明显。
3.6 使用模型进行预测
在 3.5 训练结束后,我们可以通过调用模型的 forward
方法,可以对新的数据进行预测:
# 对一条测试数据进行预测
test_sample = torch.randn(1, 784)
pred_logits = model(test_sample)
pred_label = torch.argmax(pred_logits, dim=1)
print("预测类别:", pred_label.item())
样例输出:
预测类别: 7
四、注意事项
在训练过程中,切忌混淆设备(Device),注意将模型和数据迁移到同一设备:
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
model = model.to(device)
inputs = inputs.to(device)
五、完整训练示例代码
import torch
import torch.nn as nn
import torch.optim as optim
# 定义一个简单的神经网络
class SimpleNet(nn.Module):
def __init__(self):
super(SimpleNet, self).__init__()
self.fc = nn.Linear(784, 10) # 输入 784 维,输出 10 维(例如手写数字分类)
def forward(self, x):
out = self.fc(x)
return out
# 实例化模型
model = SimpleNet()
print(model)
# 设置设备(如果有 GPU 就用 GPU,否则用 CPU)
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
model = model.to(device)
# 假设我们有一个批次的输入数据(如手写数字图像,已展平为784维向量)
batch_size = 32
dummy_input = torch.randn(batch_size, 784).to(device) # 随机生成一批数据并迁移到 device
dummy_labels = torch.randint(0, 10, (batch_size,)).to(device) # 随机生成对应的标签并迁移到 device
# 定义损失函数和优化器
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=0.001)
# 前向传播
outputs = model(dummy_input)
loss = criterion(outputs, dummy_labels)
print("初始损失:", loss.item())
# 反向传播和优化
optimizer.zero_grad()
loss.backward()
optimizer.step()
# 再次输出损失(仅作为示例,损失值可能不会明显下降)
outputs_after = model(dummy_input)
loss_after = criterion(outputs_after, dummy_labels)
print("更新后损失:", loss_after.item())
# 对一条测试数据进行预测
test_sample = torch.randn(1, 784).to(device)
pred_logits = model(test_sample)
pred_label = torch.argmax(pred_logits, dim=1)
print("预测类别:", pred_label.item())