阅读论文(1)AlexNet:ImageNet classification with deep convolutional neural networks

Alexnet卷积神经网络模型

重叠池化(overlapping pooling)

传统不重叠的池化层,步长s与窗口尺寸z是相同的,s = z。而重叠池化步长s小于窗口尺寸z,s < z。

image-20230131150906800

局部响应归一化

参考:https://zhuanlan.zhihu.com/p/434773836

https://blog.csdn.net/yangdashi888/article/details/77918311

Local Response Normalization,LRN

LRN是在卷积和池化后进行的操作,对局部神经元的活动创建竞争机制,使得其中响应比较大的值变得相对更大,并抑制其他反馈较小的神经元,增强了模型的泛化能力

LRN在之后很少使用,被更为优秀的BN(batch normalization)取代了

论文中Alex net使用的LRN参数为k = 2, n = 5, α = 10-4, and β = 0.75

架构

总体架构

architecture,共8层,5层卷积加3层池化

模型在channel维度上分成两部分是为了使用两块GPU 并行运算,论文中使用的GTX 580 3GB memory

image-20230131212805227

注:

  • 输入图片为227x227x3,上图中有误
  • 图中卷积层数据是经过卷积的输出结果,省略了池化层

分析

对其模型进行分析如下

纠正:前两个卷积层激活之后先是局部响应归一化(LRN)然后才是最大池化,下图中表示有误

image-20230131212736170

image-20230201135806777

以第一个卷积层为例进行分析,其余各卷积层分析同理

输入图片:227x227x3

conv1:96个卷积核,f = 11x11, s = 4, p = 0,根据公式计算得经过conv1卷积输出:55x55x96

image-20230114144515641

maxpool1:f = 3x3, s = 2(重叠池化),同样根据上述公式经过maxpool1池化输出:27x27x96

防止过拟合的策略

数据增强

Data Augmentation,将原始数据进行变换处理,相当于扩充了训练集,具体分为两种方式

  1. 将图片进行平移、反转变换,或者只取图片的部分(训练输入图片大小不变)
  2. 改变图片的RGB

Dropout

参考:丢弃法 - 李沐_哔哩哔哩_bilibili

相当于一个L2正则项,在隐藏层中间加入噪声,提高模型鲁棒性,用来降低过拟合的。在前向传播过程中,前一个层计算并激活之后,进行一次dropout处理,以 p 的概率将输出置为0,具体公式如下

image-20230202092507141

此公式保证了h'的期望仍为h

image-20230202092721057

另一种理解:dropout的巧妙之处在于,相当于在一个模型的训练过程中,综合考虑了多个模型,对于每一个输入,都是不同的神经网络模型。后来又有论文解释这种理解是不合适的,仅仅把dropout当作是一个正则项就好了。

注意

  • 只在训练过程中使用
  • 应用在多层前馈神经网络隐藏层输出上(多层感知机),也就是cnn中的全连接层
  • 丢弃法将输出项随机置为0来控制模型复杂性
  • 丢弃概率p为控制模型复杂性的超参数

模型复现

使用pytorch复现Alexnet

数据集

ImageNet:15000000个高分辨率图像,属于22000个类别

ILSVRC:ImageNet Large-Scale Visual Recognition Challenge,该竞赛使用ImageNet数据集的子集,每个类别1000个图像

神经网络搭建

注意:

  • 非线性处理紧跟在卷积层之后
  • 局部响应归一化LRN跟在非线性处理后,再然后是最大池化,LRN已经不用了(BN替代),可以不用理解学习
from torch import nn
import torch


class Net(nn.Module):
    def __init__(self):
        super(Net, self).__init__()
        self.model = nn.Sequential(
            nn.Conv2d(3, 96, kernel_size=11, stride=4), nn.ReLU(),
            nn.LocalResponseNorm(size=5, k=2),
            nn.MaxPool2d(kernel_size=3, stride=2),
            nn.Conv2d(96, 256, kernel_size=5, stride=1, padding=2), nn.ReLU(),
            nn.LocalResponseNorm(size=5, k=2),
            nn.MaxPool2d(kernel_size=3, stride=2),
            nn.Conv2d(256, 384, kernel_size=3, stride=1, padding=1), nn.ReLU(),
            nn.Conv2d(384, 384, kernel_size=3, stride=1, padding=1), nn.ReLU(),
            nn.Conv2d(384, 256, kernel_size=3, stride=1, padding=1), nn.ReLU(),
            nn.MaxPool2d(kernel_size=3, stride=2),
            nn.Flatten(),
            nn.Linear(9216, 4096), nn.ReLU(), nn.Dropout2d(p=0.5),
            nn.Linear(4096, 4096), nn.ReLU(), nn.Dropout2d(p=0.5),
            nn.Linear(4096, 1000)
        )

    def forward(self, x):
        x = self.model(x)
        return x

论文中没有提到损失函数怎么定义?

posted @ 2023-02-02 11:57  dctwan  阅读(38)  评论(0编辑  收藏  举报