张量








常用函数



















鸢尾花Iris分类-sklearn






预备知识




demo 流程





搭建网络步骤



神经网络输出前没有经过softmax,from_logits=True

validation_data validation_split只能用一个


神经网络复杂度

学习率


激活函数





损失函数



划分数据集

将数据集划分成3个部分------训练集、验证集和测试集,这三个集合不能有交集,常见的比例是8:1:1。需要注意的是,通常都会给定训练集和测试集,而不会给验证集。这时候验证集该从哪里得到呢?一般的做法是,从训练集中均匀随机抽样一部分样本作为验证集。
训练集
训练集用来训练模型,即确定模型的权重和偏置这些参数,通常我们称这些参数为学习参数。
验证集
而验证集用于模型的选择,更具体地来说,验证集并不参与学习参数的确定,也就是验证集并没有参与梯度下降的过程。验证集只是为了选择超参数,比如网络层数、网络节点数、迭代次数、学习率这些都叫超参数。比如在k-NN算法中,k值就是一个超参数。所以可以使用验证集来求出误差率最小的k。
测试集
测试集只使用一次,即在训练完成后评价最终的模型时使用。它既不参与学习参数过程,也不参数超参数选择过程,而仅仅使用于模型的评价。
值得注意的是,千万不能在训练过程中使用测试集,而后再用相同的测试集去测试模型。这样做其实是一个cheat,使得模型测试时准确率很高。
欠拟合和过拟合

过拟合的解决方法:
增加数据,数据增强
采用正则化(L2、L1),减少模型的参数数量
Dropout
降低模型复杂度
早停Early stopping
欠拟合的解决方法:
增大模型,增加网络参数
减少正则化参数,如降低权重衰减系数、减少或丢弃Dropout层。
增加训练数据集的特征数量
延长训练
如何判断一个模型是欠拟合、过拟合、正常拟合?
过拟合:模型在训练样本中表现得过于好,在验证数据集以及测试数据集中表现不佳。高方差,低偏差。
欠拟合:如果训练集和测试集的准确率都很低,那么说明模型欠拟合。
-
欠拟合 :模型在训练集 和验证集上表现得都不好。模型没有从数据中学到足够的知识。
-
过拟合 :模型在训练集 上表现很好,但在验证集上表现很差。模型"死记硬背"了训练数据,包括其中的噪声和细节,导致泛化能力差。
|---------|-------------|---|---|
| 欠拟合 | 训练/测试误差都高 | | |
| 过拟合 | 训练误差低,测试误差高 | | |
正则化


优化器















keras搭建网络步骤





数据增强



断点续训

提取训练参数

acc和loss可视化


BatchNormalization



池化
最大池化 均值池化


dropout
Dropout是CNN中防止过拟合的方法


cifar10



ResNet
什么是ResNet
全称Residual Network(残差网络)。
ResNet最大的创新在于引入了"残差模块"(Residual Block),有效地解决了深度神经网络训练中的梯度消失和表示瓶颈问题,使得网络的层数可以达到前所未有的深度。
- 核心 :残差模块的核心思想是通过引入跳跃连接(skip connections) ,将输入直接传递到输出,从而形成一种"残差学习"的机制。这种设计允许反向传播的梯度直接流过整个网络,缓解了深度网络训练中的梯度消失问题。因为ResNet的出现,让深度学习从而变成了可能,真正的实现了深度的概念。
为什么要引入ResNet?
当时盛行的vgg网络,最多也就是到了19层,为什么不继续加深网络的结构呢?是不想吗,当然不是,按道理来说,当网络加深的时候,模型应该会表现的越来越好,能够学习到更多的特征呐,所以表现精度应该会更加优秀才对,但是实际上并不是,当网络加深的时候,表现反而不如浅层的原因,这是为什么呢?
梯度爆炸/梯度消失:BN
首先一个很重要的原因就是当网络层数不断增加的时候,会很容易出现梯度爆炸与梯度消失的问题。因为我们更新网络的方式是通过反向传播的方式,其是通过链式求导的方式进行的,而当网络层数越深,连乘的项不断增多,所以这就是会导致很容易梯度爆炸或者梯度消失。就会导致靠近输入层的网络层,计算的到的偏导数极其大,更新后W变成一个很大的数(爆炸)或者靠近输入层的网络层,计算的到的偏导数近乎零,W几乎无法得到更新。
解决方法:首先来看看为什么会梯度爆炸梯度消失,因为梯度要么过大所以一直乘导致爆炸,要么过小接近于0,一直连乘导致消失。那么我们能不能通过控制梯度在一定的范围内变化,这样就不会出现梯度爆炸/梯度消失的现象呐。当然是可以的,首先可以将数据归一化进行处理,这样我们可以避免量纲不同带来的影响,其次对于神经网络的各层,我们可以通过加入BN层让每层的输入也现在在相同的范围内,通过这样的方式,我们可以有效的避免梯度爆炸/梯度消失。并且ResNet正是通过进行数据的归一化的BN层的设置来处理梯度爆炸与梯度消失的问题。
ResNet :通过跳跃连接,梯度可以直接从后面的层传递到前面的层,保证了梯度稳定,并且能够有效更新所有层的权重。
退化现象:残差结构-跳跃连接

