赞
踩
CNN 是卷积神经网络(Convolutional Neural Network)的缩写,是一种常用于图像和视频处理的深度学习算法。CNN 的主要思想是通过卷积、池化等操作来提取数据的空间特征,从而实现对数据的自动分类和识别。**通常用于图像分类、目标检测、语义分割等。
CNN 的结构通常包括若干个卷积层、池化层和全连接层。其中卷积层是 CNN 最重要的部分,其主要作用是通过卷积操作提取数据的局部特征,从而捕获数据的空间信息。在卷积层中,通常使用一组滤波器(也称为卷积核)对输入数据进行卷积运算,得到一组输出特征图。同时,卷积层通常还会使用激活函数对输出进行非线性变换,增加网络的表达能力。
另外,CNN 还常常使用池化层来进一步减少数据的维度,并且提高网络对平移不变性的鲁棒性。池化层通常采用最大值池化或平均值池化的方式对输入数据进行降采样,从而得到更小的输出特征图。
最后,全连接层通常被用于将 CNN 输出的特征图转换为分类或回归结果。全连接层通常包括若干个全连接层和激活函数,用于将特征图中的每个元素映射到最终的输出类别或数值。
常见且需要掌握的卷积神经网络有:VGGNet、 GoogleNet、 ResNet、SENet、MobileNet、 ShuffleNet
主要分为:数据输入层(Input Layer)、卷积计算层(CONV Layer)、ReLU激励层(ReLU Incentive Layer)、池化层(Pooling Layer)、全连接层(FC Layer)、Batch Normalization Layer(可能有)
神经网络中的激活层是指在神经网络的每个神经元输出后,通过一个非线性函数将其激活成非零值的层。**在深度学习中,常见的激活函数有sigmoid、ReLU、tanh等。
激活层的作用是增加神经网络的非线性特性,使得神经网络可以更好地逼近复杂的非线性函数,并提高模型的表达能力。通过引入激活函数,神经网络可以学习到更加复杂的特征表示,从而提高模型的性能。
Sigmoid函数(Logistic函数):将输入值映射到0到1之间,简单容易理解,常用于二分类任务和输出概率值的场景。缺点:容易饱和和终止梯度传递(死神经元),SIGMOD函数的输出没有0中心化
双曲正切函数(Tanh函数):将输入值映射到-1到1之间,常用于多分类任务,易理解,0中心化。缺点:容易饱和和终止梯度传递(死神经元)
ReLU函数(整流线性单元):在输入值大于0时直接输出输入值,小于等于0时输出0。相对于Sigmoid函数和Tanh函数提升了收敛速度,并且不会产生梯度消失和梯度爆炸。能够有效缓解梯度消失问题。缺点:没有边界,比较脆弱,容易陷入死神经元的情况(解决方案是设置较小的学习率)
梯度爆炸通常指的是,在反向传播过程中,梯度值变得非常大,甚至超过了计算机可以表示的范围,导致数值溢出的情况。这种情况下,由于参数更新量过大,模型可能无法正确地收敛,甚至完全无法训练
Leaky ReLU函数:与ReLU函数类似,但在输入值小于零时引入了一个小的线性斜率,以解决ReLU函数中负数区域的神经元“死亡”问题,但是实际场景效果不佳
参数化ReLU(PReLU函数):是对Leaky ReLU的扩展,其中斜率参数可以通过学习得到
池化层是深度学习神经网络中常用的一种层级结构,通常用于减少特征图的尺寸、提取主要特征以及减少计算量。池化层主要有两种类型:最大池化(Max Pooling)和平均池化(Average Pooling)。
在最大池化中,对于每个池化窗口,池化层会选择窗口内的最大值作为输出;而在平均池化中,池化层会选择窗口内的平均值作为输出。这两种池化方法都能够有效地减少特征图的尺寸,并且在一定程度上保留主要特征。
全连接层(Fully Connected Layer),也称为密集连接层或者仿射层,是深度学习神经网络中最基本的层之一。在全连接层中,每个神经元与上一层的所有神经元相连,每个连接都有一个对应的权重,因此全连接层的参数数量较大。
全连接层通常出现在深度学习模型的尾部,用于整合前面卷积层或者其他特征提取层提取的特征,以便进行最终的分类或者预测任务。然而,由于全连接层的参数量较大,容易产生过拟合问题,并且在处理高分辨率图片时会导致参数量过大,计算量过高。
Batch Normalization(批归一化)层是深度学习神经网络中常用的一种技术,用于在模型训练过程中加速收敛并提高模型的稳定性,并且减少了对超参数的敏感性。Batch Normalization的主要思想是对每个批次(batch)的输入进行归一化处理,使得输入数据的均值接近于0,方差接近于1。
Batch Normalization层通常被插入到卷积层或者全连接层之后,激活函数和池化层之前,而实际应用的时候有时候会放到激励层后。它可以通过对每个输入进行归一化、缩放和平移操作来实现。
优点:
缺点:
- import torch
- import torch.nn as nn
-
- class BN(nn.Module): # 实现了对输入数据进行归一化的功能
- def __init__(self, num_features):
- super(BN, self).__init__() # 调用父类nn.Module的构造函数,确保正确地初始化BN类
- self.num_features = num_features
- self.weight = nn.Parameter(torch.Tensor(num_features)) # 创建一个可学习的参数 weight,它是一个形状为 (num_features,) 的张量。该参数用于缩放归一化后的数据。
- self.bias = nn.Parameter(torch.Tensor(num_features)) # 该参数用于平移归一化后的数据。
- self.running_mean = torch.zeros(num_features) # 初始化running_mean,它是一个形状为 (num_features,) 的全零张量。running_mean 用于在训练过程中记录每个通道的均值。
- self.running_var = torch.ones(num_features) # 用于在训练过程中记录每个通道的方差
-
- def forward(self, x): # 前向传播函数 forward
- if self.training:
- mean = x.mean(dim=(0, 2, 3)) # 计算每个通道在当前batch中的均值
- var = x.var(dim=(0, 2, 3)) # 计算每个通道在当前batch中的方差
- self.running_mean = 0.9 * self.running_mean + 0.1 * mean # 更新running_mean,采用动量平均
- """
- 具体来说,这行代码的作用是将当前计算得到的均值 mean 与之前记录的 running_mean 进行加权平均。其中,0.9 是旧
- 值(self.running_mean)的权重,0.1 是新值(mean)的权重。这种加权平均的方式可以使得 running_mean 在每次
- 迭代中都向新的均值靠近,同时保留了一定程度的历史信息
- """
- self.running_var = 0.9 * self.running_var + 0.1 * var # 更新running_var,采用动量平均
- else: # 如果当前处于推断阶段。
- mean = self.running_mean # 使用之前训练好的 running_mean
- var = self.running_var # 使用之前训练好的 running_var
-
- x_hat = (x - mean[None, :, None, None]) / torch.sqrt(var[None, :, None, None] + 1e-5) # 归一化
-
- """
- x 是输入的图像数据,它的形状为 (batch_size, channels, height, width),表示批量大小、通道数、高度和宽度。mean 是
- 图像数据在各个通道上的均值,它的形状为 (channels,),其中每个元素对应一个通道的均值。var 是图像数据在各个通道上的方差,它
- 的形状也为 (channels,),其中每个元素对应一个通道的方差。None 的作用是在相应的位置增加一个维度,以便进行广播运算。
- torch.sqrt(var[None, :, None, None] + 1e-5) 表示对方差进行开方,并增加维度以便与 x 进行广播运算。在开方之前,添加
- 一个小的常数 1e-5 是为了避免除以零的情况。(x - mean[None, :, None, None]) 表示将每个像素点的原始值减去相应通道上的均值。
-
- 最后整个表达式的结果 x_hat 表示归一化后的图像数据,即将每个像素点的原始值减去均值,并除以标准差。
- """
-
- y = self.weight[None, :, None, None] * x_hat + self.bias[None, :, None, None] # 线性变换
-
- """
- x_hat 是输入数据 x 经过归一化处理后的结果。在神经网络中,常用的归一化方法是将输入数据减去均值并除以标准差,从而使数据分
- 布更接近标准正态分布。self.weight 是该层的权重参数,它通过乘以 x_hat 实现线性变换。这里使用了广播操作,将 self.weight 扩
- 展为与 x_hat 相同的维度。self.bias 是该层的偏置参数,它通过加到 self.weight * x_hat 上实现线性变换的偏移。
-
- 综合起来,这段代码的作用是将经过归一化处理的输入数据 x_hat 与权重参数 self.weight 做线性变换,并加上偏置参数 self.bias。这
- 是神经网络中常见的一种操作,用于引入非线性和适应不同数据分布的能力。
- """
- return y
-
- """
- 第 0 维:batch_size,即输入数据的样本数量。
- 第 1 维:特征维度数量,也称为通道数或特征通道。
- 第 2 维:高度维度,表示输入数据的高度。
- 第 3 维:宽度维度,表示输入数据的宽度
- """
Layer Normalization的主要思想是对每个样本的特征维度进行归一化处理,使得输入数据的均值接近于0,方差接近于1。与Batch Normalization不同的是,Layer Normalization不依赖于批次数据的统计信息,而是仅使用当前样本在特征维度上的均值和方差进行归一化。
不受样本批次大小的影响,在RNN上效果比较明显, 但是在CNN上, 效果不及BN。
- class LN(nn.Module): # 自定义的 Layer Normalization(层归一化)模块 LN
- def __init__(self, num_features, eps=1e-5): # eps 是一个小的常数,用于避免除以零的情况
- super(LN, self).__init__()
- self.num_features = num_features
- self.eps = eps
- self.weight = nn.Parameter(torch.ones(num_features)) # weight 和 bias 是可学习的张量参数,分别用于缩放和偏置操作
- self.bias = nn.Parameter(torch.zeros(num_features))
-
- def forward(self, x):
- # 计算输入数据的均值和标准差
- mean = x.mean(dim=-1, keepdim=True) # keepdim=True表示保持计算结果的维度和输入数据一致,
- std = x.std(dim=-1, keepdim=True, unbiased=False) # unbiased=False表示计算无偏估计的标准差
-
- # 标准化输入
- # eps 是加到标准差分母上的一个小量,用于防止标准差为零的情况
- x_normalized = (x - mean) / (std + self.eps)
-
- # 应用缩放和偏置操作
- out = self.weight * x_normalized + self.bias
- return out
Instance Normalization(实例归一化)是一种归一化技术,与Batch Normalization、 Layer Normalization和Group Normalization类似,但其计算方式和应用场景有所不同。Instance Normalization主要用于对单个样本在特征维度上进行归一化处理。
Instance Normalization的主要思想是对每个样本的特征维度进行独立的归一化处理,使得输入数据的均值接近于0,方差接近于1。
不受样本批次的大小影响,保证每个feature map的独立性
- import torch
- import torch.nn as nn
-
- class IN(nn.Module):
- def __init__(self, num_features, eps=1e-5):
- super(IN, self).__init__()
- self.num_features = num_features
- self.eps = eps
- self.weight = nn.Parameter(torch.ones(num_features))
- self.bias = nn.Parameter(torch.zeros(num_features))
-
- def forward(self, x):
- # 计算输入数据的均值和方差
- mean = x.mean(dim=(2, 3), keepdim=True)
- std = x.std(dim=(2, 3), keepdim=True, unbiased=False)
-
- # 标准化输入
- x_normalized = (x - mean) / (std + self.eps)
-
- # 应用缩放和偏置操作
- out = self.weight * x_normalized + self.bias
- return out
Group Normalization(组归一化)是一种归一化技术,与Batch Normalization和Layer Normalization类似,但其计算方式和应用场景有所不同。Group Normalization将特征通道分成若干组,并对每个组内的特征进行独立的归一化处理。
Group Normalization的主要思想是通过将特征通道分组,减少了对整个批次数据或单个样本的依赖性,而是更关注于每个特征通道内的统计信息。相较于Batch Normalization,Group Normalization不仅可以在小批次训练时获得较好的效果,也适用于单个样本或小样本量的情况。
N是多少个样本的批量数据,C是通道数,H是高度,W是宽度
N=8 C H W
①BN C ——> C个均值 (8×H×W)
②LN N ——> 8个均值 (C×H×W)
③IN NC ——> 8×C个均值 (H×W)
Switchable Normalization是一种结合了不同归一化方法的技术,它可以在训练过程中动态地选择适合当前场景的归一化方式。Switchable Normalization基于Batch Normalization、Layer Normalization、Instance Normalization和Group Normalization这几种常见的归一化方法,通过学习参数来决定不同归一化方式的权重,从而根据实际情况选择最适合的归一化方式。
Switchable Normalization的主要思想是在网络中引入一个控制开关,该开关通过学习参数来决定使用哪种归一化方法。在前向传播过程中,Switchable Normalization会根据学习到的权重来加权不同归一化方法的输出,从而实现动态选择最适合当前场景的归一化方式。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。