一、AlexNet简介
AlexNet 是一种深度学习模型,由 Alex Krizhevsky 等人在 2012 年提出。它是当时最先进的图像识别模型,并在 ImageNet 大规模计算机视觉挑战赛(ILSVRC)中获得冠军。
二、AlexNet
1.网络架构
( W_1 - k + 2p )/s + 1)= W_2
总共分为
输入层:这一层接受原始图像作为输入
包含3个通道(红色、绿色和蓝色),每个通道的尺寸为227x227像素。
第一层:卷积组
该层中包含了以下操作:卷积—>激活—>池化—>LRN
具体如下:
输入227×227×3
96个卷积核,每个卷积核的大小为11x11,步长为4,无填充。输出55×55×96
.
采用了非恒等映射(non-uniform mapping),使用了ReLU作为激活函数。
采用最大池化,池化核的大小为3x3,步长为2。(步长小于核大小有重叠)输出27×27×96
。
并且使用了局部响应归一化(LRN)来进行正则化local_size=5。输出27×27×96
。
第二层:卷积组
该层中包含了以下操作:卷积—>激活—>池化—>LRN
输入27×27×96
256个卷积核,每个卷积核的大小为5x5,步长为1,填充为2。输出27×27×256
.
采用了非恒等映射(non-uniform mapping),使用了ReLU作为激活函数。
采用最大池化,池化核的大小为3x3,步长为2。(步长小于核大小有重叠)输出13×13×256
。
并且使用了局部响应归一化(LRN)来进行正则化local_size=5。输出13×13×256
。
这些过滤器将输入图像分解为较低层次的特征,如边缘、角点和其他结构。
第三层:卷积组
该层中包含了以下操作:卷积—>激活
输入13×13×256
384个卷积核,每个卷积核的大小为3x3,步长为1,填充为1。输出13×13×384
.
采用了非恒等映射(non-uniform mapping),使用了ReLU作为激活函数。输出13×13×256
。
第四层:卷积组
该层中包含了以下操作:卷积—>激活
输入13×13×384
384个卷积核,每个卷积核的大小为3x3,步长为1,填充为1。输出13×13×384
.
采用了非恒等映射(non-uniform mapping),使用了ReLU作为激活函数。输出13×13×384
。
第五层:卷积组
该层中包含了以下操作:卷积—>激活—>池化
输入13×13×384
256个卷积核,每个卷积核的大小为3x3,步长为1,填充为1。输出13×13×256
.
采用了非恒等映射(non-uniform mapping),使用了ReLU作为激活函数。
采用最大池化,池化核的大小为3x3,步长为2。(步长小于核大小有重叠)输出6×6×256
。
第六层:全连接组
该层中包含了以下操作:全连接—>激活—>退化
输入6×6×256
全连接4096个神经元,输出4096x1
采用了非恒等映射(non-uniform mapping),使用了ReLU作为激活函数。
采用了随机退化(drop out)机制,按照指定的概率,随机暂时关闭神经元。输出4096x1
第七层:全连接组
该层中包含了以下操作:全连接—>激活—>退化
输入4096x1
全连接4096个神经元,输出4096x1
采用了非恒等映射(non-uniform mapping),使用了ReLU作为激活函数。
采用了随机退化(drop out)机制,按照指定的概率,随机暂时关闭神经元。输出4096x1
最后,第八层为输出组
输入4096x1
其中包含了1000个神经元,采用softmat算法用于预测图像所属的类别概率。输出1000x1
部分代码:
import torch
from torch import nn
# Define the input tensor
inputs = torch.placeholder(shape=[None, 3, 224, 224], dtype=torch.float32)
# Define the first convolutional layer
conv1 = nn.Conv2d(in_channels=3, out_channels=96, kernel_size=(11, 11), stride=(4, 4), padding=0)
# Apply ReLU activation function to the output of conv1
x = nn.ReLU(conv1(inputs))
# Define the Local Response Normalization (LRN) layer
lrn = nn.LocalResponseNorm(size=5, alpha=0.0001, beta=0.75, k=2)
# Apply the LRN layer to the output of the first convolutional layer
x = lrn(x)
# Define the second convolutional layer
conv2 = nn.Conv2d(in_channels=96, out_channels=256, kernel_size=(5, 5), stride=(1, 1), padding=2)
# Apply ReLU activation function to the output of conv2
x = nn.ReLU(conv2(x))
2.训练方法与过程
AlexNet使用小批量随机梯度下降(SGD)进行训练。这意味着网络是在小批量数据上训练的,而不是整个数据集,这允许更快的训练和更好的泛化。在PyTorch中,这可以通过定义一个SGD优化器来实现,并在每次训练迭代中使用它来更新网络的权重。
- 定义AlexNet模型并使用随机权重初始化它。
- 定义一个损失函数,如交叉熵损失,来衡量模型在训练数据上的性能。
- 定义一个优化器,如随机梯度下降(SGD),以根据计算的梯度更新模型的权重。
- 循环遍历训练数据集,使用模型对每批数据进行预测,并使用优化器更新权重。
代码实现:
# Define the AlexNet model
model = AlexNet()
# Define the loss function
criterion = nn.CrossEntropyLoss()
# Define the SGD optimizer
optimizer = optim.SGD(model.parameters(), lr=0.001, momentum=0.9)
# Train the model
for epoch in range(num_epochs):
for data, target in train_loader:
# Forward pass
output = model(data)
loss = criterion(output, target)
# Backward pass
optimizer.zero_grad()
loss.backward()
# Update the weights
optimizer.step()
3.结构复现
两种方式复现:
第一种分组实现结构,可以将操作集合成一个模块,专注于搭建网络的模组。
import torch.nn as nn
class AlexNet(nn.Module):
def __init__(self, num_classes=1000):
super(AlexNet, self).__init__()
self.features = nn.Sequential(
nn.Conv2d(3, 96, kernel_size=11, stride=4),
nn.ReLU(inplace=True),
nn.MaxPool2d(kernel_size=3, stride=2),
nn.Conv2d(96, 256, kernel_size=5, padding=2),
nn.ReLU(inplace=True),
nn.MaxPool2d(kernel_size=3, stride=2),
nn.Conv2d(256, 384, kernel_size=3, padding=1),
nn.ReLU(inplace=True),
nn.Conv2d(384, 384, kernel_size=3, padding=1),
nn.ReLU(inplace=True),
nn.Conv2d(384, 256, kernel_size=3, padding=1),
nn.ReLU(inplace=True),
nn.MaxPool2d(kernel_size=3, stride=2),
)
self.features2 = nn.Sequential(
nn.Linear(256*5*5, 4096),
nn.ReLU(inplace=True),
nn.Dropout(0.5),
nn.Linear(4096, 4096),
nn.ReLU(inplace=True),
nn.Dropout(0.5),
nn.Linear(4096, 10),
)
def forward(self, img):
feature = self.conv(img)
output = self.fc(feature.view(img.shape[0], -1))
return output
model = AlexNet()
第二种,分操作实现功能,将各种操作顺序在forward中拼合,不太建议这种方式,比较零散。
import torch.nn as nn
import torchvision.funcation as F
class AlexNet(nn.Module):
def __init__(self):
super(AlexNet, self).__init__()
# Define the convolutional layers
self.conv1 = nn.Conv2d(3, 96, 11, 4, 0)
self.pool1 = nn.MaxPool2d(3, 2, 0)
self.conv2 = nn.Conv2d(96, 256, 5, 1, 2)
self.pool2 = nn.MaxPool2d(3, 2, 0)
self.conv3 = nn.Conv2d(256, 384, 3, 1, 1)
self.conv4 = nn.Conv2d(384, 384, 3, 1, 1)
self.conv5 = nn.Conv2d(384, 256, 3, 1, 1)
self.pool3 = nn.MaxPool2d(3, 2, 0)
# Define the fully-connected layers
self.fc1 = nn.Linear(256 * 6 * 6, 4096)
self.fc2 = nn.Linear(4096, 4096)
self.fc3 = nn.Linear(4096, 1000)
def forward(self, x):
# Perform the forward pass
x = self.pool1(F.relu(self.conv1(x)))
x = self.pool2(F.relu(self.conv2(x)))
x = self.pool3(self.conv5(self.conv4(self.conv3(x))))
x = self.f3(self.f2(self.f1(x)))
# Define the AlexNet model
model = AlexNet()
对于经典网络,还可以在PyTorch中直接调用实现AlexNet,你可以使用torchvision.model模块,它为常见的架构(如AlexNet)提供预先训练好的模型。
import torch
import torchvision
from torchvision.models import AlexNet
from torch.utils.data import DataLoader
# Define the AlexNet model
model = AlexNet()
# Define the loss function
criterion = torch.nn.CrossEntropyLoss()
# Define the SGD optimizer
optimizer = torch.optim.SGD(model.parameters(), lr=0.001, momentum=0.9)
# Load the training data
train_dataset = torchvision.datasets.ImageFolder(...)
train_loader = DataLoader(train_dataset, batch_size=64, shuffle=True)
# Train the model
for epoch in range(num_epochs):
for data, target in train_loader:
# Forward pass
output = model(data)
loss = criterion(output, target)
# Backward pass
optimizer.zero_grad()
loss.backward()
# Update the weights
optimizer.step()
总结
AlexNet是一种深度卷积神经网络,由Alex Krizhevsky等人于2012年提出。
它是第一个在ImageNet图像识别挑战赛中取得胜利的深度神经网络。
AlexNet使用了大量的卷积层和池化层来提取图像特征。
AlexNet还使用了一些新颖的技术,如局部响应归一化和集成学习等,以帮助模型更好地收敛。
AlexNet 的出现标志着深度学习模型在计算机视觉领域的应用取得了突破性进展,并为今天的深度学习研究提供了重要的基础。