虽然我们通过数据的归一化的BN层的设置来处理梯度爆炸与梯度消失的问题,但是当网络加深的时候又会带来新的问题就是退化现象。什么是退化现象,就是通俗来说是网络性能的退化现象,可以理解为随着训练轮数(epoch)的增加,精度到达一定程度后,就开始下降了。可能有些同学会有疑问,会不会是因为出现了过拟合的现象呢?其实从图中可以清晰看出,如果出现过拟合的话就会导致训练的时候的误差会很小,测试的误差会很大,即过度的拟合了训练数据。但是我们看图,训练的时候的误差56层的也是大于20层的,所以这就不会是过拟合的现象。所以网络层数越深,训练误差越高,导致训练和测试效果变差,这一现象称为退化。
解决方法 :如果我们仅仅单纯地增加神经网络的深度,可能会引发网络模型的退化,进而导致网络早期层所捕获的特征丢失。可以这样理解,假设在层数达到40层时,模型已经达到了最佳状态,但继续增加层数,由于激活函数和卷积等操作的影响,只会增强整个网络的非线性,从而使性能下降。
其根本原因在于,通过多个非线性层来近似一个恒等映射(即恒等函数,一种对任何元素映射后与原元素相同的函数)可能是困难的。为什么恒等映射难以实现呢?我们可以简单设想,随着网络层数的增加,网络学习到的是更高层次的语义特征,但在这一学习过程中,由于激活函数的特性,例如ReLU函数在输入小于零时输出为零,这就可能导致在加深网络的过程中不可避免地丢失低层语义信息。这样一来,最终学习到的网络可能并不符合数据的真实信息分布,从而导致网络性能不佳。
为了解决深层网络中的退化问题,可以采取一种策略,即让神经网络的某些层跳过与下一层神经元的直接连接,实现隔层相连,从而减弱每层之间的紧密联系。ResNet论文中提出的残差结构(residual结构)正是为了缓解这一问题。如下图所示,采用了残差结构的卷积网络在层数不断增加的情况下,性能并没有下降,反而有所提升。(图中虚线表示训练误差,实线表示测试误差)

原理解析
残差连接从实现来看其实是非常简单的,只不过是从原来的输出F(x)变成了F(x)+x,但是要说到,为什么这么简单的一个跳跃连接就能起到这么大的作用呢?可能很多人就说不出来了。

- 普通网络:梯度传播过程中可能会因为网络层数过深,导致梯度消失或爆炸,使得网络很难训练。(当梯度变得非常小,无法有效更新权重)(当梯度非常大,导致权重更新过快)
- ResNet :反向传播时,通过跳跃连接,梯度可以直接从后面的层传递到前面的层,保证了梯度稳定,并且能够有效更新所有层的权重,避免了梯度消失
通过残差块的设计,网络能够学习到输入与输出之间的残差映射,即F(x) = y - x ,其中y是期望的映射,x是输入特征,F(x)是残差函数。这样,网络只需要学习输入与输出之间的差异,而不是直接学习整个映射,从而简化了学习目标并提高了训练效率。
为什么叫做残差网络呢?其实原本我们所学习到的函数映射为y=F(x),即我们希望F(x)能够学习到数据x的特征,保证其恒等映射,但是我们现在变成了y=F(x)+x,从而变成了y-x=F(x),我们所学习的F(x)变成了这样的形式,我们去学习数据x的特征容易还是去让F(x)趋向于0更容易,当然很显而易见了。所以残差网络为什么叫残差的原因就是体现在这里。
y = F(x) + x
这样做的动机是,在反向传播更新参数的时候,不至于因为梯度为零而无法更新。且如果恒等映射是最优的,网络只需要学习 F(x)=0F(x) = 0F(x)=0 的残差,避免了直接拟合复杂函数的难度。
深度学习-龙良曲
卷积代码


