PyTorch 入门指南:从基础到实战
前言
人工智能,特别是深度学习,正在以前所未有的速度改变着世界。而作为构建和训练深度学习模型的基石,各种深度学习框架应运而生。在众多框架中,PyTorch 以其动态计算图、Pythonic 的编程风格和强大的社区支持,赢得了广大研究者和工程师的青睐。
本指南旨在为 PyTorch 初学者提供一个全面而深入的入门路径,从最基础的张量操作讲起,逐步深入到自动微分、构建神经网络,并最终通过一个简单的实战案例,带你走完模型训练的整个流程。无论你是一名学生、研究员,还是希望转型进入人工智能领域的开发者,相信本指南都能为你打下坚实的 PyTorch 基础。
我们将涵盖以下核心内容:
- PyTorch 基础:张量 (Tensors) – PyTorch 中最基本的数据结构。
- 自动微分 (Autograd) – 深度学习训练的魔法所在。
- 构建神经网络 (torch.nn) – 定义模型结构的利器。
- 优化器 (Optimizers) 与损失函数 (Loss Functions) – 模型训练的关键组件。
- 实战:构建并训练一个简单的神经网络 – 将所学知识融会贯通。
- 模型保存与加载 – 持久化你的训练成果。
- ** आगे की ओर देखिए (展望未来)** – 学习的下一步方向。
准备好了吗?让我们开始 PyTorch 的探索之旅!
第一章:PyTorch 基础:张量 (Tensors)
在 PyTorch 中,所有的数据都由张量 (Tensor) 来表示。张量可以看作是 NumPy 数组的升级版,它不仅支持各种数学运算,还能在 GPU 上加速计算,并且是自动微分的基础。
1.1 创建张量
PyTorch 提供了多种创建张量的方法:
-
直接从数据创建:
“`python
import torch从 Python 列表创建张量
data = [[1, 2], [3, 4]]
x_data = torch.tensor(data)
print(x_data)输出:
tensor([[1, 2],
[3, 4]])
从 NumPy 数组创建张量
import numpy as np
np_array = np.array(data)
x_np = torch.from_numpy(np_array)
print(x_np)输出:
tensor([[1, 2],
[3, 4]])
``
torch.from_numpy()` 创建的张量与 NumPy 数组共享内存,修改一个会影响另一个。
注意: -
通过形状创建指定类型的张量:
“`python
# 创建一个形状为 (2, 3) 的全1张量,数据类型为浮点型
x_ones = torch.ones(2, 3, dtype=torch.float32)
print(x_ones)
# 输出:
# tensor([[1., 1., 1.],
# [1., 1., 1.]])创建一个形状为 (2, 3) 的全0张量
x_zeros = torch.zeros(2, 3)
print(x_zeros)输出:
tensor([[0., 0., 0.],
[0., 0., 0.]])
创建一个形状为 (2, 3) 的随机张量
x_rand = torch.rand(2, 3)
print(x_rand)输出:
tensor([[0.5544, 0.9791, 0.2338],
[0.0607, 0.8800, 0.9655]]) # 每次运行结果不同
“`
-
通过已有张量的属性创建新的张量:
“`python
x_data = torch.tensor([[1, 2], [3, 4]])创建一个与 x_data 形状、数据类型相同的全1张量
x_like_ones = torch.ones_like(x_data)
print(x_like_ones)输出:
tensor([[1, 1],
[1, 1]])
创建一个与 x_data 形状、数据类型相同的随机张量
x_like_rand = torch.rand_like(x_data, dtype=torch.float32) # 也可以指定不同的数据类型
print(x_like_rand)输出:
tensor([[0.1134, 0.0807],
[0.0209, 0.6599]])
“`
1.2 张量的属性
张量的常用属性包括:
shape
: 张量的形状(维度大小)。dtype
: 张量的数据类型(如torch.float32
,torch.int64
)。device
: 张量所在的设备('cpu'
或'cuda:0'
等)。
python
tensor = torch.rand(3, 4)
print(f"张量形状: {tensor.shape}")
print(f"张量数据类型: {tensor.dtype}")
print(f"张量所在设备: {tensor.device}")
1.3 张量的操作
张量支持丰富的数学运算和索引/切片操作,这些操作与 NumPy 非常相似。
-
数学运算:
“`python
tensor = torch.ones(4, 4)
tensor[:,1] = 0 # 修改第二列为0
print(tensor)
# 输出:
# tensor([[1., 0., 1., 1.],
# [1., 0., 1., 1.],
# [1., 0., 1., 1.],
# [1., 0., 1., 1.]])加法
tensor_add = tensor + tensor # 或者 torch.add(tensor, tensor)
print(tensor_add)乘法(元素级乘法)
tensor_mul = tensor * tensor # 或者 torch.mul(tensor, tensor)
print(tensor_mul)矩阵乘法
注意:矩阵乘法要求内维匹配 (m x n) * (n x p) = (m x p)
tensor_matmul = tensor.T @ tensor # T 是转置,@ 是矩阵乘法运算符,也可以使用 torch.matmul(tensor.T, tensor)
print(tensor_matmul)
“` -
索引与切片: 与 NumPy 一致。
“`python
tensor = torch.arange(1, 10).reshape(3, 3)
print(tensor)
# 输出:
# tensor([[1, 2, 3],
# [4, 5, 6],
# [7, 8, 9]])获取第一行
print(tensor[0]) # 输出: tensor([1, 2, 3])
获取第一列
print(tensor[:, 0]) # 输出: tensor([1, 4, 7])
获取中心元素
print(tensor[1, 1]) # 输出: tensor(5)
获取最后两行
print(tensor[-2:]) # 输出: tensor([[4, 5, 6], [7, 8, 9]])
“` -
形状变换:
“`python
tensor = torch.arange(1, 10) # 形状为 (9,)
print(tensor) # 输出: tensor([1, 2, 3, 4, 5, 6, 7, 8, 9])改变形状
tensor_reshaped = tensor.reshape(3, 3)
print(tensor_reshaped)输出:
tensor([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
展平张量
tensor_flattened = tensor_reshaped.flatten()
print(tensor_flattened) # 输出: tensor([1, 2, 3, 4, 5, 6, 7, 8, 9])增加维度 (例如,增加一个 batch 维度)
tensor_unsqueeze = tensor_reshaped.unsqueeze(0) # 在第0个维度增加一个维度
print(tensor_unsqueeze.shape) # 输出: torch.Size([1, 3, 3])移除大小为1的维度
tensor_squeeze = tensor_unsqueeze.squeeze(0) # 移除第0个大小为1的维度
print(tensor_squeeze.shape) # 输出: torch.Size([3, 3])
“` -
连接与堆叠:
“`python
tensor1 = torch.ones(2, 3)
tensor2 = torch.zeros(2, 3)按行连接
tensor_cat_row = torch.cat([tensor1, tensor2], dim=0)
print(tensor_cat_row.shape) # 输出: torch.Size([4, 3])按列连接
tensor_cat_col = torch.cat([tensor1, tensor2], dim=1)
print(tensor_cat_col.shape) # 输出: torch.Size([2, 6])堆叠 (增加一个新维度)
tensor_stack = torch.stack([tensor1, tensor2], dim=0)
print(tensor_stack.shape) # 输出: torch.Size([2, 2, 3])
“`
1.4 张量与 NumPy 的转换
在 PyTorch 张量和 NumPy 数组之间进行转换非常容易,且通常很高效(如果它们都在 CPU 上)。
“`python
PyTorch 张量转 NumPy 数组
tensor = torch.ones(5)
numpy_array = tensor.numpy()
print(f”PyTorch 张量: {tensor}”)
print(f”NumPy 数组: {numpy_array}”)
NumPy 数组转 PyTorch 张量
numpy_array = np.zeros(5)
tensor = torch.from_numpy(numpy_array)
print(f”NumPy 数组: {numpy_array}”)
print(f”PyTorch 张量: {tensor}”)
注意:如果张量在 GPU 上,需要先转到 CPU
tensor_gpu = torch.ones(5, device=’cuda’)
numpy_array = tensor_gpu.cpu().numpy()
“`
1.5 张量与 GPU 加速
将张量移动到 GPU 可以极大地加速计算(如果你的机器有 NVIDIA GPU 并且安装了 CUDA)。
“`python
检查 CUDA 是否可用
if torch.cuda.is_available():
device = “cuda”
print(“CUDA is available! Training on GPU.”)
else:
device = “cpu”
print(“CUDA not available. Training on CPU.”)
创建一个张量并将其移动到设备
tensor = torch.ones(5, device=device) # 或 tensor.to(device)
print(f”张量所在的设备: {tensor.device}”)
“`
在实际训练中,模型参数和数据都需要放在同一个设备上。
第二章:自动微分 (Autograd)
深度学习的核心是反向传播 (Backpropagation),它通过计算损失函数关于模型参数的梯度来更新参数。PyTorch 的 autograd
模块正是实现自动微分的关键。它会记录所有在张量上的操作,构建一个动态计算图,并在需要时自动计算梯度。
2.1 追踪梯度
要让 PyTorch 追踪一个张量的计算历史并计算梯度,需要将它的 requires_grad
属性设置为 True
。默认情况下,大部分张量的 requires_grad
是 False
。模型的参数 (例如 nn.Linear
层的权重和偏置) 在创建时默认就是 requires_grad=True
。
“`python
x = torch.ones(5, requires_grad=True) # 设置 requires_grad=True
y = x + 2
z = y * y * 3
out = z.mean()
print(x.requires_grad) # 输出: True
print(y.requires_grad) # 输出: True (y 是通过对 x 进行操作得到的)
print(z.requires_grad) # 输出: True
print(out.requires_grad) # 输出: True
“`
2.2 执行反向传播
一旦你有了最终的标量损失函数(例如上面的 out
),就可以调用它的 .backward()
方法来计算所有需要梯度的张量(即 requires_grad=True
的张量)的梯度。
“`python
out.backward()
现在可以访问 x 的梯度
print(x.grad)
计算过程:
out = mean(z) = mean(3 * y^2) = mean(3 * (x+2)^2)
如果 x 是 [x1, x2, x3, x4, x5],那么 out = 1/5 * sum(3 * (xi+2)^2)
d(out)/d(xi) = 1/5 * d(3 * (xi+2)^2) / d(xi)
= 1/5 * 3 * 2 * (xi+2) * 1
= 6/5 * (xi+2)
对于本例 x = [1, 1, 1, 1, 1],则 xi=1,xi+2=3
梯度 d(out)/d(xi) = 6/5 * 3 = 18/5 = 3.6
所以 x.grad 应该是一个全为 3.6 的张量 [3.6, 3.6, 3.6, 3.6, 3.6]
“`
输出与预期相符。
2.3 梯度累积与清零
需要注意的是,梯度在每次 .backward()
调用时会累积到 .grad
属性中。在进行下一轮训练之前,必须将之前的梯度清零,否则梯度会不断累加,导致计算错误。这通常是通过优化器的 zero_grad()
方法来完成的。
“`python
假设这是训练循环中的一部分
… 计算 loss
loss.backward() # 计算梯度
optimizer.step() # 更新参数
optimizer.zero_grad() # 清零梯度,准备下一轮迭代
也可以手动清零某个张量的梯度
x.grad.zero_()
“`
2.4 停止梯度追踪
在某些情况下,你可能不需要计算梯度,例如在模型评估或推理阶段。可以使用 torch.no_grad()
上下文管理器来临时停止梯度追踪:
“`python
x = torch.ones(5, requires_grad=True)
print(x.requires_grad) # True
with torch.no_grad():
y = x + 2
print(y.requires_grad) # False
z = x + 3 # 在 no_grad 上下文之外,梯度追踪恢复
print(z.requires_grad) # True
``
.detach()` 方法创建一个不附带梯度信息的新张量:
或者使用
python
x = torch.ones(5, requires_grad=True)
y = x.detach()
print(y.requires_grad) # False
detach()
创建的张量与原张量共享数据内存,但计算图被分离。
第三章:构建神经网络 (torch.nn)
torch.nn
是 PyTorch 构建神经网络的核心模块。它提供了各种层 (Layers)、损失函数 (Loss Functions) 和其他构建网络所需的工具。
3.1 Module 类
nn.Module
是所有神经网络模块(包括层、整个模型)的基类。构建自定义神经网络通常需要继承 nn.Module
类,并在其中定义网络的结构和前向传播逻辑。
一个 nn.Module
子类至少需要实现两个方法:
__init__(self, ...)
: 在构造函数中定义网络的各个层和其他子模块。通常调用父类构造函数super().__init__()
。forward(self, x)
: 定义数据在前向传播时如何流过网络。输入x
是一个张量,返回网络的输出张量。
“`python
import torch.nn as nn
import torch.nn.functional as F # 提供一些函数式的操作,如激活函数
class SimpleNeuralNetwork(nn.Module):
def init(self, input_size, hidden_size, output_size):
super(SimpleNeuralNetwork, self).init() # 调用父类构造函数
self.fc1 = nn.Linear(input_size, hidden_size) # 第一个全连接层 (线性层)
self.relu = nn.ReLU() # ReLU 激活函数
self.fc2 = nn.Linear(hidden_size, output_size) # 第二个全连接层
def forward(self, x):
x = self.fc1(x) # 数据通过第一个线性层
x = self.relu(x) # 通过 ReLU 激活函数
x = self.fc2(x) # 数据通过第二个线性层
return x
实例化模型
input_dim = 28 * 28 # 例如,处理 28×28 的图像数据
hidden_dim = 128
output_dim = 10 # 例如,10个类别的分类问题
model = SimpleNeuralNetwork(input_dim, hidden_dim, output_dim)
print(model)
“`
3.2 常用层 (Layers)
torch.nn
提供了丰富的预定义层:
- 线性层 (Linear):
nn.Linear(in_features, out_features)
实现y = xA^T + b
的线性变换。 - 卷积层 (Convolutional):
nn.Conv1d
,nn.Conv2d
,nn.Conv3d
用于处理序列、图像、体数据等。 - 池化层 (Pooling):
nn.MaxPool1d
,nn.MaxPool2d
,nn.MaxPool3d
,nn.AvgPool2d
降低特征图的空间维度。 - 激活函数 (Activation Functions):
nn.ReLU
,nn.Sigmoid
,nn.Tanh
,nn.LeakyReLU
引入非线性。通常作为单独的层或在forward
方法中直接调用函数式的版本(如F.relu()
)。 - 归一化层 (Normalization):
nn.BatchNorm1d
,nn.BatchNorm2d
帮助稳定训练。 - 丢弃层 (Dropout):
nn.Dropout
用于正则化,防止过拟合。
你也可以使用 nn.Sequential
来构建一个简单的顺序执行的模型,而无需显式定义 forward
方法:
“`python
使用 nn.Sequential 构建一个简单的网络
seq_model = nn.Sequential(
nn.Linear(input_dim, hidden_dim),
nn.ReLU(),
nn.Linear(hidden_dim, output_dim)
)
print(seq_model)
“`
3.3 访问模型参数
nn.Module
的实例会通过其 parameters()
方法暴露所有需要学习的参数(那些 requires_grad=True
的张量):
python
print("模型参数:")
for name, param in model.named_parameters():
if param.requires_grad:
print(f"{name} - Shape: {param.shape}")
第四章:优化器 (Optimizers) 与损失函数 (Loss Functions)
构建完模型后,我们需要定义如何衡量模型的输出与真实标签之间的差距(损失函数),以及如何根据这个差距调整模型参数(优化器)。
4.1 损失函数 (Loss Functions)
损失函数计算预测值与真实值之间的差异。torch.nn
提供了多种常用的损失函数:
- 回归问题:
nn.MSELoss
: 均方误差 (Mean Squared Error)。nn.L1Loss
: 平均绝对误差 (Mean Absolute Error)。
- 分类问题:
nn.CrossEntropyLoss
: 交叉熵损失,常用于多类别分类,内部包含了 LogSoftmax 和 NLLLoss。nn.BCELoss
: 二元交叉熵损失 (Binary Cross-Entropy),用于二分类问题(输入需要经过 Sigmoid)。nn.BCEWithLogitsLoss
: 带有 Logits 的二元交叉熵损失,更稳定,直接接收未经 Sigmoid 的原始输出。
“`python
实例化一个分类问题的损失函数
criterion = nn.CrossEntropyLoss()
假设模型输出 preds 和真实标签 targets
preds: 形状 (batch_size, num_classes),通常是未经激活函数的原始输出 (logits)
targets: 形状 (batch_size),包含每个样本的类别索引 (0 to num_classes-1)
preds = torch.randn(64, 10, requires_grad=True)
targets = torch.randint(0, 10, (64,))
loss = criterion(preds, targets)
print(f”计算得到的损失: {loss.item()}”)
“`
4.2 优化器 (Optimizers)
优化器负责根据模型参数的梯度更新参数。torch.optim
模块提供了各种优化算法:
optim.SGD
: 随机梯度下降 (Stochastic Gradient Descent),可以带有动量 (momentum)。optim.Adam
: Adam 优化器,一种自适应学习率方法,在实践中表现通常不错。optim.Adagrad
,optim.RMSprop
等。
实例化优化器时,需要将模型的参数传递给它,并指定学习率 (learning rate) 等超参数。
“`python
import torch.optim as optim
实例化一个 Adam 优化器
第一个参数是需要优化的参数列表,通过 model.parameters() 获取
第二个参数是学习率 lr
optimizer = optim.Adam(model.parameters(), lr=0.001)
实例化一个 SGD 优化器,带有动量
optimizer = optim.SGD(model.parameters(), lr=0.01, momentum=0.9)
“`
优化器的核心方法是:
optimizer.zero_grad()
: 清零所有被优化器管理的参数的梯度。在每次反向传播之前调用。optimizer.step()
: 根据当前计算的梯度更新参数。在反向传播之后调用。
第五章:实战:构建并训练一个简单的神经网络
现在,我们将前面学到的张量、自动微分、模型、损失函数和优化器结合起来,完成一个简单的训练流程。我们模拟一个简单的二分类任务。
5.1 模拟数据
为了简化,我们不加载真实数据集,而是生成一些模拟数据。
“`python
import torch
import torch.nn as nn
import torch.optim as optim
import matplotlib.pyplot as plt # 用于可视化 (可选)
模拟数据
torch.manual_seed(42) # 设置随机种子,保证结果可复现
num_samples = 100
特征 X,形状 (num_samples, 2),假设是二维数据点
X = torch.randn(num_samples, 2) * 2
标签 Y,形状 (num_samples,),二分类标签 (0或1)
我们定义一个简单的规则:如果 x1 + x2 > 0,则为类别 1,否则为类别 0
Y = (X[:, 0] + X[:, 1] > 0).long() # .long() 确保标签是长整型,符合 CrossEntropyLoss 的要求
可视化数据 (可选)
plt.scatter(X[:, 0].numpy(), X[:, 1].numpy(), c=Y.numpy(), cmap=’viridis’)
plt.title(“Simulated Data”)
plt.xlabel(“Feature 1”)
plt.ylabel(“Feature 2”)
plt.show()
将数据移动到设备
if torch.cuda.is_available():
device = “cuda”
else:
device = “cpu”
X = X.to(device)
Y = Y.to(device)
“`
5.2 定义模型
我们定义一个简单的包含一个隐藏层的神经网络。
“`python
class SimpleClassifier(nn.Module):
def init(self, input_size, hidden_size, output_size):
super(SimpleClassifier, self).init()
self.fc1 = nn.Linear(input_size, hidden_size)
self.relu = nn.ReLU()
self.fc2 = nn.Linear(hidden_size, output_size) # output_size=2 表示二分类
def forward(self, x):
x = self.fc1(x)
x = self.relu(x)
x = self.fc2(x)
return x
input_size = X.shape[1] # 数据特征数量
hidden_size = 10
output_size = 2 # 类别数量 (0和1)
model = SimpleClassifier(input_size, hidden_size, output_size).to(device) # 将模型移动到设备
print(model)
“`
5.3 定义损失函数和优化器
python
criterion = nn.CrossEntropyLoss() # 用于二分类和多分类,输入是 logits,标签是类别索引
optimizer = optim.Adam(model.parameters(), lr=0.01)
5.4 训练循环
训练过程通常在一个循环中进行,每次迭代处理一批数据。在本例中,我们使用全部数据作为一个批次进行训练,以简化流程。
“`python
num_epochs = 100 # 训练轮次
print(“开始训练…”)
for epoch in range(num_epochs):
# 1. 前向传播 (Forward pass)
# 输入 X,得到模型输出 preds
preds = model(X)
# 2. 计算损失 (Calculate loss)
# 将模型输出和真实标签传入损失函数
loss = criterion(preds, Y)
# 3. 反向传播和优化 (Backward pass and optimize)
# 清零之前累积的梯度
optimizer.zero_grad()
# 执行反向传播,计算梯度
loss.backward()
# 根据计算出的梯度更新模型参数
optimizer.step()
# 打印训练信息
if (epoch+1) % 10 == 0:
# 计算训练集上的准确率 (仅用于观察,实际应在验证集上评估)
# preds 经过 softmax 后取最大值的索引即为预测类别
_, predicted = torch.max(preds.data, 1)
# 比较预测类别与真实标签
correct = (predicted == Y).sum().item()
accuracy = correct / num_samples
print(f"Epoch [{epoch+1}/{num_epochs}], Loss: {loss.item():.4f}, Accuracy: {accuracy:.4f}")
print(“训练结束!”)
“`
5.5 模型评估 (简单的示例)
训练完成后,我们可以在测试集上评估模型性能。由于本例没有单独的测试集,我们直接在训练数据上进行一次评估。
“`python
将模型设置为评估模式
model.eval()
在评估模式下,不计算梯度,不启用 Dropout 等
with torch.no_grad():
preds = model(X)
_, predicted = torch.max(preds.data, 1)
correct = (predicted == Y).sum().item()
accuracy = correct / num_samples
print(f”最终训练集准确率: {accuracy:.4f}”)
将模型设置回训练模式 (如果需要继续训练)
model.train()
“`
这个简单的例子展示了 PyTorch 训练模型的核心流程:数据准备 -> 模型定义 -> 损失函数和优化器定义 -> 训练循环 (前向传播 -> 计算损失 -> 反向传播 -> 优化)。
第六章:模型保存与加载
训练好的模型需要保存,以便后续使用(如推理、继续训练)。PyTorch 提供了灵活的模型保存和加载机制。
6.1 保存和加载模型的状态字典 (State Dict)
推荐的方式是保存和加载模型参数的状态字典 (state_dict),它是一个 Python 字典,存储了模型中所有参数的张量。
“`python
保存模型状态字典
model_save_path = “simple_classifier_model.pth”
torch.save(model.state_dict(), model_save_path)
print(f”模型状态字典已保存到 {model_save_path}”)
加载模型状态字典
首先需要重新创建一个模型实例,模型的结构必须与保存时的模型一致
loaded_model = SimpleClassifier(input_size, hidden_size, output_size).to(device)
加载状态字典
loaded_model.load_state_dict(torch.load(model_save_path))
print(“模型状态字典已加载”)
现在 loaded_model 的参数与之前训练好的 model 参数一致
可以在 loaded_model 上进行评估或推理
loaded_model.eval()
…进行评估或推理…
“`
这种方法更灵活,因为你可以只加载部分参数,或者在不同的模型架构之间迁移参数(如果参数名称和形状匹配)。
6.2 保存和加载整个模型 (不推荐用于生产环境)
也可以保存整个模型对象,包括结构和参数。但这依赖于模型的类定义,如果类定义改变了,加载可能会出问题。通常用于快速保存和加载,不推荐用于长期存储或跨项目使用。
“`python
保存整个模型
model_save_path_full = “simple_classifier_full.pth”
torch.save(model, model_save_path_full)
print(f”整个模型已保存到 {model_save_path_full}”)
加载整个模型
loaded_model_full = torch.load(model_save_path_full)
print(“整个模型已加载”)
loaded_model_full.eval()
…进行评估或推理…
“`
第七章: आगे की ओर देखिए (展望未来)
恭喜你!你已经掌握了 PyTorch 的基础知识,并了解了构建和训练神经网络的核心流程。这只是深度学习世界的冰山一角。接下来,你可以继续深入学习:
- 处理真实数据集: 学习使用
torch.utils.data.Dataset
和torch.utils.data.DataLoader
高效地加载和处理大规模数据集。 - 更复杂的网络结构: 学习卷积神经网络 (CNN) 处理图像,循环神经网络 (RNN) 或 Transformer 处理序列数据。
- 迁移学习 (Transfer Learning): 利用预训练模型加速你的训练任务。
- 高级优化技术: 学习学习率调度 (Learning Rate Scheduling)、正则化技术 (如 L2, Dropout, BatchNorm)。
- PyTorch 生态系统: 探索
torchvision
,torchaudio
,torchtext
等用于特定领域任务的库,以及PyTorch Lightning
,Hugging Face Transformers
等高级框架。 - 模型部署: 学习如何将训练好的模型部署到生产环境。
结论
PyTorch 是一个强大、灵活且易于学习的深度学习框架。通过本指南,你已经掌握了张量、自动微分、构建神经网络、定义损失函数和优化器,以及完成一个基本的训练循环。从基础到实战,你迈出了坚实的第一步。
学习深度学习和 PyTorch 需要持续的实践和探索。动手尝试修改本指南中的代码,解决不同的问题,阅读官方文档和社区资源,你将能更快地成长。
祝你在 PyTorch 的学习之路上一切顺利!