深度学习经典网络回顾:AlexNet+VGG

一.AlexNet:

虽然深度学习元年是2006年,但是真正使深度学习火起来的是2012年的ImageNet上的AlexNet,由于本人本科毕设有用到该网络模型,虽然后面更优秀的网络模型层出不穷本人再没有使用过该网络,但是该网络的设计对后序网络的设计还是又不可磨灭的影响。首先该网络出自论文:《ImageNet Classification with Deep ConvolutionalNeural Networks》。其中主要贡献有如下几点:

1.从实践中证明了深度神经网络的可行性,确立了多GPU+深度神经网络解决大规模非结构化数据(CV、NLP、语音)问题的工作范式,它得益于现代硬件尤其是GPU的成熟发展,却也反过来激励与AI相关硬件的更高速的发展。

2.激活函数单元创新:引入了ReLU非线性激活函数,对tanh和sigmoid会引起的梯度消失问题有一个很好的解决。

3.引入了Dropout,对过拟合问题有一个很好的解决。

4.引入了正则化层:局部响应正则化(LRN),不过后来被证明并不很work,被各大网络舍弃。btw,后面BN层横空出世。

下面从上述几点分别阐述:

1.网络结构如图所示:

深度学习经典网络回顾:AlexNet+VGG_第1张图片

更直观的观察:

深度学习经典网络回顾:AlexNet+VGG_第2张图片深度学习经典网络回顾:AlexNet+VGG_第3张图片

为什么第一层有96个卷积核,论文原图上画了两个48,后面几层也是这样??因为当时是在两个gpu上跑的。

2.ReLU激活函数:

长这样:深度学习经典网络回顾:AlexNet+VGG_第4张图片简单点就是max(0,x)

优点如下:

(1).不会像sigmoid一样梯度消失。

(2).计算很快。

(3).收敛迅速,比sigmoid/tanh快6倍。

(4).更合理的生物性解释。

简单点为什么sigmoid会梯度消失它不会?ReLU不会梯度消失直观看来梯度为常数,所以当然不会啦。那sigmoid为什么会:因为sigmoid的导数f'(x)=f(x)(1-f(x))值域为(0,1/4),在网络层数过深时经反向传播即(1/4)^n约等于0,因此肯定会梯度消失啦。

3.Dropout:

原理为:Dropout以p的概率将隐层神经元的输出置为0,这些神经元不参与前向传播与反向传播。这样可以减少神经元之间的依赖性,因为从生物的角度上来说,一个神经元不会依赖于其他神经元而存在。借助Dropout,网络可以学到更具有泛化能力的特征。测试时,将所有神经元的输出乘0.5来产生对Dropout的近似,该模型将Dropout机制用于全连接层中。

个人理解:该机制多用于全连接网络,可以将Dropout看作是集成学习的一种,本质解决的是过拟合问题。

温馨提示:实践中多采用“Inverted dropout”,即训练时输出处以概率值p,测试时不变。

4.LRN局部相应归一化,作为被历史舍弃的产物不想再赘述,后来被batch-normal、instance-norm、group-nrom拍死在沙滩上。

最后贴一下pytorch官方实现的alexNet代码(看起来很简单,舍弃掉了LRN层):

class AlexNet(nn.Module):

    def __init__(self, num_classes=1000):
        super(AlexNet, self).__init__()
        self.features = nn.Sequential(
            nn.Conv2d(3, 64, kernel_size=11, stride=4, padding=2),
            nn.ReLU(inplace=True),
            nn.MaxPool2d(kernel_size=3, stride=2),
            nn.Conv2d(64, 192, kernel_size=5, padding=2),
            nn.ReLU(inplace=True),
            nn.MaxPool2d(kernel_size=3, stride=2),
            nn.Conv2d(192, 384, kernel_size=3, padding=1),
            nn.ReLU(inplace=True),
            nn.Conv2d(384, 256, kernel_size=3, padding=1),
            nn.ReLU(inplace=True),
            nn.Conv2d(256, 256, kernel_size=3, padding=1),
            nn.ReLU(inplace=True),
            nn.MaxPool2d(kernel_size=3, stride=2),
        )
        self.classifier = nn.Sequential(
            nn.Dropout(),
            nn.Linear(256 * 6 * 6, 4096),
            nn.ReLU(inplace=True),
            nn.Dropout(),
            nn.Linear(4096, 4096),
            nn.ReLU(inplace=True),
            nn.Linear(4096, num_classes),
        )

    def forward(self, x):
        x = self.features(x)
        x = x.view(x.size(0), 256 * 6 * 6)
        x = self.classifier(x)
        return x

二:VGG:

VGG的思想可以精简为:Small filter,Deeper networks。个人觉得它主要贡献为确立了卷积块单元(block)设计的范式,即网络设计结构的规范化。因为VGG网络看起来就是一个非常结构规范的网络:同一个block内特征图不变,相邻的block之间通过stride为2的max-pooling操作使特征图尺寸减半,其最大的亮点为全网络的卷积核都是3*3的卷积,stride为1,padding为1。网络结构如下图所示:conv3-64表示3*3的卷积核,channel数为64,图中省去了ReLU单元,btw当时batch-norm还没有问世,在batch-norm出现后又出现了好多vgg加bn的版本,其效果要好过原vgg结构。。

