【CNN】LeNet——卷积神经网络的开山鼻祖

前言

LeNet-5诞生于1994年,是最早的卷积神经网络之一, 由Yann LeCun完成,推动了深度学习领域的发展。在那时候,没有GPU帮助训练模型,甚至CPU的速度也很慢,因此,LeNet5通过巧妙的设计,利用卷积、参数共享、池化等操作提取特征,避免了大量的计算成本,最后再使用全连接神经网络进行分类识别,这个网络也是最近大量神经网络架构的起点,给这个领域带来了许多灵感。

一、LeNet介绍

LeNet-5卷积神经网络的结构组成为也很简单:两个卷积层convolutions,附带两次下采样(通过池化方法实现),和三个全连接层,如下图所示:
【CNN】LeNet——卷积神经网络的开山鼻祖_第1张图片
其中,卷积层和池化层负责对原始图像进行特征提取,全连接层负责对卷积池化提取到的特征进行学习,进一步根据这些特征来判断该输入图片属于哪一个类别。

二、卷积,池化和全连接层在pytorch深度学习框架中对应的API

下面重点在于代码实现。

2.1 卷积操作在pytorch中的API

卷积操作在pytorch中被封装成一个名称为torch.nn.Conv2d的类,具体如下图所示:
【CNN】LeNet——卷积神经网络的开山鼻祖_第2张图片
其中,类的参数解释如下:

(1)in_channels (int) - 输入图像中的通道数

(2)out_channels (int) - 由卷积产生的通道数

(3)kernel_size (int or tuple) - 卷积核的大小

(4)stride (int or tuple, optional) - 卷积的步长。默认值:1

(5)padding (int, tuple or str, optional) - 在输入的四边都加上padding。默认值:0

(6)padding_mode (string, optional) - padding的模式,可选参数有’zeros’, ‘reflect’, ‘replicate’ or ‘circular’. 分别代表’零填充’、‘镜像填充’、‘复制填充’,‘循环填充’。 默认值为:‘零填充’。

(7)dilation (int or tuple, optional) - 卷积核中元素之间的间距,对应卷积变体之扩张卷积。默认值:1

(8)groups (int, optional) - 从输入通道到输出通道的阻塞连接的数量,对应卷积变体之组卷积。默认值:1

(9)bias (bool, optional) - 如果为真,给输出增加一个可学习的偏置。默认值为真

2.2 最大池化操作在pytorch中的API

池化操作在pytorch中被封装成一个名称为torch.nn.MaxPool2d的类,具体如下图所示:
【CNN】LeNet——卷积神经网络的开山鼻祖_第3张图片
其中,类的参数解释如下:

(1)kernel_size - 池化核的大小。

(2)stride - 池化的步长。默认值是kernel_size

(3)padding - 在输入的四边都加上padding。 隐含的零填充,在两边添加。

(4)dilation - 池化核中元素之间的间距, 默认值:1

(5)return_indices - 如果为真,将与输出一起返回最大索引。对以后的 torch.nn.MaxUnpool2d 有用。

(6)ceil_mode - 如果为真,将使用ceil而不是floor来计算输出形状。

2.3 全连接神经网络层在pytorch中的API

全连接神经网络层在pytorch中被封装成一个名称为torch.nn.Linear的类,具体如下图所示:
【CNN】LeNet——卷积神经网络的开山鼻祖_第4张图片
其中,类的参数解释如下:

(1)in_features - 每个输入样本的大小

(2)out_features - 每个输出样本的大小

(3)bias - 如果设置为False,该层将不学习加性偏置。默认值。为真

2.4激活函数ReLU在pytorch中的API

常见的激活函数ReLU在pytorch中被封装成一个名称为torch.nn.ReLU的类,具体如下图所示:
【CNN】LeNet——卷积神经网络的开山鼻祖_第5张图片
其中,参数一般习惯指定为Ture,当为Ture时,ReLU的计算在底层会节省一下计算和存储资源。

三、使用pytorch搭建LeNet卷积模型

代码详细如下,代码中已给出详细注释:

import torch.nn as nn
import torch
 
class Model(nn.Module):
	#函数init定义的模型层级结构
    def __init__(self):
        super().__init__()
        #第一次卷积
        self.conv1 = nn.Conv2d(1, 6, 5)
        self.relu1 = nn.ReLU()
        #第一次池化
        self.pool1 = nn.MaxPool2d(2)
        #第二次卷积
        self.conv2 = nn.Conv2d(6, 16, 5)
        self.relu2 = nn.ReLU()
        #第二次池化
        self.pool2 = nn.MaxPool2d(2)
        #第一次全连接
        self.fc1 = nn.Linear(256, 120)
        self.relu3 = nn.ReLU()
        #第二次全连接
        self.fc2 = nn.Linear(120, 84)
        self.relu4 = nn.ReLU()
        #第三次全连接
        self.fc3 = nn.Linear(84, 10)
        self.relu5 = nn.ReLU()
	
 
 	#函数forward定义的模型的前向计算过程,其中参数x代表输入图像。
 	#下述过程表示图像x先经过第一次卷积conv1得到结果y在送入激活函数,得到新的结果y在送入第二层卷积,以此类推。
    def forward(self, x):
        y = self.conv1(x)
        y = self.relu1(y)
        y = self.pool1(y)
        y = self.conv2(y)
        y = self.relu2(y)
        y = self.pool2(y)
        #这里是打平操作(Flatten)
        y = y.view(y.shape[0], -1)
        y = self.fc1(y)
        y = self.relu3(y)
        y = self.fc2(y)
        y = self.relu4(y)
        y = self.fc3(y)
        y = self.relu5(y)
        return y

你可能感兴趣的:(CNN,cnn,深度学习,神经网络)