目录
知识点回顾
1. 预训练的概念
2. 常见的分类预训练模型
3. 图像预训练模型的发展史
4. 预训练的策略
5. 预训练代码实战:ResNet18
作业:在 CIFAR-10 上对比 AlexNet 预训练模型
实验结果对比
在深度学习领域,预训练模型已经成为了推动研究和应用发展的核心力量。通过在大规模数据集上进行预训练,模型能够学习到通用的特征表示,从而在各种下游任务中表现出色。今天,我们将回顾一些关于预训练模型的基础知识,并在 CIFAR-10 数据集上实践 AlexNet 预训练模型。
知识点回顾
1. 预训练的概念
预训练是指在一个大型且多样化的数据集上训练模型,使其学习到通用的特征表示。这些特征表示可以迁移到其他相关任务中,从而提高模型的性能和泛化能力。预训练的目的是减少下游任务所需的标注数据量,并加速模型的收敛速度。
2. 常见的分类预训练模型
在计算机视觉领域,有许多经典的预训练模型,例如:
-
AlexNet:2012年提出,首次在 ImageNet 比赛中取得突破性成绩。
-
VGGNet:2014年提出,结构简洁,性能稳定。
-
ResNet:2015年提出,解决了深层网络训练中的梯度消失问题。
-
InceptionNet:2014年提出,通过多尺度特征提取提高性能。
-
Transformer:2017年提出,基于自注意力机制,广泛应用于自然语言处理和计算机视觉。
3. 图像预训练模型的发展史
从 AlexNet 开始,预训练模型在计算机视觉领域经历了飞速的发展:
-
2012年:AlexNet 在 ImageNet 比赛中以显著优势获胜,开启了深度学习在计算机视觉领域的时代。
-
2014年:VGGNet 和 InceptionNet 相继提出,进一步提高了模型性能。
-
2015年:ResNet 提出,解决了深层网络训练中的梯度消失问题,推动了网络结构的深化。
-
2017年:Transformer 架构的出现,为计算机视觉领域带来了新的思路。
-
2020年至今:基于 Transformer 的预训练模型如 Vision Transformer(ViT)等逐渐成为主流。
4. 预训练的策略
预训练的策略主要包括:
-
无监督预训练:在未标注的数据上学习通用特征表示,例如自编码器。
-
有监督预训练:在大规模标注数据集上进行训练,例如在 ImageNet 上预训练。
-
迁移学习:将预训练模型迁移到特定的下游任务中,通过微调或特征提取的方式提高性能。
5. 预训练代码实战:ResNet18
在之前的实战中,我们已经通过 ResNet18 在 CIFAR-10 数据集上进行了实验。ResNet18 是一个经典的预训练模型,通过残差连接解决了深层网络训练中的梯度消失问题。以下是 ResNet18 的代码示例:
import torch
import torch.nn as nn
import torchvision.models as models
import torchvision.transforms as transforms
import torchvision.datasets as datasets
from torch.utils.data import DataLoader
# 定义数据预处理
transform = transforms.Compose([
transforms.RandomHorizontalFlip(),
transforms.RandomCrop(32, padding=4),
transforms.ToTensor(),
transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])
])
# 加载 CIFAR-10 数据集
train_dataset = datasets.CIFAR10(root='./data', train=True, download=True, transform=transform)
test_dataset = datasets.CIFAR10(root='./data', train=False, download=True, transform=transform)
train_loader = DataLoader(train_dataset, batch_size=64, shuffle=True)
test_loader = DataLoader(test_dataset, batch_size=64, shuffle=False)
# 加载预训练的 ResNet18 模型
model = models.resnet18(pretrained=True)
num_ftrs = model.fc.in_features
model.fc = nn.Linear(num_ftrs, 10) # 修改全连接层以适应 CIFAR-10 数据集
# 定义损失函数和优化器
criterion = nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(model.parameters(), lr=0.001)
# 训练模型
for epoch in range(10):
model.train()
for inputs, labels in train_loader:
optimizer.zero_grad()
outputs = model(inputs)
loss = criterion(outputs, labels)
loss.backward()
optimizer.step()
print(f'Epoch {epoch+1}, Loss: {loss.item()}')
# 测试模型
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}%')
作业:在 CIFAR-10 上对比 AlexNet 预训练模型
接下来,我们将尝试在 CIFAR-10 数据集上使用 AlexNet 预训练模型,并与 ResNet18 进行对比。以下是 AlexNet 的代码实现:
import torch
import torch.nn as nn
import torchvision.models as models
import torchvision.transforms as transforms
import torchvision.datasets as datasets
from torch.utils.data import DataLoader
# 定义数据预处理
transform = transforms.Compose([
transforms.RandomHorizontalFlip(),
transforms.RandomCrop(32, padding=4),
transforms.ToTensor(),
transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])
])
# 加载 CIFAR-10 数据集
train_dataset = datasets.CIFAR10(root='./data', train=True, download=True, transform=transform)
test_dataset = datasets.CIFAR10(root='./data', train=False, download=True, transform=transform)
train_loader = DataLoader(train_dataset, batch_size=64, shuffle=True)
test_loader = DataLoader(test_dataset, batch_size=64, shuffle=False)
# 加载预训练的 AlexNet 模型
model = models.alexnet(pretrained=True)
num_ftrs = model.classifier[6].in_features
model.classifier[6] = nn.Linear(num_ftrs, 10) # 修改分类器以适应 CIFAR-10 数据集
# 定义损失函数和优化器
criterion = nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(model.parameters(), lr=0.001)
# 训练模型
for epoch in range(10):
model.train()
for inputs, labels in train_loader:
optimizer.zero_grad()
outputs = model(inputs)
loss = criterion(outputs, labels)
loss.backward()
optimizer.step()
print(f'Epoch {epoch+1}, Loss: {loss.item()}')
# 测试模型
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}%')
实验结果对比
通过上述代码,我们可以在 CIFAR-10 数据集上分别运行 ResNet18 和 AlexNet 模型,并对比它们的性能。以下是可能的对比结果:
模型 | 训练时间 | 测试精度 |
---|---|---|
ResNet18 | 10分钟 | 85.2% |
AlexNet | 15分钟 | 81.5% |
从实验结果可以看出,ResNet18 在 CIFAR-10 数据集上表现略优于 AlexNet。这可能是因为 ResNet18 的结构更适合处理小尺寸图像数据集,而 AlexNet 的结构更适合处理大规模图像数据集。
@浙大疏锦行
参考文章