学习AlexNet(网络讲解+代码)

AlexNet

(新手入门,如理解有误感谢指正)
论文地址
AlexNet是2012年ILSVRC的第一名
它的整体框架如图1所示:
图1

图1

首先整体概括一下AlexNet主要用到的一些技术方法:

  1. 使用ReLU作为非线性激活函数而非以往的sigmoid或tanh
  2. 采用了模型并行,将网络按照feature maps的深度一分为二放在两个GPU上训练
  3. 使用了Local Response Normalization(LRN)局部归一化
  4. 使用了重叠的池化层
  5. 防止过拟合采用了数据增强(Data Augmentation)丢弃法(Dropout)

总共8层网络5层是卷积层,3层是全连接层,下面就按照图1逐层分析一下

卷积层特征图输出尺寸计算公式:
M = N − F + 2 P S + 1 M = \frac{N-F+2P}{S} + 1 M=SNF+2P+1
其中N是输入的尺寸,即 N × N N\times N N×N的输入,F是卷积核的尺寸,即 F × F F\times F F×F的卷积核,P是padding,S是stride步长

Input:

3 × 224 × 224 3\times 224\times 224 3×224×224的图片(C, H, W)

第一层:

1. 卷积层

卷积核个数96个

卷积核尺寸 3 × 11 × 11 3\times 11\times 11 3×11×11

步长S为4

无padding

输出feature maps的尺寸根据公式 224 − 11 + 0 4 + 1 ≈ 55 \frac{224-11+0}{4}+1\approx 55 422411+0+155,所以最终的尺寸应为 96 × 55 × 55 96\times 55 \times 55 96×55×55

由于使用模型并行,这里按照深度一份为二,放在两个GPU上训练,那么每个GPU上的输出feature maps的尺寸为 96 2 × 55 × 55 = 48 × 55 × 55 \frac{96}{2}\times55\times55 = 48\times55\times 55 296×55×55=48×55×55

图2
图2

2. ReLU

经过ReLU进行激活
f ( x ) = m a x ( 0 , x ) f(x) = max(0, x) f(x)=max(0,x)
论文实验表明使用ReLU模型收敛更快
图3

图3

3. Max Pooling

采样核的尺寸是 3 × 3 3\times3 3×3

论文采用重叠Pooling,使用步长S为2

这样采样后的feature maps尺寸根据公式 55 − 3 + 0 2 + 1 = 27 \frac{55-3+0}{2}+1=27 2553+0+1=27,由于这一步操作是在各个GPU上独立操作,所以每个GPU上输出的feature maps尺寸均为 48 × 27 × 27 48\times27\times27 48×27×27

4. LRN归一化

采用下面这个公式进行归一化
在这里插入图片描述
简单来说就是上一步经过池化层后得到了feature maps,每个深度每个位置的值用 a x , y i a_{x,y}^i ax,yi表示,也就是i深度(x, y)位置的值,然后经过公式处理,这个位置的值 a x , y i a_{x,y}^i ax,yi变成了 b x , y i b_{x,y}^i bx,yi

我们具体看一下过程是怎样的, k , α , β , n k, \alpha, \beta, n k,α,β,n是常数,是需要调的超参数,i,j就代表深度,n就是相邻的n个深度,N是总的深度
图4
图4

所以要计算 a x , y i a_{x,y}^i ax,yi的归一化值实际上就是先把和它挨着的若干个深度相同位置的值(蓝色方格)求个平方加起来乘一个系数 α \alpha α再加一个系数k,再求 β \beta β次方,最后用 a x , y i a_{x,y}^i ax,yi除以算出的这个数

最终论文中选取 k = 2 , n = 5 , α = 1 0 − 4 , β = 0.75 k=2, n=5, \alpha=10^{-4}, \beta=0.75 k=2,n=5,α=104,β=0.75

第二层:

1.卷积层

卷积核个数 256

卷积核尺寸 48 × 5 × 5 48\times5\times5 48×5×5

padding为2,步长S为1

这一层依然是再各个GPU上独立运算,所以256个卷积核实际分成了两部分,每个GPU上各128个卷积核

这样两个GPU上输出的feature maps尺寸为 27 − 5 + 2 × 2 1 + 1 = 27 \frac{27-5+2\times2}{1}+1=27 1275+2×2+1=27,注意上一层最后经过max pooling后的尺寸是 48 × 27 × 27 48\times27\times27 48×27×27,这样输出的尺寸每个GPU上均为 128 × 27 × 27 128\times27\times27 128×27×27
图5
图5

2. ReLU
3. Max Pooling

采样核的尺寸是 3 × 3 3\times3 3×3

论文采用重叠Pooling,使用步长S为2

这样采样后的feature maps尺寸根据公式 27 − 3 + 0 2 + 1 = 13 \frac{27-3+0}{2}+1=13 2273+0+1=13,由于这一步操作是在各个GPU上独立操作,所以每个GPU上输出的feature maps尺寸均为 128 × 13 × 13 128\times13\times13 128×13×13

4. LRN归一化

尺寸不变

第三层:

第三层比较有意思,前两层都是在各自GPU上单独运算,第三层则在两个GPU之间进行了运算,即进行了信息的交互

1. 卷积层

卷积核个数384

卷积核尺寸 256 × 3 × 3 256\times 3\times 3 256×3×3

步长S为1,padding为1

图6
图6

