dataset = TensorDataset(torch.tensor(X_train), torch.tensor(y_train))
dataloader = DataLoader(dataset, batch_size=32, shuffle=True)
```
关键点:`DataLoader` 自动处理批处理、打乱和数据并行加载,是高效训练的基础。
第二步:定义模型结构
这是体现框架灵活性的核心环节。我们通过继承`nn.Module`类来定义网络。
```python
import torch.nn as nn
import torch.nn.functional as F
class SimpleNN(nn.Module):
def __init__(self, input_size, hidden_size, output_size):
super().__init__()
self.fc1 = nn.Linear(input_size, hidden_size) # 全连接层1
self.fc2 = nn.Linear(hidden_size, output_size) # 全连接层2
def forward(self, x):
x = F.relu(self.fc1(x)) # 激活函数
x = self.fc2(x)
return x
model = SimpleNN(784, 128, 10) # 实例化模型
```
自问自答:为什么一定要定义`forward`方法,而不是在`__call__`里实现?实际上,`nn.Module`的`__call__`方法会调用`forward`,并挂钩一些内部钩子(hooks)。直接定义`forward`是约定俗成的标准做法,确保了模型行为的清晰和可扩展性。
第三步:配置损失函数与优化器
框架将经典算法封装为易用的组件。
```python
criterion = nn.CrossEntropyLoss() # 损失函数
optimizer = torch.optim.Adam(model.parameters(), lr=0.001) # 优化器
```
亮点:优化器(如Adam)自动管理所有模型参数(`model.parameters()`)的更新逻辑,开发者只需关注学习率等超参数。
第四步:训练循环
这是模型学习的核心过程,框架让流程变得标准化。
```python
for epoch in range(num_epochs):
for batch_x, batch_y in dataloader:
optimizer.zero_grad() # 梯度清零
outputs = model(batch_x) # 前向传播
loss = criterion(outputs, batch_y) # 计算损失
loss.backward() # 反向传播,自动计算梯度
optimizer.step() # 优化器更新参数
```
重点内容:`loss.backward()` 一行代码便完成了整个计算图上所有参数的梯度计算,这是自动微分(Autograd)技术的威力体现,是深度学习框架的基石。
掌握了基础用法后,我们需要关注领域的前沿动态。当前AI框架的发展有哪些显著趋势?
首先,计算图的融合与编译优化成为竞争焦点。无论是PyTorch的TorchScript和TorchDynamo,还是JAX的JIT,目标都是将灵活的Python代码编译成高效、可移植的底层代码,以提升性能并满足部署需求。其次,对大模型训练与推理的专项支持,如分布式训练、混合精度计算、模型并行等,已成为框架的必备能力。最后,与硬件和编译器的深度协同,使得针对特定AI芯片(如NPU)的优化更加直接和高效。
从个人实践角度看,框架的本质是生产力工具。与其纠结于“哪个框架最好”,不如深入理解其背后的共同原理:计算图、自动微分、张量运算。这能让你在技术变迁中保持适应力。当前,PyTorch在学术和工业界的平衡性,以及其以开发者为中心的设计哲学,使其在可预见的未来仍将保持强大的生命力。但值得投入时间了解JAX所代表的函数式与编译思想,这可能是未来高性能计算的重要范式。
学习AI框架的旅程,始于实用,但最终应归于对机器学习本身更深刻的理解。工具在迭代,但解决问题的思维永不过时。
