AlexNet 是一种深度卷积神经网络,由 Alex Krizhevsky、Ilya Sutskever 和 Geoffrey Hinton 于 2012 年提出。它是在 ImageNet Large Scale Visual Recognition Challenge 比赛中获得突破性成绩的模型,标记着深度学习在计算机视觉畛域的锋芒毕露。
以下是 AlexNet 的一些次要特点和奉献:
- 深度架构:AlexNet 是第一个引入多个卷积层和池化层的深度神经网络,共有 8 层变换层(5 个卷积层和 3 个全连贯层)。
- ReLU 激活函数:AlexNet 采纳了修改线性单元(Rectified Linear Unit,ReLU)作为激活函数,这对于训练深层神经网络具备重要意义,因为它可能无效地缓解梯度隐没问题。
- 部分响应归一化(Local Response Normalization):AlexNet 引入了一种部分响应归一化层,目标是加强神经元的克制成果,进步模型的泛化能力。
- Dropout:为了加重过拟合问题,AlexNet 在全连贯层引入了 Dropout 技术,即在训练过程中随机抛弃一些神经元,以促使网络更具鲁棒性。
- 数据加强:AlexNet 在训练阶段采纳了数据加强策略,如随机裁剪、程度翻转等。
- 并行计算:AlexNet 在训练时利用了两块 GPU 进行并行计算,这在过后是一种翻新,有助于放慢训练速度。
- 在 ImageNet 比赛中的问题:AlexNet 在 2012 年的 ILSVRC 比赛中获得了惊人的问题,将前一年获胜模型的错误率从 25% 升高到了约 16%。
AlexNet 的胜利标记着深度学习在计算机视觉畛域的振兴,其架构和训练技巧为后续更深层次的神经网络提供了根底和启发,也为深度学习的广泛应用奠定了根底。
本次训练采纳炼丹侠平台 A100 服务器,比照了 GPU 版本的训练代码和 CPU 版本的训练代码,胜利复现了 AlexNet 训练 MNIST 数据集,AlexNet 训练残缺代码如下:
GPU 版本:
import torch
import torch.nn as nn
import torch.optim as optim
import torchvision
import torchvision.transforms as transforms
from torchvision.datasets import MNIST
from torch.utils.data import DataLoader
# 定义简化版的 AlexNet 模型
class AlexNet(nn.Module):
def __init__(self, num_classes=10):
super(AlexNet, self).__init__()
self.features = nn.Sequential(nn.Conv2d(1, 64, kernel_size=11, stride=4, padding=2),
nn.ReLU(inplace=True),
nn.MaxPool2d(kernel_size=3, stride=2),
nn.Conv2d(64, 192, kernel_size=5, padding=2),
nn.ReLU(inplace=True),
nn.MaxPool2d(kernel_size=3, stride=2),
)
self.classifier = nn.Sequential(nn.Linear(192 * 5 * 5, 256),
nn.ReLU(inplace=True),
nn.Dropout(),
nn.Linear(256, 128),
nn.ReLU(inplace=True),
nn.Dropout(),
nn.Linear(128, num_classes),
)
def forward(self, x):
x = self.features(x)
x = torch.flatten(x, 1)
x = self.classifier(x)
return x
# 数据预处理和加载器
transform = transforms.Compose([transforms.Resize((224, 224)),
transforms.ToTensor(),])
train_dataset = MNIST(root='./data', train=True, transform=transform, download=True)
train_loader = DataLoader(train_dataset, batch_size=64, shuffle=True)
# 初始化模型、损失函数和优化器,并将它们挪动到 GPU 上
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
model = AlexNet(num_classes=10).to(device)
criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(model.parameters(), lr=0.01, momentum=0.9)
# 训练模型
num_epochs = 10
for epoch in range(num_epochs):
running_loss = 0.0
for inputs, labels in train_loader:
inputs, labels = inputs.to(device), labels.to(device)
optimizer.zero_grad()
outputs = model(inputs)
loss = criterion(outputs, labels)
loss.backward()
optimizer.step()
running_loss += loss.item()
print(f'Epoch [{epoch+1}/{num_epochs}], Loss: {running_loss / len(train_loader):.4f}')
print('Finished Training')
CPU 版本:
import torch
import torch.nn as nn
import torch.optim as optim
import torchvision
import torchvision.transforms as transforms
from torchvision.datasets import MNIST
from torch.utils.data import DataLoader
# 定义简化版的 AlexNet 模型
class AlexNet(nn.Module):
def __init__(self, num_classes=10):
super(AlexNet, self).__init__()
self.features = nn.Sequential(nn.Conv2d(1, 64, kernel_size=11, stride=4, padding=2),
nn.ReLU(inplace=True),
nn.MaxPool2d(kernel_size=3, stride=2),
nn.Conv2d(64, 192, kernel_size=5, padding=2),
nn.ReLU(inplace=True),
nn.MaxPool2d(kernel_size=3, stride=2),
)
self.classifier = nn.Sequential(nn.Linear(192 * 5 * 5, 256),
nn.ReLU(inplace=True),
nn.Dropout(),
nn.Linear(256, 128),
nn.ReLU(inplace=True),
nn.Dropout(),
nn.Linear(128, num_classes),
)
def forward(self, x):
x = self.features(x)
x = torch.flatten(x, 1)
x = self.classifier(x)
return x
# 定义数据预处理和加载器
transform = transforms.Compose([transforms.Resize((224, 224)),
transforms.ToTensor(),])
train_dataset = MNIST(root='./data', train=True, transform=transform, download=True)
train_loader = DataLoader(train_dataset, batch_size=64, shuffle=True)
# 初始化模型、损失函数和优化器
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
model = AlexNet(num_classes=10).to(device)
criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(model.parameters(), lr=0.01, momentum=0.9)
# 训练模型
num_epochs = 10
for epoch in range(num_epochs):
running_loss = 0.0
for inputs, labels in train_loader:
inputs, labels = inputs.to(device), labels.to(device)
optimizer.zero_grad()
outputs = model(inputs)
loss = criterion(outputs, labels)
loss.backward()
optimizer.step()
running_loss += loss.item()
print(f'Epoch [{epoch+1}/{num_epochs}], Loss: {running_loss / len(train_loader):.4f}')
print('Finished Training')
训练过程如下:
https://www.bilibili.com/video/BV1Rp4y1P7Nt/?vd_source=64fad5…
总结:
在本次试验中,尝试了在不同硬件条件下同时训练 AlexNet 网络,别离应用了 GPU 和 CPU。具体而言,应用了一台配备有 A100 GPU 的服务器,以及一台装备了个别性能的 CPU 的云服务器。
- GPU 版本:
在 A100 服务器上,将 AlexNet 网络配置在 GPU 上进行训练。因为 A100 是一款高性能的 GPU,具备大量的 CUDA 外围和高速显存,它可能高效地进行深度神经网络的训练。这使得模型在训练过程中可能迅速地解决大量计算工作,从而缩短了训练工夫。同时,A100 的并行计算能力和优化算法使得模型收敛更快,减速了训练的整个过程。因而,GPU 版本的 AlexNet 在性能和速度方面表现出色。 - CPU 版本:
在个别性能的 CPU 上,同样进行了 AlexNet 网络的训练。然而,因为 CPU 在解决并行计算时绝对较弱,以及不足 GPU 的高速显存,模型训练的速度绝对较慢。尤其是对于深度神经网络,CPU 的训练工夫会显著缩短。尽管 CPU 版本的训练过程可能更加适宜小规模的数据集和模型,但在大规模的图像分类工作中,它可能体现不佳。
GPU 版本在性能和速度方面具备显著劣势,而 CPU 版本在大规模工作中可能受限于计算能力和训练工夫。