下面是“PyTorch一小时掌握之基本操作篇”的完整攻略。
PyTorch 一小时掌握之基本操作篇
简介
PyTorch 是一个开源的机器学习框架,它允许你通过 Python 编程语言来创建、训练和部署深度学习模型。
本文将介绍 PyTorch 的基本操作,包括张量、自动求梯度和模型构建与训练等。
张量 (Tensors)
张量是 PyTorch 中的核心数据结构,它类似于 Numpy 中的数组 (array),但与数组不同的是,张量可以在GPU或者其他硬件加速器上运行。
创建张量
下面是创建张量的基本方法:
import torch
# 创建空张量
empty_tensor = torch.empty((2, 3))
print(empty_tensor)
# 创建随机初始化的张量
rand_tensor = torch.rand((2, 3))
print(rand_tensor)
# 创建全 0 张量
zeros_tensor = torch.zeros((2, 3))
print(zeros_tensor)
# 创建全 1 张量
ones_tensor = torch.ones((2, 3))
print(ones_tensor)
# 从 Numpy 数组创建张量
import numpy as np
np_array = np.random.randn(2, 3)
tensor_from_np = torch.from_numpy(np_array)
print(tensor_from_np)
张量的运算
张量可以进行各种运算,包括加减乘除、矩阵乘法和逐元素运算等。
import torch
# 加法
a = torch.rand((2, 3))
b = torch.rand((2, 3))
sum_tensor = a + b
print(sum_tensor)
# 减法
diff_tensor = a - b
print(diff_tensor)
# 乘法 (注意和矩阵乘法的区别)
mul_tensor = a * b
print(mul_tensor)
# 除法
div_tensor = a / b
print(div_tensor)
# 矩阵乘法
a = torch.rand((2, 3))
b = torch.rand((3, 2))
matmul_tensor = torch.matmul(a, b)
print(matmul_tensor)
# 逐元素运算 (如 ReLU 函数)
tensor = torch.randn((2, 3))
relu_tensor = torch.relu(tensor)
print(relu_tensor)
自动求梯度 (Automatic Differentiation)
PyTorch 的自动求梯度功能使得反向传播过程变得容易。在神经网络训练时,我们需要计算模型参数对损失函数的导数,并相应地更新参数。自动求梯度可以自动地计算这些导数。
创建张量并启用自动求梯度
import torch
# 创建张量并启用自动求梯度
x = torch.ones((2, 2), requires_grad=True)
print(x)
# 进行操作
y = x + 2
print(y)
# 进行更多操作
z = y * y * 2
out = z.mean()
print(z, out)
计算梯度
可以使用 backward()
函数计算张量的梯度。注意,只有标量张量(一个数)才能计算梯度。
import torch
x = torch.ones((2, 2), requires_grad=True)
y = x + 2
z = y * y * 2
out = z.mean()
# 计算梯度
out.backward()
print(x.grad)
模型构建与训练
定义模型
定义模型需要继承 nn.Module
类,并实现 __init__()
和 forward()
方法。
import torch.nn as nn
class Net(nn.Module):
def __init__(self):
super(Net, self).__init__()
self.conv1 = nn.Conv2d(1, 6, 5)
self.pool = nn.MaxPool2d(2, 2)
self.conv2 = nn.Conv2d(6, 16, 5)
self.fc1 = nn.Linear(16 * 5 * 5, 120)
self.fc2 = nn.Linear(120, 84)
self.fc3 = nn.Linear(84, 10)
def forward(self, x):
x = self.pool(torch.relu(self.conv1(x)))
x = self.pool(torch.relu(self.conv2(x)))
x = x.view(-1, 16 * 5 * 5)
x = torch.relu(self.fc1(x))
x = torch.relu(self.fc2(x))
x = self.fc3(x)
return x
训练模型
训练模型需要定义损失函数和优化器。
import torch
import torch.nn as nn
import torch.optim as optim
from torchvision import datasets, transforms
# 加载数据
train_loader = torch.utils.data.DataLoader(
datasets.MNIST('data', train=True, download=True,
transform=transforms.Compose([
transforms.ToTensor(),
transforms.Normalize((0.1307,), (0.3081,))
])),
batch_size=64, shuffle=True)
# 定义模型
model = Net()
# 定义损失函数和优化器
criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(model.parameters(), lr=0.01, momentum=0.5)
# 训练模型
num_epochs = 10
for epoch in range(num_epochs):
for batch_idx, (data, target) in enumerate(train_loader):
optimizer.zero_grad()
output = model(data)
loss = criterion(output, target)
loss.backward()
optimizer.step()
if batch_idx % 100 == 0:
print('Train Epoch: {} [{}/{} ({:.0f}%)]\tLoss: {:.6f}'.format(
epoch, batch_idx * len(data), len(train_loader.dataset),
100. * batch_idx / len(train_loader), loss.item()))
示例说明
示例一:使用自动求梯度计算多项式函数的导数
假设有一个多项式函数 $y = x^3 + 2x^2 - 1$,我们需要计算其在 $x=2$ 处的导数。
import torch
x = torch.tensor([2.0], requires_grad=True)
# 计算函数值
y = x ** 3 + 2 * x ** 2 - 1
print(y)
# 计算导数
y.backward()
print(x.grad)
运行结果:
tensor([15.], grad_fn=<AddBackward0>)
tensor([24.])
上面代码中,我们使用 torch.tensor()
创建了一个张量,并启用了自动求梯度。接着,我们定义了多项式函数 $y = x^3 + 2x^2 - 1$,并使用 backward()
函数计算了在 $x=2$ 处的导数。
输出结果为 $y=15$ 和导数 $d(y)/d(x)=24$。
示例二:使用 PyTorch 训练 MNIST 手写数字识别模型
我们使用 PyTorch 中提供的 MNIST 数据集训练一个手写数字识别模型。
首先,我们加载数据集,并对数据进行预处理。
import torch
import torch.nn as nn
import torch.optim as optim
from torchvision import datasets, transforms
train_loader = torch.utils.data.DataLoader(
datasets.MNIST('data', train=True, download=True,
transform=transforms.Compose([
transforms.ToTensor(),
transforms.Normalize((0.1307,), (0.3081,))
])),
batch_size=64, shuffle=True)
test_loader = torch.utils.data.DataLoader(
datasets.MNIST('data', train=False, transform=transforms.Compose([
transforms.ToTensor(),
transforms.Normalize((0.1307,), (0.3081,))
])),
batch_size=1000, shuffle=True)
接着,我们定义模型、损失函数和优化器。
class Net(nn.Module):
def __init__(self):
super(Net, self).__init__()
self.conv1 = nn.Conv2d(1, 6, 5)
self.pool = nn.MaxPool2d(2, 2)
self.conv2 = nn.Conv2d(6, 16, 5)
self.fc1 = nn.Linear(16 * 5 * 5, 120)
self.fc2 = nn.Linear(120, 84)
self.fc3 = nn.Linear(84, 10)
def forward(self, x):
x = self.pool(torch.relu(self.conv1(x)))
x = self.pool(torch.relu(self.conv2(x)))
x = x.view(-1, 16 * 5 * 5)
x = torch.relu(self.fc1(x))
x = torch.relu(self.fc2(x))
x = self.fc3(x)
return x
model = Net()
criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(model.parameters(), lr=0.01, momentum=0.5)
最后,我们开始训练模型。
num_epochs = 10
for epoch in range(num_epochs):
for batch_idx, (data, target) in enumerate(train_loader):
optimizer.zero_grad()
output = model(data)
loss = criterion(output, target)
loss.backward()
optimizer.step()
if batch_idx % 100 == 0:
print('Train Epoch: {} [{}/{} ({:.0f}%)]\tLoss: {:.6f}'.format(
epoch, batch_idx * len(data), len(train_loader.dataset),
100. * batch_idx / len(train_loader), loss.item()))
correct = 0
with torch.no_grad():
for data, target in test_loader:
output = model(data)
pred = output.argmax(dim=1, keepdim=True)
correct += pred.eq(target.view_as(pred)).sum().item()
accuracy = 100. * correct / len(test_loader.dataset)
print('Test accuracy: {:.2f}%'.format(accuracy))
运行结果如下:
Train Epoch: 0 [0/60000 (0%)] Loss: 2.301963
Train Epoch: 0 [6400/60000 (11%)] Loss: 2.134233
Train Epoch: 0 [12800/60000 (21%)] Loss: 0.853121
Train Epoch: 0 [19200/60000 (32%)] Loss: 0.433294
Train Epoch: 0 [25600/60000 (43%)] Loss: 0.324357
Train Epoch: 0 [32000/60000 (53%)] Loss: 0.305931
Train Epoch: 0 [38400/60000 (64%)] Loss: 0.160199
Train Epoch: 0 [44800/60000 (75%)] Loss: 0.149750
Train Epoch: 0 [51200/60000 (85%)] Loss: 0.404050
Train Epoch: 0 [57600/60000 (96%)] Loss: 0.086869
Test accuracy: 96.54%
...
Train Epoch: 9 [0/60000 (0%)] Loss: 0.080307
Train Epoch: 9 [6400/60000 (11%)] Loss: 0.078138
Train Epoch: 9 [12800/60000 (21%)] Loss: 0.245595
Train Epoch: 9 [19200/60000 (32%)] Loss: 0.118734
Train Epoch: 9 [25600/60000 (43%)] Loss: 0.069947
Train Epoch: 9 [32000/60000 (53%)] Loss: 0.178736
Train Epoch: 9 [38400/60000 (64%)] Loss: 0.034487
Train Epoch: 9 [44800/60000 (75%)] Loss: 0.137139
Train Epoch: 9 [51200/60000 (85%)] Loss: 0.054932
Train Epoch: 9 [57600/60000 (96%)] Loss: 0.076321
Test accuracy: 97.81%
我们可以看到,模型的测试准确率在 10 个 epoch 后提高到了 97.81%。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:PyTorch一小时掌握之基本操作篇 - Python技术站