kernel [5,5,3,4] 3输入的通道数决定 4卷积核个数,输出通道数

resnet网络结构




Batch Normalization
批归一化(Batch Normalization, BN)是一种在神经网络训练过程中对每一层的激活进行标准化的技术。它通过对小批量(mini-batch)内的激活进行归一化,缓解了"内部协变量偏移"(Internal Covariate Shift)问题,从而加速训练,提高收敛速度,并有一定正则化效果。
作用:
稳定每层输入分布,加快模型学习速度:BN通过规范化与线性变换使得每一层网络的输入数据的均值与方差都在一定范围内,使得后一层网络不必不断去适应底层网络中输入的变化,从而实现了网络中层与层之间的解耦,允许每一层进行独立学习,有利于提高整个神经网络的学习速度。
支持更高学习率,减少对参数初始化的敏感性:
降低梯度消失/爆炸风险,支持更深网络结构:通过normalize操作可以让激活函数的输入数据落在梯度非饱和区,缓解梯度消失的问题;另外通过自适应学习γ与 β 又让数据保留更多的原始信息。
**BN具有一定的正则化效果:**在Batch Normalization中,由于我们使用mini-batch的均值与方差作为对整体训练样本均值与方差的估计,尽管每一个batch中的数据都是从总体样本中抽样得到,但不同mini-batch的均值与方差会有所不同,这就为网络的学习过程中增加了随机噪声


其中,x(b)i表示输入当前batch的b-th样本时该层i-th输入节点的值,xi为[x(1)i,x(2)i,...,x(m)i]构成的行向量,长度为batch size m,μ和σ为该行的均值和标准差,ϵ为防止除零引入的极小量(可忽略),γ和β为该行的scale和shift参数,可知
μ和σ为当前行的统计量,不可学习。
γ和β为待学习的scale和shift参数,用于控制yi的方差和均值
BN层中,xi和xj之间不存在信息交流(i≠j)
可见,无论xi原本的均值和方差是多少,通过BatchNorm后其均值和方差分别变为待学习的β和γ。
梯度消失和梯度爆炸

防止梯度消失和爆炸的方法:
激活函数
残差连接ResNet:
-
梯度可以直接通过跳跃连接反向传播
-
即使主路径梯度很小,仍有捷径路径传递梯度
梯度裁剪
BatchNormalize:通过normalize操作可以让激活函数的输入数据落在梯度非饱和区,缓解梯度消失的问题
权重初始化:让每层输出的方差保持稳定,避免信号在传播过程中过度放大或衰减。
Xavier、He/Kaiming 初始化
网络输出




误差计算



tensorboard可视化
tensorboard --logdir logs





keras API












validation_freq training中间验证
训练完成后验证


自定义网络层






模型保存与加载





CIFAR10

