资讯详情

CNN各模块介绍

文章目录

  • 一.CNN简介
  • 二.CNN卷积神经网络-主要层次
  • 三.数据输入层
    • 1.输入层预处理
    • 2.数据增强
      • 1. 存在小数据集的问题
      • 2. 在训练期间增加噪音
      • 3. 如何添加噪声
      • 4. 添加噪声提示
      • 5. tensorflow.keras API
  • 四.卷积计算层
    • 1.卷积介绍
    • 2.深度学习中的各种卷积
      • (1)3D 卷积
      • (2)转置卷积(去卷积)
      • (3)扩大卷积/空洞卷积(Atrous 卷积)
      • (4)卷积可分离
        • 4-1空间可以分离卷积
        • 4-2深度可分离卷积 Depthwise separable convolution
      • (5)分组卷积
  • 五.激励层
    • 1.激励建议
    • 2.常见的激活函数
      • 2-1 Sigmoid函数
      • 2-2 Tanh函数
      • 2-3 ReLU函数
      • 2-4 Leaky ReLU函数
      • 2-5 softplus函数
      • 2-6 Mish 函数
  • 六.池化层
    • 1.pooling介绍
  • 七.全连接层
  • 八.BN 层
    • 1.BN的由来
    • 2.BN优点
      • (1)BN使网络中每层输入数据的分布相对稳定,加快模型学习速度
      • (2)BN使模型对网络中的参数不那么敏感,简化了调参过程,使网络学习更加稳定
      • (3)BN允许网络使用饱和激活函数(例如)sigmoid,tanh等),缓解梯度消失
      • (4)BN具有一定的正则化效果
    • 3.BN的操作阶段
    • 4.BN能防止梯度消失吗?
    • 5.为什么一化后要放缩和平移?
    • 6.BN LN IN GN SN
  • 九.卷积神经网络的优缺点
  • 十.Loss介绍
    • 5.交叉熵损失函数 CrossEntropyLoss
    • 4. BCE Loss BCEWithLogitsLoss
    • 3、clDice Loss
    • 2、Dice Loss
    • 1、Focal Loss摘要
      • 2 拟解决问题
      • 3.解决方案
      • 4、解决方案__

一.CNN简介

卷积神经网络(Convolutional Neural Networks,CNN),CNN能有效降低反馈神经网络(传统神经网络)的复杂性,常见的CNN结构有LeNet-5、AlexNet、ZFNet、VGGNet、GoogleNet ResNet、DenseNet、SENet、Residual Attention Networks、MobileNet、ShuffleNet等等CNN层次增加是发展的重要方向,通过这种方式,增加的非线性神经元可以获得目标函数的近似结构,并获得更好的特征表达。然而,这种方法增加了网络的整体复杂性,使网络更难优化。模型很容易过拟合/退化。 CNN主要用于图像分类、目标检测、图像分割等应用场景。 卷积演示图 https://cs231n.github.io/assets/conv-demo/index.htmler

二.CNN卷积神经网络-主要层次

? 数据输入层:Input Layer ? 卷积计算层:CONV Layer ? ReLU激励层:ReLU Incentive Layer ? 池化层:Pooling Layer ? 全连接层 :FC Layer ? 备注:Batch Normalization Layer(可能有)

三.数据输入层

1.输入层预处理

与神经网络/机器学习一样,输入的数据需要预处理。预处理的主要原因是: ? 不同的输入数据单位可能导致神经网络收敛缓慢,训练时间长 ? 模式分类中数据范围大的输入可能过大,而数据范围小的输入可能过小 ? 由于神经网络中的激活函数受到值域的限制,因此需要将网络训练的目标数据映射到激活函数的值域 ? S形激活函数(sigmod)区间以外的区域(-4,4)非常温和,区分太小。例如,S形函数f(X),f(100)与f(5)只相差0.0067

2.数据增强

1. 存在小数据集的问题

小数据集会在训练大型神经网络时带来问题。 第一个问题:网络可以有效地记住训练数据集。该模型可以学习特定的输入示例及其相关输出,而不是从输入到输出的一般映射。这将导致模型在训练数据集中表现良好,而在新数据中表现不佳,即泛化能力差。 第二个问题:小数据集提供了更少的机会来描述输入空间的结构及其与输出之间的关系。更多的培训数据为模型可以学习的问题提供了更丰富的描述。较少的数据意味着冲击和离散的输入空间,而不是光滑的输入空间,这可能会导致模型学习特征映射困难。 有时,很难收集一些数据。此外,即使收集了更多的数据,这些问题也可能无法解决。一种解决方案是在训练期间增加噪音。

2. 在训练期间增加噪音

小数据集程中,小数据集会导致较大的误差。通过在训练过程中添加噪声,可以提高模型从输入空间学习映射规则的能力,提高模型的泛化能力和容错率。 在神经网络模型训练过程中,添加噪声具有正则作用,从而提高了模型的鲁棒性。与权重正则化方法一样,已经证明添加噪声对损失函数的影响与惩罚项相似。 事实上,添加噪声会扩大训练数据集的大小。每次将训练样本输入模型时,随机噪声添加到输入变量中,使输入模型的数据每次都不同。将噪声添加到输入样本中是数据增强的简单形式。 添加噪声意味着网络记不住训练样本,因为它们一直在变化,导致网络权重更小,网络更强,泛化误差更低。 噪声意味着从已知样本附近的域中提取新样本,以平滑输入空间的结构。这种平滑可能意味着映射功能更容易在线学习,从而导致更好、更快的学习。

3. 如何添加噪音

