CNN
1. CNN的结构
卷积神经网络(Convolutional Neural Networks, CNN),以手写数字识别为例,整个识别的过程如下所示:

可以看到整个过程需要在如下几层进行运算:
- 输入层:输入图像等信息
- 卷积层:用来提取图像的底层特征
- 池化层:防止过拟合,将数据维度减小
- 全连接层:汇总卷积层和池化层得到的图像的底层特征和信息
- 输出层:根据全连接层的信息得到概率最大的结果
可以看到其中最重要的一层就是卷积层,这也是卷积神经网络名称的由来。
一. 输入层
输入层比较简单,这一层的主要工作就是输入图像等信息,因为卷积神经网络主要处理的是图像相关的内容,对于输入图像,首先要将其转换为对应的二维矩阵,这个二位矩阵就是由图像每一个像素的像素值大小组成的。

日常生活中最常见的就是RGB图像,有三个通道,分别是红色、绿色、蓝色。每个通道的每个像素值的范围也是0~255,
input.shape = (c, h, w)
输入层的作用就是将图像转换为其对应的由像素值构成的二维矩阵,并将此二维矩阵存储,等待后面几层的操作。
二. 卷积层
假设我们已经得到图片的二维矩阵了,想要提取其中特征,那么卷积操作就会为存在特征的区域确定一个高值,否则确定一个低值。这个过程需要通过计算其与卷积核(Convolution Kernel)的卷积值来确定。通过整个卷积过程又得到一个新的二维矩阵,此二维矩阵也被称为特征图(Feature Map)

整个过程就是一个降维的过程,通过卷积核的不停移动计算,可以提取图像中最有用的特征。
卷积参数:
-
padding
在原始的输入图像的二维矩阵周围再拓展一圈或者几圈,拓展圈数为padding数

-
stride
滑动步长,决定每次间隔多少步进行卷积 -
卷积计算公式
import numpy as np
def conv2d(image, kernel, stride=1, padding=0):
# 获取图像和卷积核的尺寸
image_height, image_width = image.shape
kernel_height, kernel_width = kernel.shape
# 在图像上添加填充
padded_image = np.pad(image, ((padding, padding), (padding, padding)), mode='constant')
# 计算输出图像的尺寸
output_height = (image_height + 2 * padding - kernel_height) // stride + 1
output_width = (image_width + 2 * padding - kernel_width) // stride + 1
# 创建输出图像
output = np.zeros((output_height, output_width))
# 进行卷积操作
for i in range(output_height):
for j in range(output_width):
# 计算当前卷积窗口的起始位置
start_i = i * stride
start_j = j * stride
# 对应区域的元素乘以卷积核并求和
output[i, j] = np.sum(padded_image[start_i:start_i + kernel_height, start_j:start_j + kernel_width] * kernel)
return output

三. 池化层
池化层又称为下采样,也就是说,当我们进行卷积操作后,再将得到的特征图进行特征提取,将其中最具有代表性的特征提取出来,可以起到减小过拟合和降低维度的作用,通常有两种方法:
-
最大池化
最大池化就是每次取正方形中所有值的最大值,这个最大值也就相当于当前位置最具有代表性的特征,这个过程如下所示:

-
平均池化
平均池化就是取此正方形区域中所有值的平均值,考虑到每个位置的值对于此处特征的影响,平均池化计算也比较简单,整个过程如下图所示:

池化层的作用:
- 在减少参数量的同时,还保留了原图像的原始特征
- 有效防止过拟合
- 为卷积神经网络带来平移不变性
四. 全连接层
将提取到的所有特征图进行“展平”,将其维度变为1 × x 1×x1×x,这个过程就是全连接的过程。

五. 输出层
将全连接层得到的一维向量经过计算后得到识别值的一个概率,这个计算可能是线性的,也可能是非线性的。在深度学习中,我们需要识别的结果一般都是多分类的,所以每个位置都会有一个概率值,代表识别为当前值的概率,取最大的概率值,就是最终的识别结果:

2. CNN的作用
什么是卷积神经网络:
卷积神经网络是一种带有卷积结构的深度神经网络,卷积结构可以减少深层网络占用的内存量,其三个关键的操作,其一是局部感受野,其二是权值共享,其三是pooling层,有效的减少了网络的参数个数,缓解了模型的过拟合问题。
一. 网络结构
卷积神经网络整体架构: 卷积神经网络是一种多层的监督学习神经网络,隐含层的卷积层和池采样层是实现卷积神经网络特征提取功能的核心模块。该网络模型通过采用梯度下降法最小化损失函数对网络中的权重参数逐层反向调节,通过频繁的迭代训练提高网络的精度。卷积神经网络的低隐层是由卷积层和最大池采样层交替组成,高层是全连接层对应传统多层感知器的隐含层和逻辑回归分类器。第一个全连接层的输入是由卷积层和子采样层进行特征提取得到的特征图像。最后一层输出层是一个分类器,可以采用逻辑回归,Softmax回归甚至是支持向量机对输入图像进行分类。
卷积神经网络结构包括:卷积层,降采样层,全链接层。每一层有多个特征图,每个特征图通过一种卷积滤波器提取输入的一种特征,每个特征图有多个神经元。
输入图像统计和滤波器进行卷积之后,提取该局部特征,一旦该局部特征被提取出来之后,它与其他特征的位置关系也随之确定下来了,每个神经元的输入和前一层的局部感受野相连,每个特征提取层都紧跟一个用来求局部平均与二次提取的计算层,也叫特征映射层,网络的每个计算层由多个特征映射平面组成,平面上所有的神经元的权重相等。
通常将输入层到隐藏层的映射称为一个特征映射,也就是通过卷积层得到特征提取层,经过pooling之后得到特征映射层。
二. 局部感受野与权值共享
卷积神经网络的核心思想就是局部感受野、是权值共享和pooling层,以此来达到简化网络参数并使得网络具有一定程度的位移、尺度、缩放、非线性形变稳定性。
局部感受野:由于图像的空间联系是局部的,每个神经元不需要对全部的图像做感受,只需要感受局部特征即可,然后在更高层将这些感受得到的不同的局部神经元综合起来就可以得到全局的信息了,这样可以减少连接的数目。
权值共享:不同神经元之间的参数共享可以减少需要求解的参数,使用多种滤波器去卷积图像就会得到多种特征映射。权值共享其实就是对图像用同样的卷积核进行卷积操作,也就意味着第一个隐藏层的所有神经元所能检测到处于图像不同位置的完全相同的特征。其主要的能力就能检测到不同位置的同一类型特征,也就是卷积网络能很好的适应图像的小范围的平移性,即有较好的平移不变性(比如将输入图像的猫的位置移动之后,同样能够检测到猫的图像)
卷积层、下采样层、全连接层
-
卷积层:因为通过卷积运算我们可以提取出图像的特征,通过卷积运算可以使得原始信号的某些特征增强,并且降低噪声。
用一个可训练的滤波器fx去卷积一个输入的图像(第一阶段是输入的图像,后面的阶段就是卷积特征map了),然后加一个偏置bx,得到卷积层Cx。 -
下采样层:因为对图像进行下采样,可以减少数据处理量同时保留有用信息,采样可以混淆特征的具体位置,因为某个特征找出来之后,它的位置已经不重要了,我们只需要这个特征和其他特征的相对位置,可以应对形变和扭曲带来的同类物体的变化。
每邻域四个像素求和变为一个像素,然后通过标量Wx+1加权,再增加偏置bx+1,然后通过一个sigmoid激活函数,产生一个大概缩小四倍的特征映射图Sx+1。 -
全连接层:采用softmax全连接,得到的激活值即卷积神经网络提取到的图片特征。
卷积神经网络相比一般神经网络在图像理解中的优点:
- 网络结构能够较好的适应图像的结构
- 同时进行特征提取和分类,使得特征提取有助于特征分类
- 权值共享可以减少网络的训练参数,使得神经网络结构变得简单,适应性更强
如何利用CNN实现图像识别的任务
输入层读入经过规则化(统一大小)的图像,每一层的每个神经元将前一层的一组小的局部近邻的单元作为输入,也就是局部感受野和权值共享,神经元抽取一些基本的视觉特征,比如边缘、角点等,这些特征之后会被更高层的神经元所使用。卷积神经网络通过卷积操作获得特征图,每个位置,来自不同特征图的单元得到各自不同类型的特征。一个卷积层中通常包含多个具有不同权值向量的特征图,使得能够保留图像更丰富的特征。卷积层后边会连接池化层进行降采样操作,一方面可以降低图像的分辨率,减少参数量,另一方面可以获得平移和形变的鲁棒性。卷积层和池化层的交替分布,使得特征图的数目逐步增多,而且分辨率逐渐降低,是一个双金字塔结构。
CNN的特征
- 具有一些传统技术所没有的优点:良好的容错能力、并行处理能力和自学习能力,可处理环境信息复杂,背景知识不清楚,推理规则不明确情况下的问题,允许样品有较大的缺损、畸变,运行速度快,自适应性能好,具有较高的分辨率。它是通过结构重组和减少权值将特征抽取功能融合进多层感知器,省略识别前复杂的图像特征抽取过程。
- 泛化能力要显著优于其它方法,卷积神经网络已被应用于模式分类,物体检测和物体识别等方面。利用卷积神经网络建立模式分类器,将卷积神经网络作为通用的模式分类器,直接用于灰度图像。
- 是一个前溃式神经网络,能从一个二维图像中提取其拓扑结构,采用反向传播算法来优化网络结构,求解网络中的未知参数。
- 一类特别设计用来处理二维数据的多层神经网络。CNN被认为是第一个真正成功的采用多层层次结构网络的具有鲁棒性的深度学习方法。CNN通过挖掘数据中的空间上的相关性,来减少网络中的可训练参数的数量,达到改进前向传播网络的反向传播算法效率,因为CNN需要非常少的数据预处理工作,所以也被认为是一种深度学习的方法。在CNN中,图像中的小块区域(也叫做“局部感知区域”)被当做层次结构中的底层的输入数据,信息通过前向传播经过网络中的各个层,在每一层中都由过滤器构成,以便能够获得观测数据的一些显著特征。因为局部感知区域能够获得一些基础的特征,比如图像中的边界和角落等,这种方法能够提供一定程度对位移、拉伸和旋转的相对不变性。
- CNN中层次之间的紧密联系和空间信息使得其特别适用于图像的处理和理解,并且能够自动的从图像抽取出丰富的相关特性。
- CNN通过结合局部感知区域、共享权重、空间或者时间上的降采样来充分利用数据本身包含的局部性等特征,优化网络结构,并且保证一定程度上的位移和变形的不变性。
- CNN是一种深度的监督学习下的机器学习模型, 具有极强的适应性, 善于挖掘数据局部特征,提取全局训练特征和分类,它的权值共享结构网络使之更类似于生物神经网络,在模式识别各个领域都取得了很好的成果。
- CNN可以用来识别位移、缩放及其它形式扭曲不变性的二维或三维图像。CNN的特征提取层参数是通过训练数据学习得到的,所以其避免了人工特征提取,而是从训练数据中进行学习;其次同一特征图的神经元共享权值,减少了网络参数,这也是卷积网络相对于全连接网络的一大优势。共享局部权值这一特殊结构更接近于真实的生物神经网络使CNN在图像处理、语音识别领域有着独特的优越性,另一方面权值共享同时降低了网络的复杂性,且多维输入信号(语音、图像)可以直接输入网络的特点避免了特征提取和分类过程中数据重排的过程。
- CNN的分类模型与传统模型的不同点在于其可以直接将一幅二维图像输入模型中,接着在输出端即给出分类结果。其优势在于不需复杂的预处理,将特征抽取,模式分类完全放入一个黑匣子中,通过不断的优化来获得网络所需参数,在输出层给出所需分类,网络核心就是网络的结构设计与网络的求解。这种求解结构比以往多种算法性能更高。
- 隐层的参数个数和隐层的神经元个数无关,只和滤波器的大小和滤波器种类的多少有关。隐层的神经元个数,它和原图像,也就是输入的大小(神经元个数)、滤波器的大小和滤波器在图像中的滑动步长都有关。
RNN
在实际应用中,会遇到很多序列形的数据:
如:
- 自然语言处理问题。x1可以看做是第一个单词, x2可以看做是第二个单词, 依次类推
- 语音处理。此时, x1、x2、x3……是每帧的声音信号。
- 时间序列问题。例如每天的股票价格等等
而其中,序列形的数据就不太好用原始的神经网络处理了。
1.RNN结构
为了建模序列问题,RNN引入了隐状态h(hidden state)的概念,隐状态h可以对序列形的数据提取特征,接着再转换为输出。
有两点需要注意下:
在计算时,每一步使用的参数U,W,bU, W, bU,W,b 都是一样的,也就是说每个步骤的参数都是共享的,这是RNN的重要特点,RNN的权值为何共享呢?很简单,因为RNN的权值是在同一个向量中,只是不同时刻而已.

计算公式:
ht=f(Uxt+Wht−1+b)yt=g(Vht+c)
h_t = f\left( Ux_t+Wh_{t-1}+b\right)\\
y_t = g(Vh_t+c)
ht=f(Uxt+Wht−1+b)yt=g(Vht+c)
RNN会有多个输出,这里如果要使用BP的话一定是要考虑到时间的,因此RNN的BP叫做时间反向传播-BPTT(Back Propagation Through Time)
∂L∂U=∑t=1T∑k=1t∂Lt∂y^t×∂y^t∂ht(∏i=k+1t∂ht∂ht−1)×∂hk∂U∂L∂W=∑t=1T∑k=1t∂Lt∂y^t×∂y^t∂ht(∏i=k+1t∂ht∂ht−1)×∂hk∂W∂L∂V=∑t=1T∂Lt∂y^t×∂y^t∂V∂ht∂ht−1=f′×W
\frac{\partial L}{\partial U} = \sum_{t=1}^T\sum_{k=1}^t\frac{\partial L_t}{\partial \hat{y}_t}\times\frac{\partial \hat{y}_t}{\partial h_t}\left(\prod_{i=k+1}^t \frac{\partial h_t}{\partial h_{t-1}}\right)\times \frac{\partial h_k}{\partial U}\\
\frac{\partial L}{\partial W} = \sum_{t=1}^T\sum_{k=1}^t\frac{\partial L_t}{\partial \hat{y}_t}\times\frac{\partial \hat{y}_t}{\partial h_t}\left(\prod_{i=k+1}^t \frac{\partial h_t}{\partial h_{t-1}}\right)\times \frac{\partial h_k}{\partial W}\\
\frac{\partial L}{\partial V} = \sum_{t=1}^T\frac{\partial L_t}{\partial \hat{y}_t}\times \frac{\partial \hat{y}_t}{\partial V}\\
\frac{\partial h_t}{\partial h_{t-1}} = f'\times W
∂U∂L=t=1∑Tk=1∑t∂y^t∂Lt×∂ht∂y^t(i=k+1∏t∂ht−1∂ht)×∂U∂hk∂W∂L=t=1∑Tk=1∑t∂y^t∂Lt×∂ht∂y^t(i=k+1∏t∂ht−1∂ht)×∂W∂hk∂V∂L=t=1∑T∂y^t∂Lt×∂V∂y^t∂ht−1∂ht=f′×W
梯度爆炸和梯度消失问题
在 WWW 和 UUU 中,存在一个连乘
∏i=k+1t∂ht∂ht−1
\prod_{i=k+1}^t \frac{\partial h_t}{\partial h_{t-1}}
i=k+1∏t∂ht−1∂ht
也就是说,会出现指数级别的问题;如果 ∂ht∂ht−1>1\frac{\partial h_t}{\partial h_{t-1}} > 1∂ht−1∂ht>1的话,那么连乘的结果可能会快速增长,导致梯度爆炸。
如果 ∂ht∂ht−1<1\frac{\partial h_t}{\partial h_{t-1}} < 1∂ht−1∂ht<1的话,连乘的结果会迅速衰减到零,导致梯度消失.
当梯度非常小时,反向传播的权重更新公式:
ΔW=−α⋅∂L∂W
\Delta W = -\alpha \cdot \frac{\partial L}{\partial W}
ΔW=−α⋅∂W∂L
梯度项 ∂L∂W\frac{\partial L}{\partial W}∂W∂L
会非常小。这里 α\alphaα 是学习率。当梯度接近零时,权重更新 $ \Delta W$ 也会接近零。这意味着神经网络的权重几乎不会发生变化,导致模型无法从训练数据中学习到有用的信息,从而无法有效捕捉长期依赖关系。