卷积
池化
卷积神经网络
感受野(Receptive Field)
感受野指的是卷积神经网络每一层输出的特征图(feature map)上每个像素点映射回输入图像上的区域大小。神经元感受野的范围越大表示其能接触到的原始图像范围就越大,也意味着它能学习更为全局,语义层次更高的特征信息;相反,范围越小则表示其所包含的特征越趋向局部和细节。因此感受野的范围可以用来大致判断每一层的抽象层次。并且我们可以很明显地知道网络越深,神经元的感受野越大。由此可知,深度卷积神经网络中靠前的层感受野较小,提取到的是图像的纹理、边缘等局部的、通用的特征;靠后的层由于感受野较大,提取到的是图像更深层次、更具象的特征。因此在迁移学习中常常会将靠前的层的参数冻结(不参与训练,因为他们在迁移到新的场景之前已经具备了提取通用特征的能力),来节省训练的时间和算力消耗。
特征图大小计算
从输入特征图到输出特征图尺寸的计算公式(其中n_in为输入size,p为padding大小,k为卷积核size,s为卷积步长stride):
n_out= (n_in + 2*p -k) / 2 +1
假设输入大小为5×5,f=3×3,padding为1×1,卷积步长为2×2,那么输出特征图size根据公式可计算为3×3。
权值共享
在卷积运算中采用权值共享可以有效减少网络参数。在一个卷积核在和一个的特征图进行卷积运算时,可以看作是用这个卷积核作为一个滑块去遍历这个特征图,卷积核的参数就叫权重,这个特征图每个位置是被同样的卷积核"扫"的,所以权重是一样的,也就是共享。
网络深度(Depth)
早期的backbone设计都是直接使用卷积层堆叠的方式,它的深度即神经网络的层数,后来的backbone设计采用了更高效的module(或block)堆叠的方式,每个module是由多个卷积层组成,它的深度也可以指module的个数
神经网络的深度决定了网络的表达能力
网络宽度(Width)
网络的宽度指的是卷积神经网络中最大的通道数,由卷积核数量最多的层决定。通常的结构设计中卷积核的数量随着层数越来越多的,直到最后一层feature map数量达到最大,这是因为越到深层,feature map的分辨率越小,所包含的信息越高级,所以需要更多的卷积核来进行学习。通道越多效果越好,但带来的计算量也会大大增加
宽度决定了网络在某一层学到的信息量
分辨率(Resolution)
分辨率指的是输入模型的图像尺寸,即长宽大小。
参数量(Params)
参数量指的网络中可学习变量的数量,包括卷积核的权重weight,批归一化(BN)的缩放系数γ,偏移系数β,有些没有BN的层可能有偏置bias,这些都是可学习的参数
计算量(FLOPs)
前向推理过程中乘加运算的次数,通常用FLOPs(即"每秒浮点运算次数")来表示,即floating point operations(浮点运算数)。
假设其输入feature map的维度是(1, iC, iH, iW),每个卷积核的维度是(1, iC, k, k),一次卷积滤波得到一层feature map的维度为(1,1, oH, oW),一共有oC个卷积核,则输出feature map的维度是(1, oC, oH, oW),计算量为iC×k×k×oC×oH×oW
卷积结构类型
标准卷积 (Convolution)
深度卷积 (Depthwise Convolution)
指的通道 。标准卷积中每个卷积核都需要与feature map的所有通道进行计算,所以每个卷积核的通道数等于输入feature map的通道数,同时通过设定卷积核的数量可以控制输出feature map的通道数。而深度卷积每个卷积核都是单通道的,维度为(1,1,k,k) ,卷积核的个数为iC(须和feature map的通道数保持一致),即第i个卷积核与feature map第i个通道进行二维的卷积计算,最后输出维度为(1,iC,oH,oW),它不能改变输出feature map的通道数,所以通常会在深度卷积后面接上一个(oC,iC,1,1)的标准卷积来代替3×3或更大尺寸的标准卷积。总的计算量为k×k×iC×oH×oW+iC×1×1×oH×oW×oC,是普通卷积的1/oC+1/(k×k),大大减少了计算量和参数量,又可以达到相同的效果,这种结构被称为深度可分离卷积(Depthwise Separable Convolution),在MobileNet V1被提出,后来渐渐成为轻量化结构设计的标配。
分组卷积 (Group Convolution)
具体计算过程是,分组卷积首先将输入feature map分成g个组,每个组的大小为(1, iC/g, iH, iW),对应每组中一个卷积核的大小是(1,iC/g,k,k),每组有oC/g个卷积核,所以每组输出feature map的尺寸为(1,oC/g,oH,oW),最终g组输出拼接得到一个(1,oC,oH,oW)的大feature map,总的计算量为iC/g×k×k×oC×oH×oW,是标准卷积的1/g,参数量也是标准卷积的1/g。
但由于feature map组与组之间相互独立,存在信息的阻隔,所以ShuffleNet提出对输出的feature map做一次channel shuffle的操作,即通道混洗,打乱原先的顺序,使得各个组之间的信息能够交互起来。
空洞卷积 (Dilated Convolution)
空洞卷积也叫扩张卷积或者膨胀卷积,是针对图像语义分割问题中下采样会降低图像分辨率、丢失信息而提出的一种卷积思路。空洞卷积有两种理解,一是可以理解为将卷积核扩展,如图下图卷积核为3×3,但是这里将卷积核变为5×5,即在卷积核每行每列中间加0;二是理解为在特征图上每隔1行或一列取数与3×3卷积核进行卷积。通过间隔取值扩大感受野,让原本3x3的卷积核,在相同参数量和计算量下拥有更大的感受野。

