文章目录
- 前言
- 一、AlexNet的特点
- 二、AlexNet的结构
- 三、代码实现及验证
简述AlexNet的特点、结构,并基于Pytorch对AlexNet网络进行代码的实现。
1. Relu函数的使用
具有ReLU函数(实线)的四层卷积神经网络在CIFAR-10上达到25%的训练错误率比具有tanh函数(虚线)的相同网络快6倍,即:大大地提高训练的速度。
2. 双GPU的使用
提高训练速度的同时,降低了错误率。
3. 提出了Local Response Normalization的思想
局部规范化,局部神经元之间产生横向抑制作用,提高精度。
4. 引入Overlapping Pooling
引入重叠层后,抑制过拟合的产生。
The architecture of AlexNet
1—>2:
nn.Conv2d(3, 96, kernel_size=11, stride=4, padding=2),
nn.ReLU(inplace=True),
输入图像为224×224×3;经过卷积核为11×11×3,步长为4,数量为96的卷积操作,输出55×55×96,Relu后的结果仍为55×55×96。
2—>3:
nn.MaxPool2d(3, 2),
nn.Conv2d(96, 256, 5, 1, 2),
nn.ReLU(inplace=True),
经过Maxpool2d,图像数据变为27×27×96;经过卷积核为5×5×96,步长为1,数量为256的卷积操作,输出27×27×256,Relu后的结果仍为27×27×256。
3—>4:
nn.MaxPool2d(3, 2),
nn.Conv2d(256, 384, 3, 1, 1),
nn.Conv2d(384, 384, 3, 1, 1),
经过Maxpool2d,图像数据变为13×13×256;经过卷积核为3×3×256,步长为1,数量为384的卷积操作,输出13×13×384。然后,再经过一次卷积操作,图像数据不变。
4—>5:
nn.Conv2d(384, 256, 3, 1, 1),
nn.ReLU(inplace=True),
nn.MaxPool2d(3, 2)
经过卷积核为3×3×384,步长为1,数量为256的卷积操作,输出13×13×256。然后,经过一个非线性激活和一次最大池化,图像数据变为6×6×256。
5—>6:
nn.Flatten(),
nn.Linear(9216, 4096),
nn.ReLU(inplace=True),
nn.Dropout(),
nn.Linear(4096, 4096),
nn.ReLU(inplace=True),
nn.Dropout(),
nn.Linear(4096, 1000)
对6×6×256进行展平操作,然后进行三次全连接操作,得到1000个特征。
代码实现:
import torch
from torch import nn
class Net(nn.Module):
def __init__(self):
super(Net, self).__init__()
self.features = nn.Sequential(
nn.Conv2d(3, 96, kernel_size=11, stride=4, padding=2),
nn.ReLU(inplace=True),
nn.MaxPool2d(3, 2),
nn.Conv2d(96, 256, 5, 1, 2),
nn.ReLU(inplace=True),
nn.MaxPool2d(3, 2),
nn.Conv2d(256, 384, 3, 1, 1),
nn.Conv2d(384, 384, 3, 1, 1),
nn.Conv2d(384, 256, 3, 1, 1),
nn.ReLU(inplace=True),
nn.MaxPool2d(3, 2)
)
self.avfpool = nn.AdaptiveAvgPool2d((6, 6))
self.classifier = nn.Sequential(
nn.Flatten(),
nn.Linear(9216, 4096),
nn.ReLU(inplace=True),
nn.Dropout(),
nn.Linear(4096, 4096),
nn.ReLU(inplace=True),
nn.Dropout(),
nn.Linear(4096, 1000)
)
def forward(self, x):
x = self.features(x)
x = self.avfpool(x)
x = self.classifier(x)
return x
model = Net()
print(model)
input = torch.ones((64, 3, 224, 224))
output = model(input)
print(output.shape)
验证结果:
Net(
(features): Sequential(
(0): Conv2d(3, 96, kernel_size=(11, 11), stride=(4, 4), padding=(2, 2))
(1): ReLU(inplace=True)
(2): MaxPool2d(kernel_size=3, stride=2, padding=0, dilation=1, ceil_mode=False)
(3): Conv2d(96, 256, kernel_size=(5, 5), stride=(1, 1), padding=(2, 2))
(4): ReLU(inplace=True)
(5): MaxPool2d(kernel_size=3, stride=2, padding=0, dilation=1, ceil_mode=False)
(6): Conv2d(256, 384, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(7): Conv2d(384, 384, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(8): Conv2d(384, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(9): ReLU(inplace=True)
(10): MaxPool2d(kernel_size=3, stride=2, padding=0, dilation=1, ceil_mode=False)
)
(avfpool): AdaptiveAvgPool2d(output_size=(6, 6))
(classifier): Sequential(
(0): Flatten(start_dim=1, end_dim=-1)
(1): Linear(in_features=9216, out_features=4096, bias=True)
(2): ReLU(inplace=True)
(3): Dropout(p=0.5, inplace=False)
(4): Linear(in_features=4096, out_features=4096, bias=True)
(5): ReLU(inplace=True)
(6): Dropout(p=0.5, inplace=False)
(7): Linear(in_features=4096, out_features=1000, bias=True)
)
)
torch.Size([64, 1000])
欢迎交流、沟通、批评、指正!