高斯噪声或白噪声(Gaussian noise, or white noise) 的平均值为零,标准差(std)1.伪随机数生成器可根据需要生成。在信号处理中,高斯噪声是指电路中不相关的随机噪声;传统上,在神经网络输入中添加高斯噪声称为抖动(jitter)或者随机抖动。 添加的噪声量(例如,扩展或标准偏差)是一个可配置的超参数。噪声太小没有影响,而且噪声太大,使得映射功能难以学习。通常,在将输入数据喂入网络之前,在输入数据上添加一个随机向量。因此,不同的随机向量也会添加相同的数据。 可根据每个输入变量的大小调整随机噪声的标准差。如果输入变量的标准化已经首先标准化,则更容易配置。 只在训练期间添加噪音。在模型评估或使用模型预测新数据时,不会添加任何噪音。 噪声的增加也是自动特征学习的重要组成部分,如所谓的降噪自动编码(Denoising Autoencoders)该设备明确要求模型在输入噪声时学习鲁棒特性。 尽管在数据中添加噪声是最常见和最广泛的方法,但随机噪声可以添加到网络的其他部分。

  • 为激活添加噪声,即每层输出。

  • 向权重添加噪声,即迭代输入。

  • 给梯度(即更新权重的方向)增加噪音。

  • 给输出(即标签或目标变量)添加噪声。

    在激活中中增加噪声,从而可以在网络的任何数据使用噪声。这对于非常深的网络可能是有益的。将噪声添加到层输出中,很可能是通过使用噪声激活函数来实现的。 在权重中添加噪声,可以使该方法以一致的方式在整个网络中使用,而不是在输入和层激活中添加噪声。这在递归神经网络中特别有用。 向梯度添加噪声,可以使模型更多地集中在提高优化过程本身的鲁棒性上,而不是输入空间的结构上。噪声的数量可能在训练开始时就开始很高,并且随着时间的流逝而降低,这很像学习速率的下降。对于非常深的网络和各种不同的网络类型,该方法已被证明是一种有效的方法。 将噪声添加到激活,权重或梯度都提供了一种更通用的添加噪声的方法,该噪声对于提供给模型的输入变量的类型是不变的。 如果认为或预期问题域带有错误标记的示例,则在类别标签上添加噪声可以提高模型对此类错误的鲁棒性。但这很容易偏离学习过程。 在回归或时间序列预测中,将噪声添加到连续目标变量中,非常类似于将噪声添加到输入变量中,并且可能是更好的方法。

4. 添加噪声的提示

添加噪声的方法,主要用于多层感知器,但可以与卷积和递归神经网络一起使用。 重要的是,噪声的添加对模型具有一致的影响。这就要求对输入数据进行重新缩放,以使所有变量都具有相同的缩放比例,以便在以固定方差将噪声添加到输入时,具有相同的效果。这也适用于在权重和渐变上添加噪声,因为它们也受输入比例的影响。这可以通过输入变量的标准化或标准化来实现。如果在数据缩放后添加了随机噪声,则可能需要对每个批处理再次重新缩放变量。

5. tensorflow.keras API

将噪声添加到具有少量训练数据集的神经网络模型中可以产生正则化效果并减少过拟合。 Keras通过单独的 GaussianNoise 层添加高斯噪声。该层可用于向现有模型添加噪声。

tf.keras.layers.GaussianNoise(
    stddev, **kwargs)123
参数说明:
stddev:float类型,噪声分布的标准差。
调用参数说明:
inputs:输入张量(任何等级)。
training:bool类型,True指示该层在训练模式下添加噪声;False表示不执行任何操作。
input_shape:在将此层用作模型的第一层时,需要指定该关键字参数(整数元组,不包括样本轴)。
示例:
from tensorflow.keras.layers import GaussianNoise
layer = GaussianNoise(0.1)12

实例:
1. 在激活之前添加高斯噪声:
...model.add(Dense(32))
model.add(GaussianNoise(0.1))
model.add(Activation('relu'))
model.add(Dense(32))...123456
2. 在激活之后添加高斯噪声:
...model.add(Dense(32, activation='reu'))
model.add(GaussianNoise(0.1))
model.add(Dense(32))...12345
可以将标准差作为超参数,通过网格搜索找出最佳的值。

方法一: 利用randn()函数生成高斯噪声这里需要用到randn()函数,该函数就专门用来生成正态分布数据的一个函数。 比如 randn(10,10),然后这个矩阵和原图像矩阵相加即可(注意缩放灰度范围)

randn(10,10)
ans =
   -0.3587    0.6694    0.2922    0.4127   -0.4399   -0.2027    1.2917   -1.2807    0.0522   -0.2097
    1.4851   -0.2349   -0.0809   -1.0475    0.4734   -0.8012   -1.3658   -2.4489    1.2525   -0.0725
    0.1214    0.2553    0.2774   -0.9508   -0.3378   -1.1350    0.7951   -0.6749   -0.1797   -0.5646
   -0.7056    1.5769   -0.8234    1.5896    1.5743    0.1304   -0.3575   -1.0971   -0.2286   -1.5035
    1.4605    0.6227   -0.6059    1.5939    0.0120   -0.1012   -0.9397   -1.6988   -2.3375    1.0503
   -0.2038    0.7016    0.7310   -0.4053   -0.0419   -0.3276   -0.7675    0.6319    0.3662   -1.0595
   -1.3164    0.1579    0.3200   -0.2055    0.5508   -0.6350    0.7769    1.1788    1.1854   -1.0070
    0.1054    1.0071    0.4267    0.6462   -1.1893   -1.8829   -1.2166   -0.2838    1.0378    0.8280
    0.9141   -1.5962   -0.0540    1.5489    1.0449    0.6155   -0.6227    0.2447    0.2955   -0.7770
   -0.7474    0.6233    1.3306   -0.2167   -0.2423    1.3778   -1.0203   -1.1946    0.4893    0.0451
代码:

t=imread('a1.jpg');
[m,n,z]=size(t);
y=0+0.1*randn(m,n);%二维高斯分布矩阵 0是均值 0.1是标准差
 
%先将其double化,再除以255 便于后面计算
t1=double(t)/255;
 
%加上噪声
t1=t1+y;

%将像素范围扩大至0--255
t1=t1*255;
 
%转换为uint8类型
t1=uint8(t1);
 

四.卷积计算层

1.卷积介绍