换言之,在递归神经网络中,获得小梯度更新的层会停止学习—— 那些通常是较早的层。 由于这些层不学习,RNN会忘记它在较长序列中以前看到的内容,因此RNN只具有短时记忆。
LSTM
长短期记忆网络(Long Short-Term Memory, LSTM)是一种特殊类型的循环神经网络(RNN),由 Hochreiter 和 Schmidhuber 于 1997 年提出。LSTM 旨在解决传统 RNN 在处理长序列数据时遇到的梯度消失或梯度爆炸问题。
LSTM 网络的核心是三个门的机制:遗忘门(forget gate)、输入门(input gate)、输出门(output gate)。这些门通过自适应的方式

上图中,σ表示的Sigmoid 激活函数与 tanh 函数类似,不同之处在于 sigmoid 是把值压缩到0~1 之间而不是 -1~1 之间。这样的设置有助于更新或忘记信息:
因为任何数乘以 0 都得 0,这部分信息就会剔除掉;
同样的,任何数乘以 1 都得到它本身,这部分信息就会完美地保存下来
相当于要么是1则记住,要么是0则忘掉,所以还是这个原则:因记忆能力有限,记住重要的,忘记无关紧要的。
LSTM的关键就是细胞状态,水平线在图上方贯穿运行。
细胞状态类似于传送带。直接在整个链上运行,只有一些少量的线性交互。信息在上面流传保持不变会很容易。
LSTM有通过精心设计的称作为“门”的结构来去除或者增加信息到细胞状态的能力。门是一种让信息选择式通过的方法。他们包含一个sigmoid神经网络层和一个pointwise乘法的非线性操作。
如此,0代表“不许任何量通过”,1就指“允许任意量通过”!从而使得网络就能了解哪些数据是需要遗忘,哪些数据是需要保存。
LSTM拥有三种类型的门结构:遗忘门/忘记门、输入门和输出门,来保护和控制细胞状态。下面,我们来介绍这三个门。
1.遗忘门
在我们LSTM中的第一步是决定我们会从细胞状态中丢弃什么信息。这个决定通过一个称为“忘记门”的结构完成。该忘记门会读取上一个输出ht−1h_{t-1}ht−1和当前输入xtx_txt,做一个Sigmoid的非线性映射,然后输出一个向量ftf_tft(该向量每一个维度的值都在0到1之间,1表示完全保留,0表示完全舍弃,相当于记住了重要的,忘记了无关紧要的),最后与细胞状态Ct−1C_{t-1}Ct−1相乘。
类比到语言模型的例子中,则是基于已经看到的预测下一个词。在这个问题中,细胞状态可能包含当前主语的性别,因此正确的代词可以被选择出来。当我们看到新的主语,我们希望忘记旧的主语,进而决定丢弃信息。

2.输入门
下一步是确定什么样的新信息被存放在细胞状态中。这里包含两个部分:
第一,sigmoid层称“输入门层”决定什么值我们将要更新;
第二,一个tanh层创建一个新的候选值向量Ct~\widetilde{C_t}Ct,会被加入到状态中。
在我们语言模型的例子中,我们希望增加新的主语的性别到细胞状态中,来替代旧的需要忘记的主语,进而确定更新的信息。

3.细胞状态
更新旧细胞状态Ct−1C_{t-1}Ct−1为CtC_tCt。我们把旧状态Ct−1C_{t-1}Ct−1与ftf_tft相乘,丢弃掉我们确定需要丢弃的信息,接着加上it∗Ct~i_t*\widetilde{C_t}it∗Ct。这就是新的候选值,根据我们决定更新每个状态的程度进行变化。
在语言模型的例子中,这就是我们实际根据前面确定的目标,丢弃旧代词的性别信息并添加新的信息的地方,类似更新细胞状态。

4.输出门
最终,我们需要确定输出什么值。这个输出将会基于我们的细胞状态,但是也是一个过滤后的版本。
首先,我们运行一个sigmoid层来确定细胞状态的哪个部分将输出出去。
接着,我们把细胞状态通过tanh进行处理(得到一个在-1到1之间的值)并将它和sigmoid门的输出相乘,最终我们仅仅会输出我们确定输出的那部分。
在语言模型的例子中,因为他就看到了一个代词,可能需要输出与一个动词相关的信息。例如,可能输出是否代词是单数还是负数,这样如果是动词的话,我们也知道动词需要进行的词形变化,进而输出信息。

LSTM的核心技术优势在于其能够学习长期依赖关系,这一点在自然语言处理(NLP)、语音识别、时间序列预测等多个领域得到了广泛应用。例如,在语言模型中,LSTM能够捕捉到文本中的语法和语义信息,为机器翻译、文本摘要等任务提供了强大的支持。
现在来解释一下,为什么说RNN和DNN的梯度消失问题含义不一样?
先来说DNN中的反向传播:在DNN梯度消失及梯度爆炸的文章中,我推导了两个权重的梯度,第一个梯度是直接连接着输出层的梯度,求解起来并没有梯度消失或爆炸的问题,因为它没有连乘,只需要计算一步。第二个梯度出现了连乘,也就是说越靠近输入层的权重,梯度消失或爆炸的问题越严重,可能就会消失会爆炸。一句话总结一下,DNN中各个权重的梯度是独立的,该消失的就会消失,不会消失的就不会消失。
再来说RNN:RNN的特殊性在于,它的权重是共享的。抛开VVV不谈,因为它在某时刻的梯度不会出现问题(某时刻并不依赖于前面的时刻),但是UUU和WWW就不一样了,每一时刻都由前面所有时刻共同决定,是一个相加的过程,这样的话就有个问题,当距离长了,计算最前面的导数时,最前面的导数就会消失或爆炸,而当前时刻整体的梯度并不会消失,因为它是求和的过程,当下的梯度总会在,只是前面的梯度没了,因此更新时,由于权值共享,所以整体的梯度还是会更新,通常人们所说的梯度消失就是指的这个,指的是当下梯度更新时,用不到前面的信息了,因为距离长了,前面的梯度就会消失,也就是没有前面的信息了,但要知道,整体的梯度并不会消失因为当下的梯度还在,并没有消失。
一句话概括:RNN的梯度不会消失,RNN的梯度消失指的是当下梯度用不到前面的梯度了,但DNN靠近输入的权重对应的梯度是真的会消失。RNN 所谓梯度消失的真正含义是,梯度被近距离梯度主导,导致模型难以学到远距离的依赖关系。
激活函数Activation Function
激活函数(Activation Function)是一种添加到人工神经网络中的函数,旨在帮助网络学习数据中的复杂模式。类似于人类大脑中基于神经元的模型,激活函数最终决定了要发射给下一个神经元的内容。
在人工神经网络中,激活函数扮演了非常重要的角色,其主要作用是对所有的隐藏层和输出层添加一个非线性的操作,使得神经网络的输出更为复杂、表达能力更强。
在神经网络中,激活函数决定来自给定输入集的节点的输出,其中非线性激活函数允许网络复制复杂的非线性行为。正如绝大多数神经网络借助某种形式的梯度下降进行优化,激活函数需要是可微分(或者至少是几乎完全可微分的)。此外,复杂的激活函数也许产生一些梯度消失或爆炸的问题。因此,神经网络倾向于部署若干个特定的激活函数(identity、sigmoid、ReLU 及其变体)。
1.sigmoid
sigmoid:f(x)=11+e−x,f′(x)=e−x(1+e−x)2=f(x)(1−f(x))
sigmoid:f(x)=\frac{1}{1+e^{-x}},f'(x) = \frac{e^{-x}}{(1+e^{-x})^2}=f(x)\left(1-f(x)\right)
sigmoid:f(x)=1+e−x1,f′(x)=(1+e−x)2e−x=f(x)(1−f(x))

