任务描述
通过本关卡,你将掌握AlexNet的网络结构,并使用pytorch进行网络结构搭建。
相关知识
AlexNet是在2012年由多伦多大学的Alex Krizhevsky等人提出的,其在ImageNet竞赛中以巨大的优势取得了冠军,也因此拉开了深度学习的大幕,在该网络之后,人们逐渐向卷积神经网络和深度学习投入关注,也造就了现在深度学习及CNN的火热。下面我们就一起来认识一下这个网络。
AlexNet的网络结构
AlexNet网络结构继承了LeNet,都是先卷积然后再使用全连接进行结果的预测输出。它的网络结构如下图所示:
图 1-1-1 AlexNet的网络结构图
在上图中,原文作者使用了两片GPU用于网络训练,所以是上下重复的两个部分,我们单看下半部分对网络进行解析:
第一层:卷积层1,输入为 224 × 224 × 3的图像,卷积核的数量为96(输出特征的通道数为96),卷积核的大小为 11 × 11 × 3,步长 stride = 4,填充数pad = 0, 表示不扩充边缘;
第二层:卷积层2, 输入为上一层卷积的feature map, 卷积核的个数为256,卷积核的大小为:5 × 5 × 96, pad = 2, stride = 1; 与第一层不同,该层随后使用了局部响应归一化(LRN), 最后进行 max_pooling, pool_size = (3, 3), stride = 2;
第三层:卷积层3, 输入为第二层的输出,卷积核个数为384, kernel_size = 3 × 3 × 256, padding = 1, 第三层没有做LRN和Pool
第四层:卷积层4, 输入为第三层的输出,卷积核个数为384, kernel_size = 3 × 3 × 384 , padding = 1, 和第三层一样,没有LRN和Pool
第五层:卷积层5, 输入为第四层的输出,卷积核个数为256, kernel_size = 3 × 3 × 384, padding = 1。然后直接进行max_pooling, pool_size = (3, 3), stride = 2;
第六,七,八层是全连接层,每一层的神经元的个数为4096,最终输出softmax为1000,这是因为ImageNet比赛的分类个数为1000。全连接层中使用了RELU和Dropout输出。
综合上面的结构分析来看,AlexNet在使用了卷积和全连接结合的形式外,还使用了一些新的操作加入到网络中,具有以下的一些特点:
- 更深的网络结构
- 使用层叠的卷积层,即卷积层+卷积层+池化层来提取图像的特征
- 使用Dropout抑制过拟合
- 使用Relu替换之前的sigmoid的作为激活函数`
Pytorch搭建AlexNet
编程要求
根据提示,在右侧编辑器补充代码,完成网络的搭建。
测试说明
平台会对你编写的代码进行测试:
开始你的任务吧,祝你成功!
任务代码如下:
import torch
from torch import nn
class AlexNet(nn.Module):
def __init__(self):
super(AlexNet, self).__init__()
'''
这里搭建卷积层,需要按顺序定义卷积层、
激活函数、最大池化层、卷积层、激活函数、
最大池化层、卷积层、激活函数、卷积层、
激活函数、卷积层、激活函数、最大池化层,
具体形状见测试说明
'''
self.conv = nn.Sequential(
########## Begin ##########
nn.Conv2d(3, 96, kernel_size=(11, 11), stride=(4, 4)),
nn.ReLU(),
nn.MaxPool2d(kernel_size=3, stride=2, padding=0, dilation=1, ceil_mode=False),
nn.Conv2d(96, 256, kernel_size=(5, 5), stride=(1, 1), padding=(2, 2)),
nn.ReLU(),
nn.MaxPool2d(kernel_size=3, stride=2, padding=0, dilation=1, ceil_mode=False),
nn.Conv2d(256, 384, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)),
nn.ReLU(),
nn.Conv2d(384, 384, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)),
nn.ReLU(),
nn.Conv2d(384, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)),
nn.ReLU(),
nn.MaxPool2d(kernel_size=3, stride=2, padding=0, dilation=1, ceil_mode=False),
########## End ##########
)
'''
这里搭建全连接层,需要按顺序定义
全连接层、激活函数、丢弃法、
全连接层、激活函数、丢弃法、全连接层,
具体形状见测试说明
'''
self.fc = nn.Sequential(
########## Begin ##########
nn.Linear(in_features=6400, out_features=4096, bias=True),
nn.ReLU(),
nn.Dropout(p=0.5),
nn.Linear(in_features=4096, out_features=4096, bias=True),
nn.ReLU(),
nn.Dropout(p=0.5),
nn.Linear(in_features=4096, out_features=1000, bias=True),
########## End ##########
)
def forward(self, img):
'''
这里需要定义前向计算
'''
########## Begin ##########
feature = self.conv(img) # 卷积层
output = self.fc(feature.view(img.shape[0], -1)) # 全连接层
return output
########## End ##########
model = AlexNet()
print(model)