这里面有个扩张率(dilation rate)的系数,这个系数定义了这个间隔的大小,标准卷积相当于dilation rate为1的空洞卷积。dilation rate为1、2、4的时候卷积核感受野如下图所示:

(5) 转置卷积 (Transposed Convolutions)
转置卷积又称反卷积(Deconvolution),它和空洞卷积的思路正好相反,是为上采样而生,也应用于语义分割当中,而且他的计算也和空洞卷积正好相反,先对输入的feature map间隔补0,卷积核不变,然后使用标准的卷积进行计算,得到更大尺寸的feature map。

(6)可变形卷积 (Deformable Convolution)
以上的卷积计算都是固定的,每次输入不同的图像数据,卷积计算的位置都是完全固定不变,即使是空洞卷积/转置卷积,0填充的位置也都是事先确定的。而可变形卷积是指卷积核上对每一个元素额外增加了一个h和w方向上偏移的参数,然后根据这个偏移在feature map上动态取点来进行卷积计算,这样卷积核就能在训练过程中扩展到很大的范围。而显而易见的是可变性卷积虽然比其他卷积方式更加灵活,可以根据每张输入图片感知不同位置的信息,类似于注意力,从而达到更好的效果。

在上面这张图里面,左边传统的卷积显然没有提取到完整绵羊的特征,而右边的可变形卷积则提取到了完整的不规则绵羊的特征。
(7) 1×1卷积(Pointwise Convolution)
有些论文里用到了尺寸为1×1的卷积核,人们刚开始见到1×1卷积可能会比较困惑------对于二维的图像数据,1×1卷积似乎是没有意义的。但是在卷积神经网络中,卷积核通常是对三维feature map进行操作,这时,1×1卷积可以看作对某个局部的加权求和。1×1卷积最早出现在Network In Network的论文中 ,使用1×1卷积是想加深加宽网络结构。
1*1卷积通常有两方面作用:
- 降维:比如一张500×500且通道数为100的图片在20个filter上做1×1的卷积,输出特征图的尺寸变为500×500×20。当filter数量为200时,输出特征图的尺寸会变为500×500×200,这时实现了网络加宽,或者说是升维。
- 增加网络层的非线性:它的卷积过程其实相当于全连接层的计算过程,并且还加入了非线性的激活函数(relu等),从而使网络结构变得更加的复杂。
池化(pooling)层
(1) 最大池化(Max Pooling)和平均池化(Mean Pooling)
通常在连续的卷积层之间会周期性地插入一个池化层(也称"汇聚"层)。它的作用是逐渐降低数据体的空间尺寸,这样的话就能减少网络中参数的数量,使得计算资源耗费变少,也能有效控制过拟合。池化这个操作比较简单,一般在上采样和下采样的时候用到,没有参数,不可学习。
普通池化操作常见的有最大池化(Max Pooling)和平均池化(Mean Pooling)。 其中,最常用的是最大池化,最常见的形式是使用尺寸2x2的滤波器,以步长为2来对每个深度切片进行降采样,将其中75%的激活信息都丢掉。对更大感受野进行池化需要的池化尺寸也更大,而且往往对网络有破坏性。平均池化历史上比较常用,但是现在已经很少使用了。因为实践证明,最大池化的效果比平均池化要好。尺寸为2×2、步长为2的最大池化核平均池化的示例如下图所示:

- 关于池化层的反向传播: 对于最大池化来说,max(x,y)函数的反向传播可以简单理解为将梯度只沿最大的数回传。因此,在向前传播经过汇聚层的时候,通常会把池中最大元素的索引记录下来(有时这个也叫作道岔(switches)),这样在反向传播的时候梯度的路由就很高效。
- 关于弃用池化层: 很多人不喜欢汇聚操作,认为可以弃用它。比如在Striving for Simplicity: The All Convolutional Net一文中,提出使用一种只有重复的卷积层组成的结构,抛弃汇聚层。通过在卷积层中使用更大的步长来降低数据体的尺寸。有发现认为,在训练一个良好的生成模型时,弃用汇聚层也是很重要的。比如变化自编码器(VAEs:variational autoencoders)和生成性对抗网络(GANs:generative adversarial networks)。现在看起来,未来的卷积网络结构中,可能会很少使用甚至不使用汇聚层
(2) 全局平均池化(Global Average Pooling)
全局平均池化的操作是对一个维度为(C,H,W)的feature map,在H和W方向整个取平均,然后输出一个长度为C的向量,这个操作一般在分类模型的最后一个feature map之后出现,然后接一个全连接层就可以完成分类结果的输出了。早期的分类模型都是把最后一个feature map直接拉平成C×H×W的向量,然后再接全连接层,可以明显看出这样计算量极大,甚至有的模型最后一个全连接层占了整个模型计算量的50%以上,之后由研究人员发现对这个feature map做一个全局平均池化,然后再加全连接层可以达到相似的效果,且计算量降低到了原来的1/HW。
全连接(Full Connected)层
全连接层和常规神经网络中一样,它的本质其实就是矩阵乘法再加上偏差,输入一个(B, iC)的数据,权重为(iC, oC),那么输出为(B, oC),在多层感知机和分类模型最后一层常常见到。

Addition / Concatenate分支
Addition和Concatenate分支操作统称为shortcut,如下图所示,操作极为简单。Addition是在ResNet中提出,两个相同维度的feature map相同位置点的值直接相加,得到新的相同维度feature map,这个操作可以融合之前的特征,增加信息的表达,Concatenate操作是在Inception中首次使用,被DenseNet发扬光大,和addition不同的是,它只要求两个feature map的HW相同,通道数可以不同,然后两个feature map在通道上直接拼接,得到一个更大的feature map,它保留了一些原始的特征,增加了特征的数量,使得有效的信息流继续向后传递。

Channel shuffle
channel shuffle是ShuffleNet中首次提出,主要是针对分组卷积中不同组之间信息不流通,对不同组的feature map进行混洗的一个操作,如下图所示,假设原始的feature map维度为(1,9,H,W),被分成了3个组,每个组有三个通道,那么首先将这个feature map进行reshape操作,得到(1,3,3,H,W),然后对中间的两个大小为3的维度进行转置,依然是(1,3,3,H,W),最后将通道拉平,变回(1,9,H,W),就完成了通道混洗,使得不同组的feature map间隔保存,增强了信息的交互。

常用激活函数
激活函数的非线性
(99+ 封私信 / 80 条消息) 深度学习笔记:如何理解激活函数?(附常用激活函数) - 知乎
为什么要使用激活函数?
因为神经网络中每一层的输入输出都是一个线性求和的过程,下一层的输出只是承接了上一层输入函数的线性变换,所以如果没有激活函数,那么无论你构造的神经网络多么复杂,有多少层,最后的输出都是输入的线性组合,纯粹的线性组合并不能够解决更为复杂的问题。而引入激活函数之后,我们会发现常见的激活函数都是非线性的,因此也会给神经元引入非线性元素,使得神经网络可以逼近其他的任何非线性函数,这样可以使得神经网络应用到更多非线性模型中。
Sigmoid函数
Sigmoid函数也叫Logistic函数,用于隐层神经元输出,取值范围为(0,1),它可以将一个实数映射到(0,1)的区间,可以用来做二分类。函数的表达式如下:

Sigmoid 激活函数存在的不足:
- 梯度消失:注意:Sigmoid 函数趋近 0 和 1 的时候变化率会变得平坦,也就是说,Sigmoid 的梯度趋近于 0。神经网络使用 Sigmoid 激活函数进行反向传播时,输出接近 0 或 1 的神经元其梯度趋近于 0。这些神经元叫作饱和神经元。因此,这些神经元的权重不会更新。此外,与此类神经元相连的神经元的权重也更新得很慢。该问题叫作梯度消失。因此,想象一下,如果一个大型神经网络包含 Sigmoid 神经元,而其中很多个都处于饱和状态,那么该网络无法执行反向传播。
- 不以零为中心:Sigmoid 输出不以零为中心的,,输出恒大于0,非零中心化的输出会使得其后一层的神经元的输入发生偏置偏移(Bias Shift),并进一步使得梯度下降的收敛速度变慢。
- 计算复杂:exp() 函数与其他非线性激活函数相比,计算成本高昂,计算机运行起来速度较慢。