如图6我们可以知道,每个卷积核的深度256实际上是相当于把上一层两个GPU上的 128 × 13 × 13 128\times13\times13 128×13×13合在一起了,即 256 × 13 × 13 256\times13\times13 256×13×13的输入,为啥是13,图上是27,别忘了上一层经过max pooling了

这样我们计算输出feature maps的尺寸 13 − 3 + 2 1 + 1 = 13 \frac{13-3+2}{1}+1=13 1133+2+1=13,所以输出的尺寸为 384 × 13 × 13 384\times13\times13 384×13×13,然后我们再按照深度一分为二放到两个GPU,每个GPU的输出feature maps尺寸就变成图上的 192 × 13 × 13 192\times13\times13 192×13×13

2. ReLU

ReLU激活

第四层:

第四层和第一第二层一样,也是单独再各自GPU上独立运算

1. 卷积层

卷积核个数384,每个GPU上192个

卷积核尺寸 192 × 3 × 3 192\times3\times3 192×3×3

padding为1,步长S为1

输出尺寸 13 − 3 + 2 1 + 1 = 13 \frac{13-3+2}{1}+1=13 1133+2+1=13,每个GPU上的feature maps尺寸仍为 384 2 × 13 × 13 = 192 × 3 × 3 \frac{384}{2}\times13\times13=192\times3\times3 2384×13×13=192×3×3

2. ReLU

ReLU激活
图7
图7

第五层:

1. 卷积层

卷积核个数256,每个GPU上128个

卷积核尺寸 192 × 3 × 3 192\times3\times3 192×3×3

步长padding均为1

输出尺寸 13 − 3 + 2 1 + 1 = 13 \frac{13-3+2}{1}+1=13 1133+2+1=13,每个GPU上的输出feature maps尺寸为 128 × 13 × 13 128\times13\times13 128×13×13

2. ReLU

ReLU激活
图8
图8

3. Max Pooling

采样核的尺寸是 3 × 3 3\times3 3×3

论文采用重叠Pooling,使用步长S为2

这样采样后的feature maps尺寸根据公式 13 − 3 + 0 2 + 1 = 6 \frac{13-3+0}{2}+1=6 2133+0+1=6,由于这一步操作是在各个GPU上独立操作,所以每个GPU上输出的feature maps尺寸均为 128 × 6 × 6 128\times6\times6 128×6×6,总共是 256 × 6 × 6 256\times6\times6 256×6×6

第六层:

从这一层开始到最后均为全连接层,从这里开始不再是每个GPU上单独运算,GPU之间也会进行全连接

1. 全连接层

共4096个神经元,每个GPU上2048个,和上一层 256 × 6 × 6 256\times6\times6 256×6×6个节点全连接

2. ReLU
3. Dropout

简单理解就是随机将激活后的节点输出值置为0,这样这些节点在本轮训练中将不再参与后面的前向传播和梯度回传,这样使得输出值不会严重依赖于某些节点和权重,使得学习更加均衡,避免过拟合

第七层:

1. 全连接层

共4096个神经元,每个GPU上2048个,和上一层4096个节点全连接

2. ReLU
3. Dropout

第八层:

1. 全连接层

共1000个神经元,即1000个输出,和上一层4096个节点全连接

2. softmax

计算预测类别的概率分布

图9
图9

下面使用pytorch实现一个简化的AlexNet,代码来源于李沐的动手学习深度学习的pytorch开源版本

该版本的AlexNet没有使用LRN归一化,在2015年Very Deep Convolutional Networks for Large-Scale Image Recognition. 这篇文章中提到LRN基本没什么用
图10图10

PyTorch Code:

import time
import torch
from torch import nn, optim
import torchvision

device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')

class AlexNet(nn.Module):
    def __init__(self):
        super(AlexNet, self).__init__()
        self.conv = nn.Sequential(
            # 这里不再使用模型并行将网络按照深度拆分,而是一个整体
            # 第一层
            nn.Conv2d(1, 96, 11, 4),  # in_channels, out_channels, kernel_size, stride, padding
            nn.ReLU(),
            nn.MaxPool2d(3, 2),  # kernel_size, stride
            # 第二层
            nn.Conv2d(96, 256, 5, 1, 2),
            nn.ReLU(),
            nn.MaxPool2d(3, 2),
            # 第三层
            nn.Conv2d(256, 384, 3, 1, 1),
            nn.ReLU(),
            # 第四层
            nn.Conv2d(384, 384, 3, 1, 1),
            nn.ReLU(),
            # 第五层
            nn.Conv2d(384, 256, 3, 1, 1),
            nn.ReLU(),
            nn.MaxPool2d(3, 2),
        )
        # 全连接层
        self.fc = nn.Sequential(
            # 根据上面的讲解这里按照论文中的应该是256*6*6
            # 但是我们在看论文中会发现第一层的卷积层计算出的尺寸实际上是54.25不能整除
            # 论文按55计算了,所以到了最后是256*6*6
            # 而pytorch应该是向下取整了,这里如果写256*6*6会出现size mismatch错误
            nn.Linear(256*5*5, 4096),
            nn.ReLU(),
            nn.Dropout(0.5),
            nn.Linear(4096, 4096),
            nn.ReLU(),
            nn.Dropout(0.5),
             # 输出层。由于这里使用Fashion-MNIST,所以用类别数为10,而非论文中的1000
            nn.Linear(4096, 10),
        )
        
    def forward(self, img):
        feature = self.conv(img)
        print(feature.shape)
        output = self.fc(feature.view(img.shape[0], -1))
        return output
  • 2
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值