CNN网络模型——AlexNet(网络讲解和代码实现)

CNN网络模型入门——AlexNet(网络讲解和代码实现)


现在的深度学习非常火热,要想入门神经网络,博主就想最初的卷积神经网络AlexNet讲起。作为一名人工智能学生,博主还是要捡一捡以前的知识的😳。AlexNet作为早期的神经网络,虽然现在都不用了,但是意义重大,毕竟 0到1的跨越是开创性的(AlexNet不是最早的,只是比较早而已)。我们从最初的CNN网络AlexNet开始,后续会讲解 反向传播算法的推导和U-Net,如果喜欢的话,可以给博主点个赞哦!💗

1、卷积神经网络(CNN)

卷积层

博主首先了解到卷积是在上《数字信号处理》这一门课上。然而,深度学习上的卷积比《数字信号处理》上的卷积简单多了。我们不要被深度学习的卷积所吓到,它其实就是一个矩形的滤波器,通过移动、相乘、相加对图像进行处理。
在这里插入图片描述

一个卷积层多个滤波器,我们可以把这些滤波器看成我们视网膜上的细胞,对图像一块块的处理。每个细胞感受的区域是不一样的。我们有多少个滤波器,最后就输出多少通道的张量
在这里插入图片描述

不管是卷积层还是池化层,我们都可以看成一种对图片进行特征提取的方法。因为我们不可能对一个图像矩阵的每一个数字看成特征,需要找到一种提取图片特征的方式,否则计算量太大,也不符合我们人类识别图片的方式。

池化层

池化层实际上是一种形式的降采样。我们说,池化层可以通过减少数据维度,提取数据的主要特征,这样既能减少了计算量,也能防止过拟合。最常见的是最大池化。
在这里插入图片描述

非线性激活函数

我们认为,非线性激活函数在神经网络中起着至关重要的作用。非线性激活函数使得神经网络能够学习和表示复杂的非线性关系。如果没有非线性激活函数,多层神经网络将等价于单个线性变换,无法学习复杂的模式和特征。常用的非线性激活函数是ReLu函数

世界不是线性的,是复杂的,不能只用线性去衡量。
在这里插入图片描述

2、AlexNet讲解

这是AlexNet论文的原图,我们会根据这个图片讲解AlexNet的结构。
在这里插入图片描述
AlexNet 的网络结构相对简单直观,主要由卷积层、池化层、全连接层和输出层组成。下面是 AlexNet 的网络结构:

  1. 输入层:AlexNet 的输入层接收图像数据,通常为 RGB 彩色图像,大小为 227x227x3。
  2. 第一个卷积层(Conv1):包含 96 个大小为 11x11x3 的卷积核,步长为 4,使用 ReLU 激活函数。该层的输出尺寸为 55x55x96。
  3. 第一个池化层(Pool1):使用最大池化,池化窗口大小为 3x3,步长为 2。该层的输出尺寸为 27x27x96。
  4. 第二个卷积层(Conv2):包含 256 个大小为 5x5x48 的卷积核(48 是由于之前的池化层有 2 倍的通道数),步长为 1,使用 ReLU 激活函数。该层的输出尺寸为 27x27x256。
  5. 第二个池化层(Pool2):使用最大池化,池化窗口大小为 3x3,步长为 2。该层的输出尺寸为 13x13x256。
  6. 第三个卷积层(Conv3):包含 384 个大小为 3x3x256 的卷积核,步长为 1,使用 ReLU 激活函数。该层的输出尺寸为 13x13x384。
  7. 第四个卷积层(Conv4):包含 384 个大小为 3x3x192 的卷积核,步长为 1,使用 ReLU 激活函数。该层的输出尺寸为 13x13x384。
  8. 第五个卷积层(Conv5):包含 256 个大小为 3x3x192 的卷积核,步长为 1,使用 ReLU 激活函数。该层的输出尺寸为 13x13x256。
  9. 第三个池化层(Pool3):使用最大池化,池化窗口大小为 3x3,步长为 2。该层的输出尺寸为 6x6x256。
  10. 全连接层(FC1):包含 4096 个神经元,使用 ReLU 激活函数。
  11. 全连接层(FC2):包含 4096 个神经元,使用 ReLU 激活函数。
  12. 输出层:包含 1000 个神经元,对应 ImageNet 数据集的 1000 个类别,通常使用 softmax 激活函数进行分类。

3、Pytorch代码实现

代码来源于《动手学深度学习》

import torch
import torch.nn as nn

class AlexNet(nn.Module):
    def __init__(self, num_classes) -> None:
        super(AlexNet, self).__init__()
        self.net = nn.Sequential(
            # 这里使用一个11*11的更大窗口来捕捉对象。
            # 同时,步幅为4,以减少输出的高度和宽度。
            # 另外,输出通道的数目远大于LeNet
            nn.Conv2d(1, 96, kernel_size=11, stride=4, padding=1), nn.ReLU(),
            nn.MaxPool2d(kernel_size=3, stride=2),
            # 减小卷积窗口,使用填充为2来使得输入与输出的高和宽一致,且增大输出通道数
            nn.Conv2d(96, 256, kernel_size=5, padding=2), nn.ReLU(),
            nn.MaxPool2d(kernel_size=3, stride=2),
            # 使用三个连续的卷积层和较小的卷积窗口。
            # 除了最后的卷积层,输出通道的数量进一步增加。
            # 在前两个卷积层之后,汇聚层不用于减少输入的高度和宽度
            nn.Conv2d(256, 384, kernel_size=3, padding=1), nn.ReLU(),
            nn.Conv2d(384, 384, kernel_size=3, padding=1), nn.ReLU(),
            nn.Conv2d(384, 256, kernel_size=3, padding=1), nn.ReLU(),
            nn.MaxPool2d(kernel_size=3, stride=2),
            nn.Flatten(),
            # 这里,全连接层的输出数量是LeNet中的好几倍。使用dropout层来减轻过拟合
            nn.Linear(6400, 4096), nn.ReLU(),
            nn.Dropout(p=0.5),
            nn.Linear(4096, 4096), nn.ReLU(),
            nn.Dropout(p=0.5),
            # 最后是输出层。由于这里使用Fashion-MNIST,所以用类别数为10,而非论文中的1000
            nn.Linear(4096, num_classes))
    def forward(self, x):
        x = self.net(x)
        return x


# rand:返回一个张量,包含了从区间[0, 1)的均匀分布中抽取的一组随机数,此处为四维张量
x = torch.rand([1, 1, 224, 224])
# 模型实例化
model = AlexNet(10)
y = model(x)
print(y.shape)
  • 29
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值