• 卷积计算层:CONV Layer • 局部关联:每个神经元看做一个filter/kernal • 窗口(receptive field)滑动,filter对局部数据进行计算 • 相关概念 • 深度:depth • 步长:stride • 填充值:zero-padding • CONV过程参考:http://cs231n.github.io/assets/conv-demo/index.html

2.深度学习中的各种卷积

(1)3D 卷积

在上一节的解释中,我们看到我们实际上是对一个 3D 体积执行卷积。但通常而言,我们仍在深度学习中称之为 2D 卷积。这是在 3D 体积数据上的 2D 卷积。过滤器深度与输入层深度一样。这个 3D 过滤器仅沿两个方向移动(图像的高和宽)。这种操作的输出是一张 2D 图像(仅有一个通道)。 很自然,3D 卷积确实存在。这是 2D 卷积的泛化。下面就是 3D 卷积,其过滤器深度小于输入层深度(核大小<通道大小)。因此,3D 过滤器可以在所有三个方向(图像的高度、宽度、通道)上移动。在每个位置,逐元素的乘法和加法都会提供一个数值。因为过滤器是滑过一个 3D 空间,所以输出数值也按 3D 空间排布。也就是说输出是一个 3D 数据。

在 3D 卷积中,3D 过滤器可以在所有三个方向(图像的高度、宽度、通道)上移动。在每个位置,逐元素的乘法和加法都会提供一个数值。因为过滤器是滑过一个 3D 空间,所以输出数值也按 3D 空间排布。也就是说输出是一个 3D 数据。 与 2D 卷积(编码了 2D 域中目标的空间关系)类似,3D 卷积可以描述 3D 空间中目标的空间关系。对某些应用(比如生物医学影像中的 3D 分割/重构)而言,这样的 3D 关系很重要,比如在 CT 和 MRI 中,血管之类的目标会在 3D 空间中蜿蜒曲折。

(2)转置卷积(去卷积)

对于很多网络架构的很多应用而言,我们往往需要进行与普通卷积方向相反的转换,即我们希望执行上采样。例子包括生成高分辨率图像以及将低维特征图映射到高维空间,比如在自动编码器或形义分割中。(在后者的例子中,形义分割首先会提取编码器中的特征图,然后在解码器中恢复原来的图像大小,使其可以分类原始图像中的每个像素。) 实现上采样的传统方法是应用插值方案或人工创建规则。而神经网络等现代架构则倾向于让网络自己自动学习合适的变换,无需人类干预。为了做到这一点,我们可以使用转置卷积。 转置卷积在文献中也被称为去卷积或 fractionally strided convolution。但是,需要指出「去卷积(deconvolution)」这个名称并不是很合适,因为转置卷积并非信号/图像处理领域定义的那种真正的去卷积。从技术上讲,信号处理中的去卷积是卷积运算的逆运算。但这里却不是这种运算。因此,某些作者强烈反对将转置卷积称为去卷积。人们称之为去卷积主要是因为这样说很简单。后面我们会介绍为什么将这种运算称为转置卷积更自然且更合适。 我们一直都可以使用直接的卷积实现转置卷积。对于下图的例子,我们在一个 2×2 的输入(周围加了 2×2 的单位步长的零填充)上应用一个 3×3 核的转置卷积。上采样输出的大小是 4×4。

将 2×2 的输入上采样成 4×4 的输出 有趣的是,通过应用各种填充和步长,我们可以将同样的 2×2 输入图像映射到不同的图像尺寸。下面,转置卷积被用在了同一张 2×2 输入上(输入之间插入了一个零,并且周围加了 2×2 的单位步长的零填充),所得输出的大小是 5×5。

将 2×2 的输入上采样成 5×5 的输出 观察上述例子中的转置卷积能帮助我们构建起一些直观认识。但为了泛化其应用,了解其可以如何通过计算机的矩阵乘法实现是有益的。从这一点上我们也可以看到为何「转置卷积」才是合适的名称。 在卷积中,我们定义 C 为卷积核,Large 为输入图像,Small 为输出图像。经过卷积(矩阵乘法)后,我们将大图像下采样为小图像。这种矩阵乘法的卷积的实现遵照:C x Large = Small。 下面的例子展示了这种运算的工作方式。它将输入平展为 16×1 的矩阵,并将卷积核转换为一个稀疏矩阵(4×16)。然后,在稀疏矩阵和平展的输入之间使用矩阵乘法。之后,再将所得到的矩阵(4×1)转换为 2×2 的输出。

卷积的矩阵乘法:将 Large 输入图像(4×4)转换为 Small 输出图像(2×2) 现在,如果我们在等式的两边都乘上矩阵的转置 CT,并借助「一个矩阵与其转置矩阵的乘法得到一个单位矩阵」这一性质,那么我们就能得到公式 CT x Small = Large,如下图所示。

卷积的矩阵乘法:将 Small 输入图像(2×2)转换为 Large 输出图像(4×4) 这里可以看到,我们执行了从小图像到大图像的上采样。这正是我们想要实现的目标。现在。你就知道「转置卷积」这个名字的由来了。 转置矩阵的算术解释可参阅:https://arxiv.org/abs/1603.07285

(3)扩张卷积/空洞卷积(Atrous 卷积)

空洞卷积(atrous convolutions)又名扩张卷积(dilated convolutions),向卷积层引入了一个称为“ 扩张率(dilation rate)”的新参数,该参数定义了卷积核处理数据时各值的间距。过程如图:

卷积核为3、扩张率为2和无边界扩充的二维空洞卷积 一个扩张率为2的3×3卷积核,感受野与5×5的卷积核相同,而且仅需要9个参数。你可以把它想象成一个5×5的卷积核,每隔一行或一列删除一行或一列。 在相同的计算条件下,空洞卷积提供了更大的感受野。空洞卷积经常用在实时图像分割中。当网络层需要较大的感受野,但计算资源有限而无法提高卷积核数量或大小时,可以考虑空洞卷积。 我们基本上无需添加额外的成本就能有较大的感受野。