Sigmoid优点:
-
其值域为[0,1],非常适合作为模型的输出函数用于输出一个(0,1)范围内的概率值,可用于将预测概率作为输出的模型,比如用于表示二分类的类别或者用于表示置信度。
-
Sigmoid 函数的输出范围是 0 到 1。由于输出值限定在0到1,因此它对每个神经元的输出进行了归一化。
-
该函数是连续可导的(即可微),可以提供非常平滑的梯度值,防止模型训练过程中出现突变的梯度(即避免「跳跃」的输出值)。
Sigmoid不足:
-
从其导数的函数图像上可以看到,其导数的最大值只有0.25,而且当x在[-5,5]的范围外时其导数值就已经几乎接近于0了。这种情况会导致训练过程中神经元处于一种饱和状态,反向传播时其权重几乎得不到更新,从而使得模型变得难以训练,这种现象被称为梯度消失问题。
-
其输出不是以0为中心而是都大于0的(这会降低权重更新的效率),这样下一层的神经元会得到上一层输出的全正信号作为输入,所以Sigmoid激活函数不适合放在神经网络的前面层而一般是放在最后的输出层中使用。
-
需要进行指数运算(计算机运行得较慢),计算量大及计算复杂度高,训练耗时;指数的越大其倒数就越小,容易产生梯度消失。
2.Tanh
Tanh:f(x)=ex−e−xex+e−x,f′(x)=4(ex+e−x)2=1−[f(x)]2
Tanh:f(x) = \frac{e^{x}-e^{-x}}{e^{x}+e^{-x}},f'(x)=\frac{4}{(e^x+e^{-x})^2}=1-\left[f(x)\right]^2
Tanh:f(x)=ex+e−xex−e−x,f′(x)=(ex+e−x)24=1−[f(x)]2