Tanh/双曲正切激活函数
anh 激活函数又叫作双曲正切激活函数(hyperbolic tangent activation function)。与 Sigmoid 函数类似,Tanh 函数也使用真值,但 Tanh 函数将其压缩至-1 到 1 的区间内。与 Sigmoid 不同,Tanh 函数的输出以零为中心,因为区间在-1 到 1 之间。
函数表达式:

tanh存在的不足:
- 与sigmoid类似,Tanh 函数也会有梯度消失的问题,因此在饱和时(x很大或很小时)梯度较小,这不利于权重更新
- 计算复杂
ReLU激活函数
ReLU函数又称为修正线性单元(Rectified Linear Unit),是一种分段线性函数,其弥补了sigmoid函数以及tanh函数的梯度消失问题,在目前的深度神经网络中被广泛使用。ReLU函数本质上是一个斜坡(ramp)函数,公式及函数图像如下:


优点:
- 当输入为正时,导数为1,一定程度上改善了梯度消失问题,加快梯度下降的收敛速度;
- 计算速度快得多。ReLU 函数中只存在线性关系,因此它的计算速度比 sigmoid 和 tanh 更快。
ReLU函数的不足:
- Dead ReLU 问题。当输入为负时,ReLU 完全失效,在正向传播过程中,这不是问题。有些区域很敏感,有些则不敏感。但是在反向传播过程中,如果输入负数,则梯度将完全为零;
**【Dead ReLU问题】**ReLU神经元在训练时比较容易"死亡"。在训练时,如果参数在一次不恰当的更新后,第一个隐藏层中的某个ReLU 神经元在所有的训练数据上都不能被激活,那么这个神经元自身参数的梯度永远都会是0,在以后的训练过程中永远不能被激活。这种现象称为死亡ReLU问题,并且也有可能会发生在其他隐藏层。
- 不以零为中心:和 Sigmoid 激活函数类似,ReLU 函数的输出不以零为中心,ReLU 函数的输出为 0 或正数,给后一层的神经网络引入偏置偏移,会影响梯度下降的效率。
Leaky ReLU
为了解决 ReLU 激活函数中的梯度消失问题,当 x < 0 时,我们使用 Leaky ReLU------该函数试图修复 dead ReLU 问题。下面我们就来详细了解 Leaky ReLU。
函数表达式以及图像如下:

其中 r是一个很小的数,如0.1,0.01等等。这里,令 r=0.1进行展示:
为什么使用Leaky ReLU会比ReLU效果要好呢?
- Leaky ReLU 通过把 x 的非常小的线性分量给予负输入(0.01x)来调整负值的零梯度(zero gradients)问题,当 x < 0 时,它得到 0.1 的正梯度。该函数一定程度上缓解了 dead ReLU 问题,
- leak 有助于扩大 ReLU 函数的范围,通常 a 的值为 0.01 左右;
- Leaky ReLU 的函数范围是(负无穷到正无穷)
尽管Leaky ReLU具备 ReLU 激活函数的所有特征(如计算高效、快速收敛、在正区域内不会饱和),但并不能完全证明在实际操作中Leaky ReLU 总是比 ReLU 更好。

相当于是一个比较简单的Maxout单元(Maxout函数会在下面讲解)
为什么使用Leaky ReLU会比ReLU效果要好呢?
- Leaky ReLU 通过把 x 的非常小的线性分量给予负输入(0.01x)来调整负值的零梯度(zero gradients)问题,当 x < 0 时,它得到 0.1 的正梯度。该函数一定程度上缓解了 dead ReLU 问题,
- leak 有助于扩大 ReLU 函数的范围,通常 a 的值为 0.01 左右;
- Leaky ReLU 的函数范围是(负无穷到正无穷)
尽管Leaky ReLU具备 ReLU 激活函数的所有特征(如计算高效、快速收敛、在正区域内不会饱和),但并不能完全证明在实际操作中Leaky ReLU 总是比 ReLU 更好。
