AlexNet 神经网络

1. AlexNet 简介

  2006 年,研究人员成功利用 GPU 加速 CNN,相比 CPU 快了 4 倍。2012 年,由谷歌 Hinton 率领的团队提出新的卷积神经网络 AlexNet,在 ImageNet 2012 的图片分类任务上,以 15.3% 的错误率登顶,而且以高出第二名十几个百分点的差距吊打所有其他参与者。论文为《ImageNet Classification with Deep Convolutional Neural Networks》。AlexNet 的出现标志着神经网络的复苏和深度学习的崛起。

  AlexNet 的网络结构跟 LeNet 类似,但使⽤了更多的卷积层和更⼤的参数空间来拟合⼤规模数据集 ImageNet。AlexNet 是浅层神经⽹络和深度神经⽹络的分界线,其网络结构如下

上图分为上下两个部分的网络,分别对应两个 GPU,只有到特定的网络层后才进行两块 GPU 间的交互,这种设置是为了利用两块 GPU 来提高运算的效率,其实两部分网络的结构差异不大。为便于理解,下文便选择一部分的网络 (一块 GPU 上) 进行介绍。单部分的网络结构如下

如上图所示,网络总共 8 层,包含 5 层卷积和 3 层全连接层。有关各层的详细介绍参见下图

  与 LeNet 相比,AlexNet 的卷积/池化操作没有太大变化,不过网络层数有所加深。AlexNet 的主要特点有

  1. 成功使用 ReLU 作为激活函数,成功解决了Sigmoid 在网络较深时的梯度弥散问题。
  2. 使用了数据增强
  3. 使用了小批量随机梯度下降法 (mini-batch SGD)。
  • GPU 上训练,这得益于 2006 年 CNN 在 GPU 上的实现。。
  • 训练时使用 Dropout 随机忽略一部分神经元,以避免模型过拟合。
  • 提出了局部响应归一化 (LRN) 层,对局部神经元的活动创建竞争机制,增强响应较大的神经元,抑制反馈较小的神经元,提高了模型的泛化能力。如今这部分工作多用 BN 替代。
  • 使用重叠的最大池化。此前普遍使用平均池化,而最大池化能够避免平均池化的模糊化效果。此外,AlexNet 提出设置步长小于池化核的尺寸,让池化层的输出之间出现重叠和覆盖,提升特征的丰富性。

2. AlexNet 的 PyTorch 实现

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


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
            # 减小卷积窗口,使用填充为2来使得输入与输出的高和宽一致,且增大输出通道数
            nn.Conv2d(96, 256, 5, 1, 2),
            nn.ReLU(),
            nn.MaxPool2d(3, 2),
            # 连续3个卷积层,且使用更小的卷积窗口。除了最后的卷积层外,进一步增大了输出通道数。
            # 前两个卷积层后不使用池化层来减小输入的高和宽
            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)
        )

         # 这里全连接层的输出个数比LeNet中的大数倍。使用丢弃层来缓解过拟合
        self.fc = nn.Sequential(
            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)
        output = self.fc(feature.view(img.shape[0], -1))
        return output

【参考】

  1. CNN发展简史——AlexNet(二)
  2. 卷积神经网络之Alexnet
  • 0
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是基于MindSpore的带有两个残差模块的AlexNet神经网络的代码: ```python import mindspore.nn as nn import mindspore.ops.operations as P import mindspore.common.dtype as mstype class AlexNet(nn.Cell): def __init__(self, num_classes=10): super(AlexNet, self).__init__() self.conv1 = nn.Conv2d(in_channels=3, out_channels=64, kernel_size=11, stride=4, pad_mode='valid') self.relu1 = nn.ReLU() self.pool1 = nn.MaxPool2d(kernel_size=3, stride=2, pad_mode='valid') self.conv2 = nn.Conv2d(in_channels=64, out_channels=192, kernel_size=5, pad_mode='same') self.relu2 = nn.ReLU() self.pool2 = nn.MaxPool2d(kernel_size=3, stride=2, pad_mode='valid') self.conv3 = nn.Conv2d(in_channels=192, out_channels=384, kernel_size=3, pad_mode='same') self.relu3 = nn.ReLU() self.conv4 = nn.Conv2d(in_channels=384, out_channels=256, kernel_size=3, pad_mode='same') self.relu4 = nn.ReLU() self.conv5 = nn.Conv2d(in_channels=256, out_channels=256, kernel_size=3, pad_mode='same') self.relu5 = nn.ReLU() self.pool5 = nn.MaxPool2d(kernel_size=3, stride=2, pad_mode='valid') self.flatten = nn.Flatten() self.fc1 = nn.Dense(in_channels=6*6*256, out_channels=4096) self.relu6 = nn.ReLU() self.fc2 = nn.Dense(in_channels=4096, out_channels=4096) self.relu7 = nn.ReLU() self.fc3 = nn.Dense(in_channels=4096, out_channels=num_classes) self.softmax = nn.Softmax(axis=1) self.add = P.TensorAdd() def construct(self, x): x = self.pool1(self.relu1(self.conv1(x))) x = self.pool2(self.relu2(self.conv2(x))) x = self.relu3(self.conv3(x)) x = self.relu4(self.conv4(x)) x = self.pool5(self.relu5(self.conv5(x))) x = self.flatten(x) x = self.relu6(self.fc1(x)) x = self.relu7(self.fc2(x)) x = self.fc3(x) x1 = x x = self.fc3(self.relu7(self.fc2(self.relu6(self.fc1(x))))) x = self.add(x, x1) return self.softmax(x) ``` 其中,我们在fc1和fc2之间添加了一个残差模块,在fc2之后再添加一个残差模块。这两个残差模块的实现方式都是使用TensorAdd来实现的。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值