文章目录
Torch 入门教程
这是一篇针对 Torch 框架的入门教程,主要介绍 Torch 的基础知识、数据载入、模型定义和训练,以及模型测试。
Torch 的基础知识
Torch 是一个基于 Lua 编程语言的科学计算框架,主要用于深度学习研究。在 Torch 中,所有的数据都可以被表示为多维张量(tensor),并且支持自动求导。Torch 同时也提供了一些常见的深度学习模型和优化算法的实现。
torch和PyTorch什么区别?
torch 和 PyTorch 是两个不同的概念。
torch 是 PyTorch 默认的数据结构库,其提供了多种张量操作函数,包括 torch.Tensor,torch.nn,torch.optim 等模块。在 PyTorch 中使用 torch 库创建 Tensor、执行张量运算等,因此我们可以认为 torch 是 PyTorch 框架中的一部分。
而 PyTorch 则是一个完整的深度学习框架,以计算图为核心,提供了完善的模型定义、训练、推理等功能。
因此,torch 和 PyTorch 是不同的概念,但在 PyTorch 中使用 torch 库是必须的。
Tensor
Tensor(张量)是 Torch 中最常见的数据结构,类似于 Numpy 中的数组,可以表示多维数据。Tensor 可以在 CPU 和 GPU 上进行计算,也支持自动求导。
创建一个 Tensor:
import torch
# 创建一个空的 Tensor,2 表示 2 维,3 表示第一维的长度,4 表示第二位的长度
x = torch.empty(2, 3, 4)
# 创建一个随机初始化的 Tensor
x = torch.rand(2, 3)
# 创建一个全 0 Tensor
x = torch.zeros(2, 3)
# 创建一个全 1 Tensor
x = torch.ones(2, 3)
# 从 Numpy 数组创建一个 Tensor
import numpy as np
x = torch.from_numpy(np.array([[1, 2], [3, 4]]))
Tensor 的形状(shape)可以通过 size()
方法获取:
x = torch.rand(2, 3)
print(x.size()) # 输出: torch.Size([2, 3])
Tensor 的数据类型(dtype)可以通过 Tensor 的构造函数指定,也可以通过 dtype
属性获取:
x = torch.rand(2, 3, dtype=torch.float)
print(x.dtype) # 输出: torch.float32
可以使用 to()
方法将 Tensor 移动到指定设备(CPU 或 GPU):
# 检查是否有可用的 GPU
if torch.cuda.is_available():
device = torch.device("cuda") # GPU 设备
else:
device = torch.device("cpu") # CPU 设备
x = x.to(device)
Autograd
Autograd(自动求导)是 Torch 中的自动微分引擎,用于计算梯度。Autograd 在记录 Tensor 上的所有操作,并构建一个有向无环图(DAG),在反向传播时自动计算梯度。
创建一个可求导的 Tensor:
import torch
x = torch.ones(2, 3, requires_grad=True)
print(x.requires_grad) # 输出: True
可以通过 backword()
方法计算梯度:
y = x.sum()
y.backward()
print(x.grad) # 输出: tensor([[1., 1., 1.],
# [1., 1., 1.]])
注意:只有形状为标量的 Tensor(例如单个数值),才能调用 backword()
方法计算梯度,对于其他形状的 Tensor,需要对其中一个元素进行求和操作。
y = x.sum()
y.backward()
print(x.grad) # 输出: tensor([[1., 1., 1.],
# [1., 1., 1.]])
Optimizer
Optimizer(优化器)是 Torch 中用于优化模型参数的算法。常用的优化器包括随机梯度下降(SGD)、Adam、Adagrad 等。
import torch
import torch.optim as optim
# 定义一个模型和优化器
model = ...
optimizer = optim.SGD(model.parameters(), lr=0.1)
# 在训练循环中使用优化器
optimizer.zero_grad()
loss_fn(model(input), target).backward()
optimizer.step()
举例一
模型定义
在 Torch 中,可以通过继承 torch.nn.Module
类来定义自己的深度学习模型。例如,下面是一个简单的全连接神经网络:
import torch
class Net(torch.nn.Module):
def __init__(self):
super(Net, self).__init__()
self.fc1 = torch.nn.Linear(784, 256)
self.fc2 = torch.nn.Linear(256, 10)
def forward(self, x):
x = torch.flatten(x, start_dim=1)
x = torch.relu(self.fc1(x))
x = self.fc2(x)
return x
model = Net()
以上代码中,Net
类继承自 torch.nn.Module
,并定义了两个全连接层(self.fc1
和 self.fc2
)。在 forward()
方法中,先将输入数据展开成一维向量(torch.flatten(x)
),然后依次经过两个全连接层和一个 ReLU 激活函数,最后输出模型的预测结果。
模型训练
在训练模型之前,需要定义损失函数和优化器。常见的损失函数有交叉熵(torch.nn.CrossEntropyLoss()
)和均方误差(torch.nn.MSELoss()
),常见的优化器有随机梯度下降(torch.optim.SGD()
)和 Adam(torch.optim.Adam()
)。
import torch
import torch.optim as optim
# 定义模型和损失函数
model = ...
loss_fn = torch.nn.CrossEntropyLoss()
# 定义优化器
optimizer = optim.SGD(model.parameters(), lr=0.01)
# 训练模型
for epoch in range(num_epochs):
for i, (inputs, labels) in enumerate(train_loader):
optimizer.zero_grad() # 清空梯度
outputs = model(inputs) # 正向传播
loss = loss_fn(outputs, labels) # 计算损失
loss.backward() # 反向传播
optimizer.step() # 更新参数
以上代码中,num_epochs
表示训练轮数,train_loader
表示用于载入训练数据的迭代器对象。在每一轮训练中,先将梯度清零(optimizer.zero_grad()
),然后进行模型的正向传播(model(inputs)
),接着计算损失(loss_fn(outputs, labels)
),再进行反向传播计算梯度(loss.backward()
),最后调用优化器的 step()
方法更新模型参数。
模型保存和加载
在训练完成后,可以将模型保存到文件中,以便在之后的使用中加载模型并进行预测。
保存模型:
torch.save(model.state_dict(), 'model.pt')
加载模型:
model = Net()
model.load_state_dict(torch.load('model.pt'))
模型评估
训练完模型后,可以使用以下代码计算测试集上的准确率:
model.eval() # 设置模型为评估模式
correct = 0
total = 0
with torch.no_grad():
for inputs, labels in test_loader:
outputs = model(inputs)
_, predicted = torch.max(outputs.data, 1)
total += labels.size(0)
correct += (predicted == labels).sum().item()
print(f'Accuracy: {100 * correct / total:.2f}%')
以上代码中,model.eval()
表示设置模型为评估模式,关闭 Dropout 和 BatchNorm 层的随机性行为。然后对测试集中的每个样本进行预测(outputs = model(inputs)
),取预测结果的最大值作为模型最终的预测结果(_, predicted = torch.max(outputs.data, 1)
)。最终计算预测正确的样本数量和总样本数量,计算准确率。
举例二
数据载入
在 Torch 中,可以使用 torchvision
模块来载入常用的数据集,例如 MNIST、CIFAR-10 等。
import torch
import torchvision
train_dataset = torchvision.datasets.MNIST(root='./data', train=True, transform=None, download=True)
test_dataset = torchvision.datasets.MNIST(root='./data', train=False, transform=None, download=True)
train_loader = torch.utils.data.DataLoader(train_dataset, batch_size=128, shuffle=True)
test_loader = torch.utils.data.DataLoader(test_dataset, batch_size=128, shuffle=True)
以上代码中,train_dataset
和 test_dataset
分别表示训练集和测试集,train_loader
和 test_loader
则是用于载入数据的迭代器对象。其中,batch_size
表示每个批次的大小,shuffle
表示是否打乱数据顺序。
模型定义和训练
在 Torch 中,可以通过继承 torch.nn.Module
类来定义自己的深度学习模型。例如,下面是一个简单的全连接神经网络:
class Net(torch.nn.Module):
def __init__(self):
super(Net, self).__init__()
self.fc1 = torch.nn.Linear(784, 256)
self.fc2 = torch.nn.Linear(256, 10)
def forward(self, x):
x = torch.flatten(x, start_dim=1)
x = torch.relu(self.fc1(x))
x = self.fc2(x)
return x
以上代码中,__init__
方法用于定义模型结构,forward
方法则用于定义模型的前向计算流程。
定义好模型后,可以使用以下代码进行训练:
model = Net()
criterion = torch.nn.CrossEntropyLoss()
optimizer = torch.optim.SGD(model.parameters(), lr=0.01)
for epoch in range(10):
for i, (inputs, labels) in enumerate(train_loader):
optimizer.zero_grad()
outputs = model(inputs)
loss = criterion(outputs, labels)
loss.backward()
optimizer.step()
if i % 100 == 0:
print(f'Epoch: {epoch+1}, Batch: {i+1}, Loss: {loss.item():.4f}')
以上代码中,criterion
和 optimizer
分别表示损失函数和优化算法。在训练过程中,先将梯度清零(optimizer.zero_grad()
),然后计算模型输出和损失(outputs
和 loss
),再调用 backward()
方法计算梯度,最后调用 optimizer.step()
方法更新模型参数。
模型测试
在训练完模型后,可以使用以下代码进行测试:
correct = 0
total = 0
with torch.no_grad():
for inputs, labels in test_loader:
outputs = model(inputs)
_, predicted = torch.max(outputs.data, 1)
total += labels.size(0)
correct += (predicted == labels).sum()
print(f'Accuracy: {100 * correct / total:.2f}%')
以上代码中,torch.no_grad()
表示在测试过程中不需要计算梯度。对于每个测试样本,计算模型输出并取预测结果的最大值(predicted
),然后统计预测正确的样本数量和总样本数量,最后计算准确率。
总结
这篇 Torch 入门教程主要包括以下几个方面:
- Tensor:介绍了 Torch 中最常见的数据结构 Tensor,并介绍 Tensor 的创建、形状、数据类型以及如何在 CPU 和 GPU 上进行计算。
- Autograd:介绍了 Torch 中的自动求导引擎 Autograd,并介绍了如何创建可求导的 Tensor,以及如何使用
backward()
方法计算梯度。 - Optimizer:介绍了 Torch 中的优化器,包括如何定义优化器,如何在训练循环中使用优化器。
- 模型定义:介绍了如何继承
torch.nn.Module
类来定义深度学习模型,在__init__()
方法中定义网络结构,在forward()
方法中定义前向计算流程。 - 模型训练:介绍了如何训练深度学习模型,包括定义损失函数和优化器,调用前向传播、反向传播函数,以及如何使用优化器更新模型参数。
- 模型保存和加载:介绍了如何将训练好的模型保存到文件,并在之后的使用中加载模型以进行预测。
- 模型评估:介绍了如何使用训练好的模型计算测试集的准确率。
总的来说,本教程是一个完整的 Torch 入门教程,涵盖了从数据载入到模型定义、训练和评估的整个流程,对于希望学习深度学习和 Torch 框架的初学者来说,是一个很好的起点。