深度学习经典网络回顾:AlexNet+VGG_第5张图片

为什么全是3*3的卷积核可以work?

从感受野的角度上说,理论上两个3*3的卷积核堆叠在一起的感受野等同于一个5*5的卷积核,且使用更少的参数量(3*3*2<5*5),同时两层比一层非线性抽象能力更强,拟合能力更强。

最后上代码:

class VGG(nn.Module):

    def __init__(self, features, num_classes=1000, init_weights=True):
        super(VGG, self).__init__()
        self.features = features
        self.classifier = nn.Sequential(
            nn.Linear(512 * 7 * 7, 4096),
            nn.ReLU(True),
            nn.Dropout(),
            nn.Linear(4096, 4096),
            nn.ReLU(True),
            nn.Dropout(),
            nn.Linear(4096, num_classes),
        )
        if init_weights:
            self._initialize_weights()

    def forward(self, x):
        x = self.features(x)
        x = x.view(x.size(0), -1)
        x = self.classifier(x)
        return x

    def _initialize_weights(self):
        for m in self.modules():
            if isinstance(m, nn.Conv2d):
                n = m.kernel_size[0] * m.kernel_size[1] * m.out_channels
                m.weight.data.normal_(0, math.sqrt(2. / n))
                if m.bias is not None:
                    m.bias.data.zero_()
            elif isinstance(m, nn.BatchNorm2d):
                m.weight.data.fill_(1)
                m.bias.data.zero_()
            elif isinstance(m, nn.Linear):
                m.weight.data.normal_(0, 0.01)
                m.bias.data.zero_()


def make_layers(cfg, batch_norm=False):
    layers = []
    in_channels = 3
    for v in cfg:
        if v == 'M':
            layers += [nn.MaxPool2d(kernel_size=2, stride=2)]
        else:
            conv2d = nn.Conv2d(in_channels, v, kernel_size=3, padding=1)
            if batch_norm:
                layers += [conv2d, nn.BatchNorm2d(v), nn.ReLU(inplace=True)]
            else:
                layers += [conv2d, nn.ReLU(inplace=True)]
            in_channels = v
    return nn.Sequential(*layers)


cfg = {
    'A': [64, 'M', 128, 'M', 256, 256, 'M', 512, 512, 'M', 512, 512, 'M'],
    'B': [64, 64, 'M', 128, 128, 'M', 256, 256, 'M', 512, 512, 'M', 512, 512, 'M'],
    'D': [64, 64, 'M', 128, 128, 'M', 256, 256, 256, 'M', 512, 512, 512, 'M', 512, 512, 512, 'M'],
    'E': [64, 64, 'M', 128, 128, 'M', 256, 256, 256, 256, 'M', 512, 512, 512, 512, 'M', 512, 512, 512, 512, 'M'],
}

以上即两个网络的基本结构。

下面来说下对网络的思考和面试中可能会遇到的与本文相关问题:

首先几个面试中的问题:

1.ReLU相比sigmoid的优点,sigmoid为什么会梯度消失?答案如上文所说。

2.深度学习中常用的防止过拟合的手段?

加正则、dropout、数据增强、batchnorm、early stopping、模型集成、加噪声。。

当然以上属于常规操作。面试中也碰到一些让我印象深刻的深层次问题:

春招腾讯实习面试二面:

问:深度学习网络演化规律?答:越来越深,卷积核越来越小。

问:还记得AlexNet的网络结构吗?第一层卷积核多大?

答:9*9。

问:为什么后面卷积核越来越小?

答:按上述感受野和参数量的角度说了下。

问:那以前人们不知道这个道理吗?为什么以前的卷积核设计的那么大?

我:喵喵喵?内心OS:可能以前人们真不知道。憋了半天不会。

面试官说了答案:之前的图像数据清晰度不高,信息量不丰富,比较稀疏。适用于大卷积核,小卷积核反而效果不好,现在图像都是高清,信息量大。

我:好吧,这也可以,你赢了。

当时二面被怼的怀疑人生回去心情沮丧,不过最后竟然给过了也是amazing,后来顺利拿到了实习的offer,还是很开心。

秋招面陌陌时碰到的问题:

1.pooling的反向传播时候是怎么实现的?

2.caffe和tensorflow中的dropout的实现方法不一样,分别是怎么实现的?

喵喵喵?不会不好意思。。后来知道caffe产生一个贝努力分布的vector,用输出乘以这个vector。

还有面试中我记得好几次被问到对batchnorm的理解,可见batchnorm很重要。

对网络结构的思考:之前的网络最后都会连几层很宽的全连接层eg:4096。这样做的不好的地方?(全连接层占了大多数的参数量,造成参数冗余)。ResNet和googleNet舍弃了全连接层,这样做的好处?(输入图像任意尺寸)。

加BN和不加BN对网络输入的要求有何不同?

不加BN层输入图像必须进行归一化,加BN之后可以不进行归一化。

最后说一句:实践出真知,注意细节。Devils in the details。

你可能感兴趣的:(深度学习经典网络回顾:AlexNet+VGG)