扩张卷积 直观而言,扩张卷积就是通过在核元素之间插入空格来使核「膨胀」。新增的参数 l(扩张率)表示我们希望将核加宽的程度。具体实现可能各不相同,但通常是在核元素之间插入 l-1 个空格。下面展示了 l = 1, 2, 4 时的核大小。

论文的作者用多个扩张卷积层构建了一个网络,其中扩张率 l 每层都按指数增大。由此,有效的感受野大小随层而指数增长,而参数的数量仅线性增长。 这篇论文中扩张卷积的作用是系统性地聚合多个比例的形境信息,而不丢失分辨率。这篇论文表明其提出的模块能够提升那时候(2016 年)的当前最佳形义分割系统的准确度。请参阅那篇论文了解更多信息。

(4)可分离卷积

某些神经网络架构使用了分离卷积,比如 MobileNets。可分卷积有空间分离卷积和深度可分卷积。

4-1、空间可分离卷积

空间可分卷积操作的是图像的 2D 空间维度,即高和宽。从概念上看,空间可分卷积是将一个卷积分解为两个单独的运算。对于下面的示例,3×3 的 Sobel 核被分成了一个 3×1 核和一个 1×3 核。

Sobel 核可分为一个 3x1 和一个 1x3 核 在卷积中,3×3 核直接与图像卷积。在空间可分卷积中,3×1 核首先与图像卷积,然后再应用 1×3 核。这样,执行同样的操作时仅需 6 个参数,而不是 9 个。 此外,使用空间可分卷积时所需的矩阵乘法也更少。给一个具体的例子,5×5 图像与 3×3 核的卷积(步幅=1,填充=0)要求在 3 个位置水平地扫描核(还有 3 个垂直的位置)。总共就是 9 个位置,表示为下图中的点。在每个位置,会应用 9 次逐元素乘法。总共就是 9×9=81 次乘法。

具有 1 个通道的标准卷积 另一方面,对于空间可分卷积,我们首先在 5×5 的图像上应用一个 3×1 的过滤器。我们可以在水平 5 个位置和垂直 3 个位置扫描这样的核。总共就是 5×3=15 个位置,表示为下图中的点。在每个位置,会应用 3 次逐元素乘法。总共就是 15×3=45 次乘法。现在我们得到了一个 3×5 的矩阵。这个矩阵再与一个 1×3 核卷积,即在水平 3 个位置和垂直 3 个位置扫描这个矩阵。对于这 9 个位置中的每一个,应用 3 次逐元素乘法。这一步需要 9×3=27 次乘法。因此,总体而言,空间可分卷积需要 45+27=72 次乘法,少于普通卷积。

具有 1 个通道的空间可分卷积 我们稍微推广一下上面的例子。假设我们现在将卷积应用于一张 N×N 的图像上,卷积核为 m×m,步幅为 1,填充为 0。传统卷积需要 (N-2) x (N-2) x m x m 次乘法,空间可分卷积需要 N x (N-2) x m + (N-2) x (N-2) x m = (2N-2) x (N-2) x m 次乘法。空间可分卷积与标准卷积的计算成本比为: 因为图像尺寸 N 远大于过滤器大小(N>>m),所以这个比就变成了 2/m。也就是说,在这种渐进情况(N>>m)下,当过滤器大小为 3×3 时,空间可分卷积的计算成本是标准卷积的 2/3。过滤器大小为 5×5 时这一数值是 2/5;过滤器大小为 7×7 时则为 2/7。 尽管空间可分卷积能节省成本,但深度学习却很少使用它。一大主要原因是并非所有的核都能分成两个更小的核。如果我们用空间可分卷积替代所有的传统卷积,那么我们就限制了自己在训练过程中搜索所有可能的核。这样得到的训练结果可能是次优的。

4-2、深度可分离卷积 Depthwise separable convolution

现在来看深度可分卷积,这在深度学习领域要常用得多(比如 MobileNet 和 Xception)。深度可分卷积包含两个步骤:逐通道卷积(Depthwise Convolution)和逐点卷积(Pointwise Convolution)。 在描述这些步骤之前,有必要回顾一下我们之前介绍的 2D 卷积核 1×1 卷积。首先快速回顾标准的 2D 卷积。举一个具体例子,假设输入层的大小是 7×7×3(高×宽×通道),而过滤器的大小是 3×3×3。经过与一个过滤器的 2D 卷积之后,输出层的大小是 5×5×1(仅有一个通道)。

用于创建仅有 1 层的输出的标准 2D 卷积,使用 1 个过滤器 一般来说,两个神经网络层之间会应用多个过滤器。假设我们这里有 128 个过滤器。在应用了这 128 个 2D 卷积之后,我们有 128 个 5×5×1 的输出映射图(map)。然后我们将这些映射图堆叠成大小为 5×5×128 的单层。通过这种操作,我们可将输入层(7×7×3)转换成输出层(5×5×128)。空间维度(即高度和宽度)会变小,而深度会增大。

用于创建有 128 层的输出的标准 2D 卷积,要使用 128 个过滤器 现在使用深度可分卷积,看看我们如何实现同样的变换。 首先,我们将深度卷积应用于输入层。但我们不使用 2D 卷积中大小为 3×3×3 的单个过滤器,而是分开使用 3 个核。每个过滤器的大小为 3×3×1。每个核与输入层的一个通道卷积(仅一个通道,而非所有通道!)。每个这样的卷积都能提供大小为 5×5×1 的映射图。然后我们将这些映射图堆叠在一起,创建一个 5×5×3 的图像。经过这个操作之后,我们得到大小为 5×5×3 的输出。现在我们可以降低空间维度了,但深度还是和之前一样。

深度可分卷积——第一步:我们不使用 2D 卷积中大小为 3×3×3 的单个过滤器,而是分开使用 3 个核。每个过滤器的大小为 3×3×1。每个核与输入层的一个通道卷积(仅一个通道,而非所有通道!)。每个这样的卷积都能提供大小为 5×5×1 的映射图。然后我们将这些映射图堆叠在一起,创建一个 5×5×3 的图像。经过这个操作之后,我们得到大小为 5×5×3 的输出。 在深度可分卷积的第二步,为了扩展深度,我们应用一个核大小为 1×1×3 的 1×1 卷积。将 5×5×3 的输入图像与每个 1×1×3 的核卷积,可得到大小为 5×5×1 的映射图。

