卷积层
概念
卷积层是深度学习中最基础的神经网络层之一,它在图像处理、语音处理、自然语言处理等领域都有广泛应用。卷积层的主要功能是对输入数据进行卷积操作,以提取其中的特征信息。
具体来说,卷积层通过滑动一个固定大小的卷积核(也称为滤波器或过滤器)在输入数据上进行卷积操作,将输入数据的局部特征提取出来并映射到输出特征图上。卷积操作可以看做是一种特殊的加权求和过程,它利用相邻像素之间的相关性来降低数据维度,并使模型更加稳健。
函数
形如:Conv2d(in_channels, out_channels, kernel_size, stride, padding)
- in_channels:输入通道数(与input的通道一致)。
- out_channels:输出通道数(表示经过此卷积后通道数,即有多少个卷积核)。
- kernel_size=N:卷积核尺寸为N*N。
- stride=N:步长为N,每次平移N个单位长度。
- padding=N:在原图基础上下左右都添加N个像素填充。
定义了一个具有in_channels个输入通道、out_channels个输出通道、kernel_size*kernel_size大小的卷积核、步长为stride、padding像素零填充的二维卷积层。
令一个(a, b, c, d)的tensor张量经过该卷积层
- a为样本数量,前后保持不变
- b为通道数,与Conv2d的in_channels相对应,变为Conv2d的out_channels
- c, d为尺寸c * d,变为(c - N(kernel_size) + 1 + 2 * N(padding)) / N(stride) * (d - N(kernel_size) + 1 + 2 * N(padding)) / N(stride)
from torch.nn import Conv2d
import torch
con = Conv2d(3, 10, 5, 1, 1)
tensors = torch.ones((1, 3, 5, 5))
print(tensors.size())
tensors = con(tensors)
print(tensors.size())
# 结果:
# torch.Size([1, 3, 5, 5])
# torch.Size([1, 10, 3, 3])
功能
-
特征提取:卷积层通过应用卷积操作,可以从输入数据中提取出不同尺寸的特征。通过设置不同大小的卷积核,可以捕捉输入数据的局部模式和结构信息。这些特征可以帮助模型更好地理解输入数据,并用于后续的分类、回归或其他任务。
-
参数共享:卷积层具有参数共享的特性,即卷积核在整个输入数据上共享参数。这种共享可以大大减少模型的参数数量,降低过拟合的风险,并提高模型的泛化能力。
-
稀疏连接:与全连接层相比,卷积层采用稀疏连接的方式,只连接输入数据中的局部区域。这种连接方式可以减少计算量,并使模型对输入数据的平移不变性具有一定的鲁棒性。
-
降低维度:通过卷积操作,卷积层可以将输入数据的维度降低。例如,在图像处理任务中,一次卷积操作可以将图像的高度和宽度降低,从而减少后续层的计算复杂度。
-
非线性激活:卷积层通常会在卷积操作后应用非线性激活函数,如ReLU函数。这样可以增加模型的非线性能力,并帮助模型更好地捕捉输入数据的非线性关系。
池化层
概念
池化层是深度学习中常用的一种神经网络层,其主要作用是在卷积神经网络中对特征图进行降采样,以减少模型的计算复杂度和内存占用。池化层可以通过缩小特征图的尺寸来减少模型参数和提高模型的鲁棒性,同时还可以对输入图像的平移、旋转和缩放等变换具有一定的不变性。
池化层通常会对每个特征图的局部区域进行操作,并选择其中的最大值或平均值作为输出。最大池化(Max Pooling)是池化层中最常用的一种方式,它可以从每个局部区域中提取出最显著的特征,同时还可以增加模型的平移不变性和局部不变性。平均池化(Average Pooling)则是将每个局部区域的特征取平均值作为输出,它适用于需要减少特征图大小但又不希望损失太多信息的情况。
函数
形如:MaxPool2d(kernel_size, ceil_mode)
-
kernel_size=N表示池化核大小为N*N。
-
ceil_mode = True表示保留,即当池化核覆盖时超出图像范围时,继续取相交部分最大值。
-
ceil_mode = False表示不保留,即当池化层覆盖范围超过图像范围时,不取值。
import torch
from torch.nn import MaxPool2d
inputs = torch.tensor([[1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12],
[13, 14, 15, 16]], dtype=torch.float32)
# 最大池化层需要接受四维的tensor,而inputs为二维,因此要进行reshape转化为四维
inputs = torch.reshape(inputs, [-1, 1, 4, 4])
mp2 = MaxPool2d(kernel_size=3, ceil_mode=True)
output = mp2(inputs)
print(output)
# 结果
tensor([[[[11., 12.], [15., 16.]]]]) # ceil_mode=True
tensor([[[[11.]]]]) # ceil_mode=False
功能
-
特征提取:最大池化层通过在每个局部区域内选择最大值作为输出,可以有效地提取出最显著的特征。这有助于保留重要的特征信息,减少对噪声和不相关特征的敏感度。
-
平移不变性:最大池化操作具有一定程度的平移不变性,即当输入图像发生平移时,由于选取的是局部区域内的最大值,输出值的位置会随之移动,但最大值的位置仍然保持不变。这有助于模型学习到对目标的位置不敏感的特征。
-
降采样:最大池化层可以将特征图的尺寸缩小,减少参数数量和计算量,同时提高模型的计算效率。通过减小特征图的空间维度,还可以增加模型的感受野,从而更好地捕捉图像中的全局信息。
-
不变性:最大池化层在一定程度上具有旋转、缩放和部分变形等变换的不变性。因为无论输入图像如何变换,最大池化层总是选择局部区域内的最大值作为输出,从而保持一定的不变性。
-
防止过拟合:最大池化层可以帮助减少过拟合,通过丢弃一些非主要特征,降低模型对训练数据的过度拟合,提高模型的泛化能力。
卷积层与池化层交叉使用
卷积层与池化层的交叉使用,对输入的张量进行特征提取,降采样等操作,保留其特性的同时,减少了内存与特征图的空间维度,提高计算效率,避免过拟合。
举个例子,如果将卷积神经网络比作一个人的话,那么卷积层就相当于这个人的眼睛,可以看到周围的事物,并提取其中有用的信息;最大池化层则相当于这个人的大脑,可以将眼睛看到的信息进行加工处理,进一步提取出有用的特征,并缩小输入数据的尺寸。
-
特征提取:卷积层用于提取输入数据的特征,而池化层则可以对特征图进行降采样,保留主要特征的同时减少计算量,加快训练速度。
-
参数共享:卷积层通过参数共享的方式有效地减少了需要学习的参数数量,而池化层可以进一步减小特征图的尺寸,减少模型的复杂度。
-
提高鲁棒性:池化层有助于使特征对于位置的微小变化具有一定的鲁棒性,从而提高模型对输入数据的泛化能力。
-
减少过拟合:池化层的降采样作用有助于减少模型的过拟合风险,同时卷积层的特征提取能力有助于增强模型的泛化能力。
线性层
概念
线性层(Linear Layer),也称为全连接层(Fully Connected Layer)或密集层(Dense Layer),是深度学习神经网络中的一种基本结构。在神经网络中,线性层通常位于卷积层或池化层之后,是用来实现特征提取和非线性映射后的最后一层。
函数
形如:Linear(in_features=N, out_features=M)
in_features=N
表示输入特征的维度为 N。out_features=M
表示输出特征的维度为 M。
import torch
from torch.nn import Flatten, Linear
inputs = torch.tensor([[1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12],
[13, 14, 15, 16]], dtype=torch.float32)
inputs = torch.reshape(inputs, [1, 2, 4, 2])
Fa = Flatten()
Li = Linear(in_features=16, out_features=10)
inputs = Fa(inputs)
output = Li(inputs)
print("inputs:", inputs.size())
print("output:", output.size())
# 运行结果:
# 线性层前后,shape[1, 2, 4, 2]中样本数量(1)保持不变,通道数(2) * height(4) * weight(2) = 16
inputs: torch.Size([1, 16])
output: torch.Size([1, 10])
功能
-
表达能力强: 线性层提供了非常强大的表达能力,能够学习复杂的非线性关系,使得神经网络能够适应各种复杂的数据特征。
-
参数化处理: 通过权重矩阵和偏置项的学习,线性层可以将输入数据进行线性变换,从而实现对数据的高维特征提取和映射。
-
特征变换: 通过线性变换,线性层可以将输入数据从一个空间映射到另一个空间,从而实现特征的变换和提取。
-
适用范围广: 线性层可用于各种不同类型的深度学习模型,例如全连接神经网络、卷积神经网络、循环神经网络等,具有较强的通用性。
-
可解释性强: 由于线性层进行的是线性变换,因此权重矩阵的每个元素都可以直接解释为输入特征与输出特征之间的关系,这有助于理解模型的工作原理。
激活函数
激活函数是神经网络中非常重要的一部分,它的作用是为神经元引入非线性属性,从而使神经网络可以学习和表达更加复杂的函数关系。在深度学习中,激活函数通常被应用在每个神经元的输出上,以增加网络的表达能力。
-
Sigmoid 函数:将输入值压缩到 (0, 1) 区间内,常用于二分类问题。
-
Tanh 函数:将输入值压缩到 (-1, 1) 区间内,可以处理具有负值的数据。
-
ReLU 函数(Rectified Linear Unit):对负数部分直接置零,能够加速收敛并减少训练时间。
-
Leaky ReLU 函数:引入一个小的斜率来解决 ReLU 死亡神经元问题。
-
Softmax 函数:常用于多分类问题,将输入转化为概率分布。
-
Swish 函数:由 Google 提出,结合了 Sigmoid 的平滑性和线性部分的特性。