Tanh优点:
-
在分类任务中,双曲正切函数(Tanh)逐渐取代 Sigmoid 函数作为标准的激活函数,其具有很多神经网络所钟爱的特征。它是完全可微分的,反对称,对称中心在原点。
-
输出是S型曲线,具备打破网络层与网络层之间的线性关系,可以把网络层输出非线形地映射到 (−1,1) 区间里。负输入将被强映射为负,而零输入被映射为接近零;tanh 的输出间隔为1且值域是以0为中心的[-1,1](可以解决Sigmoid激活函数输出不以0为中心的问题。)
-
在一般的二元分类问题中,tanh 函数用于隐藏层,而 sigmoid 函数用于输出层,但这并不是固定的,需要根据特定问题进行调整。
Tanh不足:
-
当输入较大或较小时,输出几乎是平滑的并且梯度较小,这不利于权重更新。
-
Tanh函数也需要进行指数运算,所以其也会存在计算复杂度高且计算量大的问题。
-
当神经网络的层数增多的时候,由于在进行反向传播的时候,链式求导,多项相乘,函数进入饱和区(导数接近于零的地方)就会逐层传递,这种现象被称为梯度消失。
ReLU(Rectified Linear Unit)
ReLU:f(x)={x,x≥00,x<0,f′(x)={1,x≥00,x<0
ReLU: f(x)=\begin{cases}x,\quad x\geq0\\0,\quad x<0\end{cases},\qquad f'(x)=\begin{cases}1,\quad x\geq0\\0,\quad x<0\end{cases}
ReLU:f(x)={x,x≥00,x<0,f′(x)={1,x≥00,x<0

ReLU函数:
-
ReLU 函数在正输入时是线性的,收敛速度快,计算速度快,同时符合恒等性的特点。当输入为正时,由于导数是1,能够完整传递梯度,不存在梯度消失的问题(梯度饱和问题)。
-
计算速度快。ReLU 函数中只存在线性关系且无论是函数还是其导数都不包含复杂的数学运算,因此它的计算速度比 sigmoid 和 tanh 更快。
-
当输入大于0时,梯度为1,能够有效避免链式求导法则梯度相乘引起的梯度消失和梯度爆炸;计算成本低。
-
它保留了 step 函数的生物学启发(只有输入超出阈值时神经元才激活),不过当输入为正的时候,导数不为零,从而允许基于梯度的学习(尽管在 x=0 的时候,导数是未定义的)。当输入为负值的时候,ReLU 的学习速度可能会变得很慢,甚至使神经元直接无效,因为此时输入小于零而梯度为零,从而其权重无法得到更新,在剩下的训练过程中会一直保持静默。
ReLU不足:
-
ReLU的输入值为负的时候,输出始终为0,其一阶导数也始终为0,这样会导致神经元不能更新参数,也就是神经元不学习了,这种现象叫做“Dead Neuron”。为了解决ReLU函数这个缺点,在ReLU函数的负半区间引入一个泄露(Leaky)值,所以称为Leaky ReLU函数。
-
与Sigmoid一样,其输出不是以0为中心的(ReLU的输出为0或正数)。
-
ReLU在小于0的时候梯度为零,导致了某些神经元永远被抑制,最终造成特征的学习不充分;这是典型的 Dead ReLU 问题,所以需要改进随机初始化,避免将过多的负数特征送入ReLU。
Leaky ReLU
LeakyReLU:f(x)={x,x≥0λx,x<0,f′(x)={1,x≥0λ,x<0λ∈(0,1)
LeakyReLU: f(x)=\begin{cases}x,\quad x\geq0\\\lambda x,\quad x<0\end{cases},\qquad f'(x)=\begin{cases}1,\quad x\geq0\\\lambda,\quad x<0\end{cases}\qquad \lambda \in (0,1)
LeakyReLU:f(x)={x,x≥0λx,x<0,f′(x)={1,x≥0λ,x<0λ∈(0,1)

Leaky ReLU函数(ReLU的改进):
-
与ReLU函数相比,把x的非常小的线性分量给予负输入(0.01x)来调整负值的零梯度问题;有助于扩大 ReLU 函数的范围,通常𝜆λ的值为 0.01 左右;函数范围是负无穷到正无穷。
-
LeakyRelu激活函数通过在负半轴添加一个小的正斜率(使得负轴的信息不会全部丢失)来解决ReLU激活函数的“死区”问题,该斜率参数𝜆λ是手动设置的超参数,一般设置为0.01。通过这种方式,LeakyRelu激活函数可以确保模型训练过程中神经元的权重在输入小于0的情况下依然会得到更新。
-
不会出现 Dead ReLu 问题,但是关于输入函数f(x) 的部分容易出现梯度爆炸的情况是一样的,所以必要时,也可以搭配 sigmoid 或 tanh 使用。
Leaky ReLU不足:
-
经典(以及广泛使用的)ReLU 激活函数的变体,带泄露修正线性单元(Leaky ReLU)的输出对负值输入有很小的坡度。由于导数总是不为零,这能减少静默神经元的出现,允许基于梯度的学习(虽然会很慢)。
-
从理论上讲,Leaky ReLU 具有 ReLU 的所有优点,而且 Dead ReLU 不会有任何问题,但在实际操作中,尚未完全证明 Leaky ReLU 总是比 ReLU 更好。
PReLU
PReLU:f(x)={x,x≥0αx,x<0,f′(x)={1,x≥0α,x<0α可训练参数
PReLU: f(x)=\begin{cases}x,\quad x\geq0\\\alpha x,\quad x<0\end{cases},\qquad f'(x)=\begin{cases}1,\quad x\geq0\\\alpha,\quad x<0\end{cases}\qquad \alpha可训练参数
PReLU:f(x)={x,x≥0αx,x<0,f′(x)={1,x≥0α,x<0α可训练参数

PReLU函数(ReLU的改进):
1、在负值域,PReLU的斜率较小,这也可以避免Dead ReLU问题。与ELU相比,PReLU在负值域是线性运算。尽管斜率很小,但不会趋于0。
2、公式与Leaky ReLu相似,但并不完全一样。𝛼可以是常数,或自适应调整的参数。也就是说,如果让a自适应,那么PReLu会在反向传播时更新参数a。
3、参数α通常为0到1之间的数字,并且通常相对较小。
(1)如果𝛼 = 0,则f(x)变为ReLU。
(2)如果𝛼 > 0,则f(x)变为leaky ReLU。
(3)如果𝛼是可学习的参数,则f(x)变为PReLU。
GELU
GELU:f(x)=x∗P(X≤x)=x∗Φ(x)=x∗∫−∞xe−(X−μ)22σ22πσ2dXf(x)≈0.5x[1+tanh(2π(x+0.047715x3))]≈x∗sigmoid(1.702x)
GELU:f(x) = x*P(X\leq x) = x*\Phi(x)=x*\int_{-\infty}^{x}\frac{e^{-\frac{(X-\mu)^2}{2\sigma^2}}}{\sqrt{2\pi}\sigma^2}dX\\
f(x)\approx0.5x\left[1+tanh\left(\sqrt{\frac{2}{\pi}}\left(x+0.047715x^3\right)\right)\right]\approx x*sigmoid(1.702x)
GELU:f(x)=x∗P(X≤x)=x∗Φ(x)=x∗∫−∞x2πσ2e−2σ2(X−μ)2dXf(x)≈0.5x[1+tanh(π2(x+0.047715x3))]≈x∗sigmoid(1.702x)

GELU优点:
-
当方差为无穷大,均值为0的时候,GeLU就等价于ReLU了。GELU可以当作为RELU的一种平滑策略。GELU是非线性输出,具有一定的连续性。GELU有一个概率解释,因为它是一个随机正则化器的期望。
-
研究学者尝试使用一个依赖于输入本身的概率统计量为激活函数提供随机正则性,同时保持输入信息,得到了一个更好的激活函数,即高斯误差线性单元,形式如下:
GELU:f(x)=x∗P(X≤x)=x∗Φ(x) GELU:f(x) = x*P(X\leq x) = x*\Phi(x) GELU:f(x)=x∗P(X≤x)=x∗Φ(x)
由于上面这个函数是无法直接计算的,研究者在研究过程中发现GELU函数可以被近似地表示为
f(x)≈0.5x[1+tanh(2π(x+0.047715x3))] f(x)\approx0.5x\left[1+tanh\left(\sqrt{\frac{2}{\pi}}\left(x+0.047715x^3\right)\right)\right] f(x)≈0.5x[1+tanh(π2(x+0.047715x3))] -
GELU的实用技巧。首先,建议在使用GELU训练时使用具有动量的优化器,这是深度神经网络的标准。其次,使用对高斯分布的累积分布函数的密切近似是很重要的。
Swish
Swish:f(x)=x∗sigmoid(βx),f′(x)=xf(βx)(1−f(βx))+f(βx)
Swish:f(x)=x*sigmoid(\beta x),\quad f'(x) = xf(\beta x)\left(1-f(\beta x)\right)+f(\beta x)
Swish:f(x)=x∗sigmoid(βx),f′(x)=xf(βx)(1−f(βx))+f(βx)

Swish优点:(上图的β=1.0\beta=1.0β=1.0.)
- 和Relu一样,没有上边界,因此不会出现梯度饱和的现象(避免过拟合)。
- 有下边界,可以产生更强的正则化效果(x左半轴慢慢趋近于0)
- x<0非单调函数
- 平滑(处处可导,更容易训练)
Softmax
Softmax:f(x)i=e−xi∑j=1ne−xj
Softmax:f(x)_i= \frac{e^{-x_i}}{\sum_{j=1}^ne^{-x_j}}
Softmax:f(x)i=∑j=1ne−xje−xi
Softmax函数:
Softmax激活函数的特点:
- 在零点不可微,负输入的梯度为零,这意味着对于该区域的激活,权重不会在反向传播期间更新,因此会产生永不激活的死亡神经元。
- 将预测结果转化为非负数、预测结果概率之和等于1。
- 经过使用指数形式的Softmax函数能够将差距大的数值距离拉的更大。在深度学习中通常使用反向传播求解梯度进而使用梯度下降进行参数更新的过程,而指数函数在求导的时候比较方便.
优化器(Optimizer)
深度学习模型通过引入损失函数,用来计算目标预测的错误程度。根据损失函数计算得到的误差结果,需要对模型参数(即权重和偏差)进行很小的更改,以期减少预测错误。但问题是如何知道何时应更改参数,如果要更改参数,应更改多少?这就是引入优化器的时候了。简单来说,优化器可以优化损失函数,优化器的工作是以使损失函数最小化的方式更改可训练参数,损失函数指导优化器朝正确的方向移动。
优化器即优化算法是用来求取模型的最优解的,通过比较神经网络自己预测的输出与真实标签的差距,也就是Loss函数。为了找到最小的loss(也就是在神经网络训练的反向传播中,求得局部的最优解),通常采用的是梯度下降(Gradient Descent)的方法,而梯度下降,便是优化算法中的一种。总的来说可以分为三类,一类是梯度下降法(Gradient Descent),一类是动量优化法(Momentum),另外就是自适应学习率优化算法。

1.梯度下降(GD, Gradient Descent)
假设要学习训练的模型参数为WWW,代价函数为J(W)J(W)J(W),则代价函数关于模型参数的偏导数即相关梯度为ΔJ(W)\Delta J(W)ΔJ(W),学习率为η\etaη,则使用梯度下降法更新参数为:
Wt+1=Wt−ηΔJ(Wt)
W_{t+1} = W_t-\eta \Delta J(W_t)
Wt+1=Wt−ηΔJ(Wt)
其中,η\etaη为学习率、WtW_tWt表示ttt时刻的模型参数。
从表达式来看,模型参数的更新调整,与代价函数关于模型参数的梯度有关,即沿着梯度的方向不断减小模型参数,从而最小化代价函数。
基本策略可以理解为”在有限视距内寻找最快路径下山“,因此每走一步,参考当前位置最陡的方向(即梯度)进而迈出下一步。可以形象的表示为:

评价:标准梯度下降法主要有两个缺点:
训练速度慢:每走一步都要要计算调整下一步的方向,下山的速度变慢。在应用于大型数据集中,每输入一个样本都要更新一次参数,且每次迭代都要遍历所有的样本。会使得训练过程及其缓慢,需要花费很长时间才能得到收敛解。
容易陷入局部最优解:由于是在有限视距内寻找下山的反向。当陷入平坦的洼地,会误以为到达了山地的最低点,从而不会继续往下走。所谓的局部最优解就是鞍点。落入鞍点,梯度为0,使得模型参数不在继续更新。(对于非凸函数而言,容易陷入局部最优解)
2.随机梯度下降(SGD, Stochastic Gradient Descent)
均匀地、随机选取其中一个样本,(X(i),Y(i))(X^{(i)},Y^{(i)})(X(i),Y(i))用它代表整体样本.
SGD的更新公式为:
Wt+1=Wt−η△J(Wt,X(i),Y(i))
W _ { t + 1 } = W _ { t } - \eta \bigtriangleup J ( W _ { t },X^{(i)},Y^{(i)} )
Wt+1=Wt−η△J(Wt,X(i),Y(i))
基本策略可以理解为随机梯度下降像是一个盲人下山,不用每走一步计算一次梯度,但是他总能下到山底,只不过过程会显得扭扭曲曲。
优点:
-
虽然SGD需要走很多步的样子,但是对梯度的要求很低(计算梯度快)。而对于引入噪声,大量的理论和实践工作证明,只要噪声不是特别大,SGD都能很好地收敛。
-
应用大型数据集时,训练速度很快。比如每次从百万数据样本中,取几百个数据点,算一个SGD梯度,更新一下模型参数。相比于标准梯度下降法的遍历全部样本,每输入一个样本更新一次参数,要快得多。
缺点:
- SGD在随机选择梯度的同时会引入噪声,使得权值更新的方向不一定正确。此外,SGD也没能单独克服局部最优解的问题。
小批量梯度下降(MBGD, Mini-Batch Gradient Descent)
每次迭代使用m个样本来对参数进行更新,MBGD的更新公式为:
Wt+1=Wt−η1m∑i=ki+m−1ΔJ(Wt,X(k),Y(k))
W _ { t + 1 } = W _ { t } - \eta \frac{1}{m}\sum_{i=k}^{i+m-1}\Delta J ( W _ { t },X^{(k)},Y^{(k)} )
Wt+1=Wt−ηm1i=k∑i+m−1ΔJ(Wt,X(k),Y(k))
其中WtW_tWt表示ttt时刻的模型参数。
从表达式来看,模型参数的调整更新与小部分的输入样本的代价函数的和(即批量/全局误差)有关。即每次权值调整发生在批量样本输入之后,而不是每输入一个样本就更新一次模型参数。这样就会大大加快训练速度。
基本策略可以理解为,在下山之前掌握了附近的地势情况,选择相对的总体平均梯度最小的方向下山。
优点:
- 使用mini-batch的时候,可以收敛得很快,有一定摆脱局部最优的能力。
缺点: - 在随机选择梯度的同时会引入噪声,使得权值更新的方向不一定正确。
- 不能解决局部最优解的问题
传统梯度优化的不足(BGD,SGD,MBGD)
BGD、SGD、MBGD分别为批量梯度下降算法、随机梯度下降算法、小批量梯度下降算法。BGD在训练的时候选用所有的训练集进行计算,SGD在训练的时候只选择一个数据进行训练,而MBGD在训练的时候只选择小部分数据进行训练。这三个优化算法在训练的时候虽然所采用的的数据量不同,但是他们在进行参数优化的时候是相同的。
这种梯度更新算法简洁,当学习率取值恰当时,可以收敛到全面最优点(凸函数)或局部最优点(非凸函数)。但其还有很大的不足点:
- 对超参数学习率比较敏感(过小导致收敛速度过慢,过大又越过极值点)。
- 学习率除了敏感,有时还会因其在迭代过程中保持不变,很容易造成算法被卡在鞍点的位置。
- 在较平坦的区域,由于梯度接近于0,优化算法会因误判,在还未到达极值点时,就提前结束迭代,陷入局部极小值。
动量梯度下降(Momentum)
使用动量(Momentum)的随机梯度下降法(SGD),主要思想是引入一个积攒历史梯度信息动量来加速SGD。
理解策略为:由于当前权值的改变会受到上一次权值改变的影响,类似于小球向下滚动的时候带上了惯性。这样可以加快小球向下滚动的速度。
从训练集中取一个大小为nnn的小批量{X(1),X(2),…,X(n)}\{X^{(1)},X^{(2)},\dots,X^{(n)}\}{X(1),X(2),…,X(n)}样本,对应的真实值分别为Y(i)Y^{(i)}Y(i),则Momentum优化表达式为:
dWt=ΔJ(Wt)Vt=βVt−1+(1−β)dWtWt+1=Wt−ηVt
dW_t = \Delta J(W_t)\\
V_{t} = \beta V_{t-1}+(1-\beta)dW_t\\
W_{t+1} = W_t - \eta V_t
dWt=ΔJ(Wt)Vt=βVt−1+(1−β)dWtWt+1=Wt−ηVt
其中,WtW_tWt表示ttt时刻积攒的加速度。β\betaβ表示动力的大小,一般取值为0.9(表示最大速度10倍于SGD)。含义见SGD算法。表示t时刻模型参数。
动量主要解决SGD的两个问题:一是随机梯度的方法(引入的噪声);二是Hessian矩阵病态问题(可以理解为SGD在收敛过程中和正确梯度相比来回摆动比较大的问题)。
SGDM相比SGD优势明显,加入动量后,参数更新就可以保持之前更新趋势,而不会卡在当前梯度较小的点了。
在梯度方向改变时,momentum能够降低参数更新速度,从而减少震荡;在梯度方向相同时,momentum可以加速参数更新, 从而加速收敛。动量移动得更快(因为它积累的所有动量)。动量有机会逃脱局部极小值(因为动量可能推动它脱离局部极小值)
自适应梯度(AdaGrad)
AdaGrad算法,独立地适应所有模型参数的学习率,缩放每个参数反比于其所有梯度历史平均值总和的平方根。具有代价函数最大梯度的参数相应地有个快速下降的学习率,而具有小梯度的参数在学习率上有相对较小的下降。与SGD的区别在于,学习率除以 前t−1t-1t−1迭代的梯度的平方和。故称为自适应梯度下降。
dWt=ΔJ(Wt)st=st−1+(dwt)2Wt+1=Wt−ηst+εdWt
dW_t = \Delta J(W_t)\\
s_t = s_{t-1}+(dw_t)^2\\
W_{t+1} = W_t-\frac{\eta}{\sqrt{s_t+\varepsilon}}dW_t
dWt=ΔJ(Wt)st=st−1+(dwt)2Wt+1=Wt−st+εηdWt
从表达式可以看出,对出现比较多的类别数据,Adagrad给予越来越小的学习率,而对于比较少的类别数据,会给予较大的学习率。因此Adagrad适用于数据稀疏或者分布不平衡的数据集。
Adagrad 的主要优势在于不需要人为的调节学习率,它可以自动调节;缺点在于,随着迭代次数增多,学习率会越来越小,最终会趋近于0, 使得训练提前结束,无法继续学习。
Adagrad有个致命问题,就是没有考虑迭代衰减。极端情况,如果刚开始的梯度特别大,而后面的比较小,则学习率基本不会变化了,也就谈不上自适应学习率了。
RMSprop
RMSProp算法修改了AdaGrad的梯度积累为指数加权的移动平均,使得其在非凸设定下效果更好。
dWt=ΔJ(Wt)St=βSt−1+(1−β)(dWt)2Wt+1=Wt−ηSt+εdWt
dW_t = \Delta J(W_t)\\
S_t = \beta S_{t-1}+(1-\beta)(dW_t)^2\\
W_{t+1} = W_t - \frac{\eta}{\sqrt{S_t+\varepsilon}}dW_t
dWt=ΔJ(Wt)St=βSt−1+(1−β)(dWt)2Wt+1=Wt−St+εηdWt
- 其实RMSprop依然依赖于全局学习率
- 适合处理非平稳目标——对于RNN效果很好。
- RMSProp借鉴了Adagrad的思想,观察表达式,分母为St+ε\sqrt{S_t+\varepsilon}St+ε。由于取了个加权平均,避免了学习率越来越低的的问题,而且能自适应地调节学习率。
- RMSProp算法在经验上已经被证明是一种有效且实用的深度神经网络优化算法。目前它是深度学习从业者经常采用的优化方法之一。
Adam
Adam是SGDM和RMSProp的结合,它基本解决了之前提到的梯度下降的一系列问题,比如随机小样本、自适应学习率、容易卡在梯度较小点等问题,2015年提出。如下:
dWt=ΔJ(Wt)Vt=β1Vt−1+(1−β1)dWt,St=β2St−1+(1−β2)(dWt)2Vtcorrect=Vt(1−β1)t,Stcorrect=St(1−β2)tW=W−ηStcorrect+εVtcorrect
dW_t = \Delta J(W_t)\\
V_{t} = \beta_1V_{t-1}+(1-\beta_1)dW_t,\quad S_{t} = \beta_2S_{t-1}+(1-\beta_2)(dW_t)^2\\
V_t^{correct}=\frac{V_t}{(1-\beta_1)^t},\quad S_t^{correct}=\frac{S_t}{(1-\beta_2)^t}\\
W = W - \frac{\eta}{\sqrt{S_t^{correct}+\varepsilon}}V_t^{correct}
dWt=ΔJ(Wt)Vt=β1Vt−1+(1−β1)dWt,St=β2St−1+(1−β2)(dWt)2Vtcorrect=(1−β1)tVt,Stcorrect=(1−β2)tStW=W−Stcorrect+εηVtcorrect
Adam通常被认为对超参数的选择相当鲁棒,尽管学习率有时需要从建议的默认修改。自动调整参数的学习率;大幅提升了训练速度;提高了稳定性;
主要包含以下几个显著的优点:
- 实现简单,计算高效,对内存需求少
- 参数的更新不受梯度的伸缩变换影响
- 超参数具有很好的解释性,且通常无需调整或仅需很少的微调
- 更新的步长能够被限制在大致的范围内(初始学习率)
- 能自然地实现步长退火过程(自动调整学习率)
- 很适合应用于大规模的数据及参数的场景
- 适用于不稳定目标函数
- 适用于梯度稀疏或梯度存在很大噪声的问题
AdamW


过拟合
一. 什么是过拟合
过拟合其实就是为了得到一致假设而使得假设过于地严格。使得其在训练集上的表现非常地完美,但是在训练集以外的数据集却表现不好。
二. 过拟合的表现(判定方法)
- 训练集的正确率不增反减
- 验证集的正确率不再发生变化
- 训练集的error一直下降,但是验证集的error不减反增

三. 产生过拟合的原因
1.样本方面
-
用于训练的样本量过于少,使得训练出来的模型不够全面以致于使用模型时错误率高。比如对于猫这类动物,如果训练数据集中只有一个正拍且坐立的猫,那么当过拟合时,模型往往有可能只能识别出这类姿态的猫,像跳跃的猫、局部捕捉的猫、反转的猫等等可能都识别不出来了
-
训练的样本量噪声大(质量不好),导致一些错误的特征错认为是学习的对象,使得训练模型不够健壮
2.模型方面
- 参数过多,模型过于复杂
- 选择的模型本身就不适用于当前的学习任务
- 网络层数过多,导致后面学习得到的特征不够具有代表性
四. 避免过拟合的方法
1. 样本方面
- 增加样本量,深度学习中样本量一般需要在万级别才能训练出较好的模型,且样本尽可能地多样化,使得样本更加地全面。一般通过图像变换可以进行数据增强。
- 特征降维:PCA等,根据现有的特征创造出新的特征
- 特征选择:选择具有代表性的特征参与训练
- 改变数据的分布,使得更集中在激活函数的敏感区。
2. 模型方法
正则化----使模型简单化、参数稀疏化
正则化其实就是在原来的损失函数后面增加了一项加数,这项加数称之为正则项,这个正则项通常由一个系数和范数的乘积的累加和构成。其主要是通过正则项来限制权重w参数的值的变化,使其尽可能的小或者尽可能地趋于0,以达到稀疏参数的效果,进而使得模型复杂度下降,避免过拟合。
- 什么是稀疏参数?什么是数据的稀疏性?
稀疏参数:使得模型中参数的零分量尽可能地多;数据的稀疏性:在特征选择中的概念,指的是在众多的特征中,有的特征对于模型的优化是无关的,这就是数据存在稀疏性,可以通过特征选择来选择有价值的特征。
但是在机器学习的参数中,由于参数众多,模型复杂度过于高的话,易出现过拟合现象,因此我们需要通过增加参数的稀疏性来降低复杂度,进而避免过拟合。
- 什么是范数?常用的范数函数是什么?
范数:在泛函分析中,它定义在赋范线性空间中,并满足一定的条件,即非负性;齐次性;三角不等式。它常常被用来度量某个向量空间(或矩阵)中的每个向量的长度或大小, 最常用的是p范数即x=[x1,x2,…,xn]∈Rnx = \left[x_1,x_2,\dots,x_n\right]\in\mathbb{R}^nx=[x1,x2,…,xn]∈Rn
∥x∥p=(∣x1∣p+∣x2∣p+⋯+∣xn∣p)1p
\Vert x\Vert_p = \left(|x_1|^p+|x_2|^p+\dots+|x_n|^p\right)^{\frac1p}
∥x∥p=(∣x1∣p+∣x2∣p+⋯+∣xn∣p)p1
最常用的是当p=1,2,∞p=1,2,\inftyp=1,2,∞时
∥x∥1=∣x1∣+∣x2∣+⋯+∣xn∣∥x∥2=(∣x1∣2+∣x2∣2+⋯+∣xn∣2)12∥x∥∞=max{∣x1∣,∣x2∣,…,∣xn∣}
\Vert x\Vert_1 = |x_1|+|x_2|+\dots+|x_n|\\
\Vert x\Vert_2 = \left(|x_1|^2+|x_2|^2+\dots+|x_n|^2\right)^{\frac12}\\
\Vert x\Vert_{\infty} = \max\{|x_1|,|x_2|,\dots,|x_n|\}
∥x∥1=∣x1∣+∣x2∣+⋯+∣xn∣∥x∥2=(∣x1∣2+∣x2∣2+⋯+∣xn∣2)21∥x∥∞=max{∣x1∣,∣x2∣,…,∣xn∣}
3. 实现参数的稀疏有什么好处吗?
一个好处是可以简化模型,避免过拟合。因为一个模型中真正重要的参数可能并不多,如果考虑所有的参数起作用,那么可以对训练数据可以预测的很好,但是对测试数据表现性能极差。另一个好处是参数变少可以使整个模型获得更好的可解释性。
- 参数值越小代表模型越简单吗?
是的。为什么参数越小,说明模型越简单呢,这是因为越复杂的模型,越是会尝试对所有的样本进行拟合,甚至包括一些异常样本点,这就容易造成在较小的区间里预测值产生较大的波动,这种较大的波动也反映了在这个区间里的导数很大,而只有较大的参数值才能产生较大的导数。因此复杂的模型,其参数值会比较大。反过来就是如果参数值小的话,那么异常点在这个区间里的导数就会比较小,造成预测值的波动也就小,这样就会利于模型,避免过拟合,更具有泛化能力去预测新样本。
L0正则化——正则项为非零分量的个数
利用非零参数的个数,可以很好的来选择特征,实现特征稀疏的效果,具体操作时选择参数非零的特征即可。但因为L0L_{0}L0正则化很难求解,是个NP难问题,因此一般采用L1L_{1}L1正则化。L1L_{1}L1正则化是L0L_{0}L0正则化的最优凸近似,比L0L_{0}L0容易求解,并且也可以实现稀疏的效果。
L1正则化(LASSO)——效果使w分量往0靠拢
Lossnorm(W)=Loss(W)+λn∑∣W∣
Loss_{norm}(W) = Loss(W)+{\lambda \over n} \sum|W|
Lossnorm(W)=Loss(W)+nλ∑∣W∣
λ\lambdaλ是惩罚系数,nnn是参数的数量
ΔLossnorm(W)=ΔLoss(W)+λnsgn(W)
\Delta Loss_{norm}(W) = \Delta Loss(W)+{\lambda \over n}sgn(W)
ΔLossnorm(W)=ΔLoss(W)+nλsgn(W)
其中λ和n参数大于0,由权重参数的更新可以看出,当w为正时,更新后的w变小。当w为负时,更新后的w变大——因此它的效果就是让w往0靠,使网络中的权重尽可能为0,也就相当于减小了网络复杂度,防止过拟合。
L2正则化(岭回归)——效果使参数减小
Lossnorm(W)=Loss(W)+λ2n∑∣W∣2
Loss_{norm}(W) = Loss(W)+{\lambda \over 2n} \sum|W|^2
Lossnorm(W)=Loss(W)+2nλ∑∣W∣2
λ\lambdaλ是惩罚系数,nnn是参数的数量
ΔLossnorm(W)=ΔLoss(W)+λnW
\Delta Loss_{norm}(W) = \Delta Loss(W)+{\lambda \over n}W
ΔLossnorm(W)=ΔLoss(W)+nλW
它的效果是减小WWW,这也就是权重衰减(weight decay)的由来。当然考虑到后面的导数项,WWW最终的值可能增大也可能减小。根据奥卡姆剃刀法则可知,更小的权值WWW,从某种意义上说,表示网络的复杂度更低,对数据的拟合刚刚好。
- 为什么可以避免过拟合?
其实就是增加正则项后,使得参数变小了,模型简化,使得损失在避免过拟合和最小化损失之间进行了折中,以此来避免了过拟合。
归一化(normalization)
为了克服神经网络加深导致难以训练而诞生的,随着神经网络深度加深,训练起来就会越来越困难,收敛速度回很慢,常常会导致梯度弥散问题(Vanishing Gradient Problem)。
解决办法:一般是根据训练样本和目标样本的比例对训练样本做一个矫正。所以,通过引入Batch Normalization来标准化某些层或者所有层的输入,从而固定每层输入信息的均值和方差。
Batch Normalization
一般用在非线性映射(激活函数)之前,对x=Wu+b做标准化,是结果(输出信号各个维度)的均值为0,方差为1。让每一层的输入有一个稳定的分布会有利于网络的训练。
一般来说卷积,BN,激活层,Dropout层的相对顺序如:->CONV/FC -> BatchNorm -> ReLu(or other activation) -> Dropout -> CONV/FC ->;BN要比Dropout效果好,Dropout在慢慢被抛弃。
5.Batch Norm
(1) 可以使学习快速进行(可以增大学习率)。
(2)不那么依赖初始值(对于初始值不用那么神经质)。
(3)抑制过拟合(降低Dropout等的必要性)。
对于每个小批量数据,计算该批次数据在某一维度上的均值和方差。
μB=1m∑i=1mxi
\mu _{B} = \frac{1}{m} \sum^{m}_{i=1}x_i
μB=m1i=1∑mxi
其中,xix_ixi 是小批量中第i个数据点的值,m是小批量的大小(即小批量中数据点的总数)。
σB2=1m∑i=1m(xi−μB)2
\sigma_B^2 = \frac{1}{m} \sum^{m}_{i=1}(x_i - \mu_B )^2
σB2=m1i=1∑m(xi−μB)2
其中,xix_ixi 表示小批量数据中的第i个数据点,μB\mu_BμB 是小批量的均值,和前面的公式一致,而m依然是小批量的大小。
使用这些统计量将小批量数据的每个特征调整为均值=0和方差=1
x^(k)=x(k)−μBσB2+ϵ
\hat{x}^{(k)} = \frac{x^{(k)} - \mu_B}{\sqrt{\sigma_B^2 + \epsilon}}
x^(k)=σB2+ϵx(k)−μB
其中 x(k)x^{(k)}x(k) 是输入数据,μB\mu_BμB 是批数据的均值,σB2\sigma_B^2σB2 是批数据的方差,ϵ\epsilonϵ 是一个很小的数以避免除以零。
为了保留网络的学习能力,还会引入两个可学习的参数\gamma(缩放因子)和\beta(平移因子)对规范化后的数据进行调整
z^(k)=γ(k)x^(k)+β(k)
\hat z^{(k)} = \gamma^{(k)} \hat{x}^{(k)} + \beta^{(k)}
z^(k)=γ(k)x^(k)+β(k)
batch norm适用于CV,因为计算机视觉喂入的数据都是像素点,可以说数据点与点之间是可以比较的,所以使用batch norm可以有比较好的效果,而NLP里,每个词的词向量是一组向量表示一个词,一个词向量割裂开来看是没有意义的,因此不同词向量里的数据点是不能混为一谈的,所以batch norm之后可能会使得词损失语义,效果就可能不好了,但是使用layer norm只是让各个词向量进行标准化,就能够有比较理想的效果了。
**
对于 CNN 某个卷积层对应的输出通道 k 来说,假设某个 Batch 包含 n 个训练实例,那么每个训练实例在这个通道 k 都会产生一个二维激活平面,也就是说 Batch 中 n 个训练实例分别通过同一个卷积核的输出通道 k 的时候产生了 n 个激活平面。假设激活平面长为 5,宽为 4,则激活平面包含 20 个激活值,n 个不同实例的激活平面共包含 20*n 个激活值。
**
局限 1:如果 Batch Size 太小,则 BN 效果明显下降。
局限 2:对于有些像素级图片生成任务来说,BN 效果不佳;
对于有些输入输出都是图片的像素级别图片生成任务,比如图片风格转换等应用场景,使用 BN 会带来负面效果,这很可能是因为在 Mini-Batch 内多张无关的图片之间计算统计量,弱化了单张图片本身特有的一些细节信息。
局限 3:RNN 等动态网络使用 BN 效果不佳且使用起来不方便
同一个位置出现的词很难服从相似分布,所以RNN中BN很难学到合适的μ和σ,将来自不同分布的特征做正确变换,甚至带来反作用,所以效果不好。
局限 4:训练时和推理时统计量不一致
对于 BN 来说,采用 Mini-Batch 内实例来计算统计量,这在训练时没有问题,但是在模型训练好之后,在线推理的时候会有麻烦。因为在线推理或预测的时候,是单实例的,不存在 Mini-Batch,所以就无法获得 BN 计算所需的均值和方差,一般解决方法是采用训练时刻记录的各个 Mini-Batch 的统计量的数学期望,以此来推算全局的均值和方差,在线推理时采用这样推导出的统计量。虽说实际使用并没大问题,但是确实存在训练和推理时刻统计量计算方法不一致的问题。

LN层
一般来说,层归一化所做的就是,对于图像,即输入为N×C×H×WN \times C \times H \times WN×C×H×W的特征图:在每个样本内部,计算所有像素点的均值和标准差,并针对每个像素点训练一组可学习参数γ\gammaγ和β\betaβ,用于进行缩放和平移,以归一化到同一范围内。
如下图所示,针对的是一个样本中的所有通道内的所有像素。也就是说和Batch无关。
因此可学习参数的组数就等于C×H×WC \times H \times WC×H×W。

BN层和LN层的对比

CNN适合用BN层,RNN、transformer等适合用LN层
因为对于图像等非时空序列特征来说, 不同Batch之间的分布差不多,且同维度,可以在不同batch之间归一化
对于时空序列、NLP的词向量序列等,不同序列之间的分布差别大(例如,不同句子之间差别很大),而且不同序列维度可能不同,不能使用BN,使用LN在同一个样本内部归一化。
BN的缺陷:
- BN是在batch size样本上各个维度做标准化的,所以size越大肯定越能得出合理的μ和σ来做标准化,因此BN比较依赖size的大小。
- 在训练的时候,是分批量进行填入模型的,但是在预测的时候,如果只有一个样本或者很少量的样本来做inference,这个时候用BN显然偏差很大,例如在线学习场景。
- RNN是一个动态的网络,也就是size是变化的,可大可小,造成多样本维度都没法对齐,所以不适合用BN。
LN带来的优势:
- Layer Normalization是每个样本内部做标准化,跟size没关系,不受其影响。
- RNN中LN也不受影响,内部自己做标准化,所以LN的应用面更广。
Dropout
概念:我们在前向传播的时候,让某个神经元的激活值以一定的概率p停止工作,这样可以使模型泛化性更强,因为它不会太依赖某些局部的特征。每次迭代丢失的神经元都不一样,使得其训练得到了不一样的模型。使用DropOut训练的神经网络中的每个隐藏单元必须学会与随机选择的其他单元样本一起工作,这样会使得每个隐藏单元更加的健壮,并使得他们尽量自己可以创造有用的功能,而不是依赖其他隐藏单元。减少神经元之间复杂的共适应关系。
过程
输入是x输出是y,正常的流程是:我们首先把x通过网络前向传播,然后把误差反向传播以决定如何更新参数让网络进行学习。使用Dropout之后,过程变成如下:

注意:
- 在测试中,权重参数w被缩放
Wl=pWl W^l=pW^l Wl=pWl - 训练的过程中,会停止训练一些神经元,但是在测试的时候,整个模型是完整的,为了解决这个问题,我们会对没有被dropout的神经元权值做一个rescale,例如:dropout rate为ppp,经过该算式之后rescale rate比例为1p\frac 1pp1,这在一定程度上弥补了删掉一些神经元带来的误差。
rescalerate=1/(1−dropoutrate) rescale rate=1 / (1 - dropout rate) rescalerate=1/(1−dropoutrate) - 拓展延伸:如果不想测试阶段缩放权重,可以选择在训练阶段缩放激活函数,即反向Dropout,这样的话在测试阶段可以保持网络不变。所以我们换一个思路,在训练时候将剩余权重乘以1/(1-p),在测试时,就不需要做什么了。
1804