因此,在应用了 128 个 1×1 卷积之后,我们得到大小为 5×5×128 的层。

深度可分卷积——第二步:逐点卷积(Pointwise Convolution),应用多个 1×1 卷积来修改深度。 通过这两个步骤,深度可分卷积也会将输入层(7×7×3)变换到输出层(5×5×128)。 下图展示了深度可分卷积的整个过程。

深度可分卷积的整个过程 所以,深度可分卷积有何优势呢?效率!相比于 2D 卷积,深度可分卷积所需的操作要少得多。 回忆一下我们的 2D 卷积例子的计算成本。有 128 个 3×3×3 个核移动了 5×5 次,也就是 128 x 3 x 3 x 3 x 5 x 5 = 86400 次乘法。 可分卷积又如何呢?在第一个深度卷积步骤,有 3 个 3×3×1 核移动 5×5 次,也就是 3x3x3x1x5x5 = 675 次乘法。在 1×1 卷积的第二步,有 128 个 1×1×3 核移动 5×5 次,即 128 x 1 x 1 x 3 x 5 x 5 = 9600 次乘法。因此,深度可分卷积共有 675 + 9600 = 10275 次乘法。这样的成本大概仅有 2D 卷积的 12%! 所以,对于任意尺寸的图像,如果我们应用深度可分卷积,我们可以节省多少时间?让我们泛化以上例子。现在,对于大小为 H×W×D 的输入图像,如果使用 Nc 个大小为 h×h×D 的核执行 2D 卷积(步幅为 1,填充为 0,其中 h 是偶数)。为了将输入层(H×W×D)变换到输出层((H-h+1)x (W-h+1) x Nc),所需的总乘法次数为: Nc x h x h x D x (H-h+1) x (W-h+1) 另一方面,对于同样的变换,深度可分卷积所需的乘法次数为: D x h x h x 1 x (H-h+1) x (W-h+1) + Nc x 1 x 1 x D x (H-h+1) x (W-h+1) = (h x h + Nc) x D x (H-h+1) x (W-h+1) 则深度可分卷积与 2D 卷积所需的乘法次数比为: 现代大多数架构的输出层通常都有很多通道,可达数百甚至上千。对于这样的层(Nc >> h),则上式可约简为 1 / h²。基于此,如果使用 3×3 过滤器,则 2D 卷积所需的乘法次数是深度可分卷积的 9 倍。如果使用 5×5 过滤器,则 2D 卷积所需的乘法次数是深度可分卷积的 25 倍。 使用深度可分卷积有什么坏处吗?当然是有的。深度可分卷积会降低卷积中参数的数量。因此,对于较小的模型而言,如果用深度可分卷积替代 2D 卷积,模型的能力可能会显著下降。因此,得到的模型可能是次优的。但是,如果使用得当,深度可分卷积能在不降低你的模型性能的前提下帮助你实现效率提升。

(5)分组卷积

AlexNet 论文(https://papers.nips.cc/paper/4824-imagenet-classification-with-deep-convolutional-neural-networks.pdf)在 2012 年引入了分组卷积。实现分组卷积的主要原因是让网络训练可在 2 个内存有限(每个 GPU 有 1.5 GB 内存)的 GPU 上进行。下面的 AlexNet 表明在大多数层中都有两个分开的卷积路径。这是在两个 GPU 上执行模型并行化(当然如果可以使用更多 GPU,还能执行多 GPU 并行化)。

图片来自 AlexNet 论文 这里我们介绍一下分组卷积的工作方式。首先,典型的 2D 卷积的步骤如下图所示。在这个例子中,通过应用 128 个大小为 3×3×3 的过滤器将输入层(7×7×3)变换到输出层(5×5×128)。推广而言,即通过应用 Dout 个大小为 h x w x Din 的核将输入层(Hin x Win x Din)变换到输出层(Hout x Wout x Dout)。

标准的 2D 卷积 在分组卷积中,过滤器会被分为不同的组。每一组都负责特定深度的典型 2D 卷积。下面的例子能让你更清楚地理解。

具有两个过滤器分组的分组卷积 上图展示了具有两个过滤器分组的分组卷积。在每个过滤器分组中,每个过滤器的深度仅有名义上的 2D 卷积的一半。它们的深度是 Din/2。每个过滤器分组包含 Dout/2 个过滤器。第一个过滤器分组(红色)与输入层的前一半([:, :, 0:Din/2])卷积,而第二个过滤器分组(橙色)与输入层的后一半([:, :, Din/2:Din])卷积。因此,每个过滤器分组都会创建 Dout/2 个通道。整体而言,两个分组会创建 2×Dout/2 = Dout 个通道。然后我们将这些通道堆叠在一起,得到有 Dout 个通道的输出层。 6-1、分组卷积与深度卷积 你可能会注意到分组卷积与深度可分卷积中使用的深度卷积之间存在一些联系和差异。如果过滤器分组的数量与输入层通道的数量相同,则每个过滤器的深度都为 Din/Din=1。这样的过滤器深度就与深度卷积中的一样了。 另一方面,现在每个过滤器分组都包含 Dout/Din 个过滤器。整体而言,输出层的深度为 Dout。这不同于深度卷积的情况——深度卷积并不会改变层的深度。在深度可分卷积中,层的深度之后通过 1×1 卷积进行扩展。 分组卷积有几个优点。 第一个优点是高效训练。因为卷积被分成了多个路径,每个路径都可由不同的 GPU 分开处理,所以模型可以并行方式在多个 GPU 上进行训练。相比于在单个 GPU 上完成所有任务,这样的在多个 GPU 上的模型并行化能让网络在每个步骤处理更多图像。人们一般认为模型并行化比数据并行化更好。后者是将数据集分成多个批次,然后分开训练每一批。但是,当批量大小变得过小时,我们本质上是执行随机梯度下降,而非批梯度下降。这会造成更慢,有时候更差的收敛结果。 在训练非常深的神经网络时,分组卷积会非常重要,正如在 ResNeXt 中那样。

图片来自 ResNeXt 论文,https://arxiv.org/abs/1611.05431 第二个优点是模型会更高效,即模型参数会随过滤器分组数的增大而减少。在之前的例子中,完整的标准 2D 卷积有 h x w x Din x Dout 个参数。具有 2 个过滤器分组的分组卷积有 (h x w x Din/2 x Dout/2) x 2 个参数。参数数量减少了一半。 第三个优点有些让人惊讶。分组卷积也许能提供比标准完整 2D 卷积更好的模型。另一篇出色的博客已经解释了这一点:https://blog.yani.io/filter-group-tutorial。这里简要总结一下。 原因和稀疏过滤器的关系有关。下图是相邻层过滤器的相关性。其中的关系是稀疏的。

在 CIFAR10 上训练的一个 Network-in-Network 模型中相邻层的过滤器的相关性矩阵。高度相关的过滤器对更明亮,而相关性更低的过滤器则更暗。图片来自:https://blog.yani.io/filter-group-tutorial 分组矩阵的相关性映射图又如何?

在 CIFAR10 上训练的一个 Network-in-Network 模型中相邻层的过滤器的相关性,动图分别展示了有 1、2、4、8、16 个过滤器分组的情况。图片来自 https://blog.yani.io/filter-group-tutorial 上图是当用 1、2、4、8、16 个过滤器分组训练模型时,相邻层的过滤器之间的相关性。那篇文章提出了一个推理:「过滤器分组的效果是在通道维度上学习块对角结构的稀疏性……在网络中,具有高相关性的过滤器是使用过滤器分组以一种更为结构化的方式学习到。从效果上看,不必学习的过滤器关系就不再参数化。这样显著地减少网络中的参数数量能使其不容易过拟合,因此,一种类似正则化的效果让优化器可以学习得到更准确更高效的深度网络。」

AlexNet conv1 过滤器分解:正如作者指出的那样,过滤器分组似乎会将学习到的过滤器结构性地组织成两个不同的分组。本图来自 AlexNet 论文。 此外,每个过滤器分组都会学习数据的一个独特表征。正如 AlexNet 的作者指出的那样,过滤器分组似乎会将学习到的过滤器结构性地组织成两个不同的分组——黑白过滤器和彩色过滤器。

五.激励层

y_relu = torch.relu(x).data.numpy()  
y_sigmoid = torch.sigmoid(x).data.numpy()
y_tanh = torch.tanh(x).data.numpy()
y_softplus = F.softplus(x).data.numpy()

1.激励层建议

• CNN尽量不要使用sigmoid,如果要使用,建议只在全连接层使用 • 首先使用ReLU,因为迭代速度快,但是有可能效果不佳 • 如果使用ReLU失效的情况下,考虑使用Leaky ReLu或者Maxout,此时一般情况都可以解决啦 • tanh激活函数在某些情况下有比较好的效果,但是应用场景比较少

2.常见的激活函数

2-1 Sigmoid函数

目前已被淘汰 缺点: 1.饱和时梯度值非常小。由于BP算法反向传播的时候后层的梯度是以乘性方式传递到前层,因此当层数比较多的时候,传到前层的梯度就会非常小,网络权值得不到有效的更新,即梯度耗散。如果该层的权值初始化使得f(x) 处于饱和状态时,网络基本上权值无法更新。 2. 输出值不是以0为中心值。

2-2 Tanh函数

其中σ(x) 为sigmoid函数,仍然具有饱和的问题。

2-3 ReLU函数

  Alex在2012年提出的一种新的激活函数。该函数的提出很大程度的解决了BP算法在优化深层神经网络时的梯度耗散问题

优点: ∙ x>0 时,梯度恒为1,无梯度耗散问题,收敛快; ∙ 增大了网络的稀疏性。当x<0 时,该层的输出为0,训练完成后为0的神经元越多,稀疏性越大,提取出来的特征就约具有代表性,泛化能力越强。即得到同样的效果,真正起作用的神经元越少,网络的泛化性能越好 ∙ 运算量很小; 缺点: 如果后层的某一个梯度特别大,导致W更新以后变得特别大,导致该层的输入<0,输出为0,这时该层就会‘die’,没有更新。当学习率比较大时可能会有40%的神经元都会在训练开始就‘die’,因此需要对学习率进行一个好的设置。 由优缺点可知max(0,x) 函数为一个双刃剑,既可以形成网络的稀疏性,也可能造成有很多永远处于‘die’的神经元,需要tradeoff。

2-4 Leaky ReLU函数

改善了ReLU的死亡特性,但是也同时损失了一部分稀疏性,且增加了一个超参数,目前来说其好处不太明确 Maxout函数 泛化了ReLU和Leaky ReLU,改善了死亡特性,但是同样损失了部分稀疏性,每个非线性函数增加了两倍的参数 真实使用的时候最常用的还是ReLU函数,注意学习率的设置以及死亡节点所占的比例即可

2-5 softplus函数

就是relu函数的平滑版本

2-6 Mish 函数

2-6.1介绍 一个新的深度学习激活函数,该函数在最终准确度上比Swish(+0.494%)和ReLU(+1.671%)都有提高。 Mish已经在70多个基准上进行了测试,包括图像分类,分割和生成,并与其他15个激活函数进行了比较。 2-6.2Mish 公式

2-6.2Mish 公式 torch代码实现

import torch
import torch.nn as nn
import torch.nn.functional as F
from matplotlib import pyplot as plt
 
class Mish(nn.Module):
    def __init__(self):
        super().__init__()
        print("Mish activation loaded...")
    def forward(self,x):
        x = x * (torch.tanh(F.softplus(x)))
        return x
 
mish = Mish()
x = torch.linspace(-10,10,1000)
y = mish(x)
 
plt.plot(x,y)
plt.grid()
plt.show()

六.池化层

1.pooling介绍

• 在池化层中,进行压缩减少特征数量的时候一般采用两种策略: • Max Pooling:最大池化,一般采用该方式 • Average Pooling:平均池化 2.GAP(global average pooling) 3.SPP pooing(空间金字塔池化) 4.ROI pooling

七.全连接层

八.BN 层

1.BN的由来

BN是由Google于2015年提出,论文是《Batch Normalization_ Accelerating Deep Network Training by Reducing Internal Covariate Shift》,这是一个深度神经网络训练的技巧,主要是让数据的分布变得一致,从而使得训练深层网络模型更加容易和稳定。所以目前BN已经成为几乎所有卷积神经网络的标配技巧了。

2.BN的作用,优点

通俗地讲,刚开始的数据都是同一个分布的,模型学习过程中,模型的参数已经适合于一种分布,突然又要适应另一种分布,这就会让模型的参数发生很大的调整,从而影响到收敛速度和精度,这就是Internal covariate shift。而BN的作用就是将这些输入值或卷积网络的张量进行类似标准化的操作,将其放缩到合适的范围,从而加快训练速度;另一方面使得每一层可以尽量面对同一特征分布的输入值,减少了变化带来的不确定性。

(1)BN使得网络中每层输入数据的分布相对稳定,加速模型学习速度

BN通过规范化与线性变换使得每一层网络的输入数据的均值与方差都在一定范围内,使得后一层网络不必不断去适应底层网络中输入的变化,从而实现了网络中层与层之间的解耦,允许每一层进行独立学习,有利于提高整个神经网络的学习速度。

(2)BN使得模型对网络中的参数不那么敏感,简化调参过程,使得网络学习更加稳定

在神经网络中,我们经常会谨慎地采用一些权重初始化方法(例如Xavier)或者合适的学习率来保证网络稳定训练。

(3)BN允许网络使用饱和性激活函数(例如sigmoid,tanh等),缓解梯度消失问题

在不使用BN层的时候,由于网络的深度与复杂性,很容易使得底层网络变化累积到上层网络中,导致模型的训练很容易进入到激活函数的梯度饱和区;通过normalize操作可以让激活函数的输入数据落在梯度非饱和区,缓解梯度消失的问题;另外通过自适应学习 γ与 β又让数据保留更多的原始信息。

(4)BN具有一定的正则化效果

在Batch Normalization中,由于我们使用mini-batch的均值与方差作为对整体训练样本均值与方差的估计,尽管每一个batch中的数据都是从总体样本中抽样得到,但不同mini-batch的均值与方差会有所不同,这就为网络的学习过程中增加了随机噪音,与Dropout通过关闭神经元给网络训练带来噪音类似,在一定程度上对模型起到了正则化的效果。 另外,原作者通过也证明了网络加入BN后,可以丢弃Dropout,模型也同样具有很好的泛化效果。

3.BN的操作阶段

【BN添加在激活层之前】

4.BN可以防止梯度消失吗

   BN可以防止学习过程中梯度消失,这一点论文中有阐述,作者说可以如果使用sigmod激活函数的时候,如果不用BN的话,会让反向传播的过程中梯度消失(当输出值较大或较小时,sigmod函数就会进入饱和区域,导致其导数几乎为零),但是可以通过使用Relu激活函数来解决,那就意味着BN主要还是让数据分布变为一致。

5.为什么归一化后还要放缩和平移

(1)减均值除方差得到的分布是正态分布,我们能否认为正态分布就是最好或最能体现我们训练样本的特征分布呢? 答: 非也,如果激活函数在方差为1的数据上,没有表现最好的效果,比如Sigmoid激活函数。这个函数在-1~1之间的梯度变化不大。假如某一层学习到特征数据本身就分布在S型激活函数的两侧,把它归一化处理、标准差也限制在了1,把数据变换成分布于s函数的中间部分,就没有达到非线性变换的目的,换言之,减均值除方差操作后可能会削弱网络的性能。 因此,必须进行一些转换才能将分布从0移开。使用缩放因子γ和移位因子β来执行此操作。随着训练的进行,这些γ和β也通过反向传播学习以提高准确性。这就要求为每一层学习2个额外的参数来提高训练速度。这个最终转换因此完成了批归一算法的定义。缩放和移位是算法比较关键,因为它提供了更多的灵活性。假设如果我们决定不使用BatchNorm,我们可以设置γ=σ和β= mean,从而返回原始值。 PS:γ和β也是待学习的参数,在网络学习的过程中会被更新

6.BN LN IN GN SN

Batch Normalization: 1.BN的计算就是把每个通道的NHW单独拿出来归一化处理,而保留通道 C 的维度。 2.针对每个channel我们都有一组γ,β,所以可学习的参数为2*C 3.受batchsize 影响,当batch size越小,BN的表现效果也越不好,因为计算过程中所得到的均值和方差不能代表全局

Layer Normalizaiton: 1.LN的计算就是把每个CHW单独拿出来归一化处理,不受batchsize 的影响,受C影响 2.常用在RNN网络,但如果输入的特征区别很大,那么就不建议使用它做归一化处理 Instance Normalization 1.IN的计算就是把每个HW单独拿出来归一化处理,不受通道和batchsize 的影响 2.常用在风格化迁移,但如果特征图可以用到通道之间的相关性,那么就不建议使用它做归一化处理 Group Normalizatio 1.GN的计算就是把先把通道C分成G组,然后把每个gHW单独拿出来归一化处理,最后把G组归一化之后的数据合并成CHW 2.GN介于LN和IN之间,当然可以说LN和IN就是GN的特列,比如G的大小为1或者为C Switchable Normalization 1.将 BN、LN、IN 结合,赋予权重,让网络自己去学习归一化层应该使用什么方法 2.集万千宠爱于一身,但训练复杂

九.卷积神经网络优缺点

优点 • 局部感知的共享卷积核(共享参数),对高维数据的处理没有压力 • 无需选择特征属性,只要训练好权重,即可得到特征值 • 深层次的网络抽取图像信息比较丰富,表达效果好 缺点 • 需要调参,需要大量样本,训练迭代次数比较多,最好使用GPU训练 • 物理含义不明确,从每层输出中很难看出含义来

十.Loss介绍

导读:对于图像分割,通过模型的优化提高准确率一直是大家推进的重点,目标损失函数作为算法求解重要的一部分,在帮助模型快速收敛方面发挥着重要的作用。本文全面的盘点了图像分割中常用的4类损失函数,文内还附有代码,推荐大家收藏~

这是一篇关于图像分割损失函数的总结,具体包括: Binary Cross Entropy Weighted Cross Entropy Balanced Cross Entropy Dice Loss Focal loss Tversky loss Focal Tversky loss log-cosh dice loss (本文提出的新损失函数) 论文地址: https://arxiv.org/pdf/2006.14822.pdf 代码地址: https://github.com/shruti-jadon/Semantic-Segmentation-Loss-Functions 项目推荐: https://github.com/JunMa11/SegL 图像分割一直是一个活跃的研究领域,因为它有可能修复医疗领域的漏洞,并帮助大众。在过去的5年里,各种论文提出了不同的目标损失函数,用于不同的情况下,如偏差数据,稀疏分割等。在本文中,总结了大多数广泛用于图像分割的损失函数,并列出了它们可以帮助模型更快速、更好的收敛模型的情况。此外,本文还介绍了一种新的log-cosh dice损失函数,并将其在NBFS skull-stripping数据集上与广泛使用的损失函数进行了性能比较。某些损失函数在所有数据集上都表现良好,在未知分布数据集上可以作为一个很好的选择。 1 简介 深度学习彻底改变了从软件到制造业的各个行业。深度学习在医学界的应用也十分广泛,例如使用U-Net进行肿瘤分割、使用SegNet进行癌症检测等。在这些应用中,图像分割是至关重要的,分割后的图像除了告诉我们存在某种疾病外,还展示了它到底存在于何处,这为实现自动检测CT扫描中的病变等功能提供基础保障。 图像分割可以定义为像素级别的分类任务。图像由各种像素组成,这些像素组合在一起定义了图像中的不同元素,因此将这些像素分类为一类元素的方法称为语义图像分割。在设计基于复杂图像分割的深度学习架构时,通常会遇到了一个至关重要的选择,即选择哪个损失/目标函数,因为它们会激发算法的学习过程。损失函数的选择对于任何架构学习正确的目标都是至关重要的,因此自2012年以来,各种研究人员开始设计针对特定领域的损失函数,以为其数据集获得更好的结果。

在本文中,总结了15种基于图像分割的损失函数。被证明可以在不同领域提供最新技术成果。 这些损失函数可大致分为4类: 基于分布的损失函数,( Distribution-based) 基于区域的损失函数,(Region-based) 基于边界的损失函数,(Boundary-based) 基于复合的损失函数(Compounded_based)。

本文还讨论了确定哪种目标/损失函数在场景中可能有用的条件。除此之外,还提出了一种新的log-cosh dice损失函数用于图像语义分割。为了展示其效率,还比较了NBFS头骨剥离数据集上所有损失函数的性能。 2 Distribution-based loss 2-1. Binary Cross-Entropy二进制交叉熵损失函数 交叉熵定义为对给定随机变量或事件集的两个概率分布之间的差异的度量。它被广泛用于分类任务,并且由于分割是像素级分类,因此效果很好。在多分类任务中,经常采用 softmax 激活函数+交叉熵损失函数,因为交叉熵描述了两个概率分布的差异,然而神经网络输出的是向量,并不是概率分布的形式。所以需要 softmax激活函数将一个向量进行“归一化”成概率分布的形式,再采用交叉熵损失函数计算 loss。 交叉熵损失函数的具体表达为:

交叉熵损失函数可以用在大多数语义分割场景中,但它有一个明显的缺点:当图像分割任务只需要分割前景和背景两种情况。当前景像素的数量远远小于背景像素的数量时,y=0的数量远大于y=1的数量,损失函数y=0的成分就会占据主导,使得模型严重偏向背景,导致效果不好。 #二值交叉熵,这里输入要经过sigmoid处理

import torch  
import torch.nn as nn  
import torch.nn.functional as F  
nn.BCELoss\(F.sigmoid\(input\), target\)

#多分类交叉熵, 用这个 loss 前面不需要加Softmax层nn.CrossEntropyLoss(input, target) 2-2. Weighted Binary Cross-Entropy加权交叉熵损失函数

[公式] 加权交叉嫡损失函数只是在交叉嫡Loss的基础上为每一个类别添加了一个权重参数为正样本加权。设置B>1 , 减少假阴性; 设置 B<1, 减少假阳性。这样相比于原始的交叉嫡Loss, 在样本数量不均衡的情况下可以获得更好的效果。

class WeightedCrossEntropyLoss\(torch.nn.CrossEntropyLoss\):  
   """  
   Network has to have NO NONLINEARITY\!  
   """  
   def \_\_init\_\_\(self, weight=None\):  
       super\(WeightedCrossEntropyLoss, self\).\_\_init\_\_\(\)  
       self.weight = weight  
  
   def forward\(self, inp, target\):  
       target = target.long\(\)  
       num\_classes = inp.size\(\)\[1\]  
  
       i0 = 1  
       i1 = 2  
  
       while i1 \< len\(inp.shape\): # this is ugly but torch only allows to transpose two axes at once 
           inp = inp.transpose\(i0, i1\)  
           i0 += 1  
           i1 += 1  
  
       inp = inp.contiguous\(\)  
       inp = inp.view\(-1, num\_classes\)  
  
       target = target.view\(-1,\)  
       wce\_loss = torch.nn.CrossEntropyLoss\ 

标签: 2p3p间距连接器8012连接器

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台