最新文�? 原创 : 【校招Verilog进阶挑战】 时序逻辑篇:VL12 状态机-重叠序列检测 原创 : 【校招Verilog进阶挑战】 时序逻辑篇:VL13 时钟分频(偶数) 原创 : 【校招Verilog进阶挑战】 时序逻辑篇:VL14 自动贩售机1(注意Moore机在输入完成后的时钟周期输出需要使用next_state判断) 原创 : 【深度学习入门】基础概念记录 原创 : 【校招Verilog进阶挑战】 时序逻辑篇:VL15 自动贩售机2
深度学习 历史版本:
上次修改时间:
RNN,CNN,DNN区别 历史版本:
上次修改时间: 2022-02-09 09:46:19

DNN,CNN,RNN的区别在于结构上的差别,产生这种差别主要还是因为要解决的问题不同,其中:

  • CNN 专门解决图像问题的,可用把它看作特征提取层,放在输入层上,最后用MLP 做分类。
  • RNN 专门解决时间序列问题的,用来提取时间序列信息,放在特征提取层(如CNN)之后。
  • DNN 其实就是就是多层网络,只不过解决了多层结构下梯度消失的问题 。

DNN 深度神经网络

DNN也是人工神经网络(ANN),区别在于层数不同,ANN结构如下:
多层感知机(multilayer perceptron)
image.png
同时,每个感知器的结构如下:
image.png
每个感知机的输出都是输入加权和的激活。单层网络仅学习线性函数,但不学习复杂关系,所谓的DNN就是层数较多的多层感知机。
DNN和ANN的差别是DNN是层数较多的ANN,对于浅层MLP而言,通常用于解决回归和分类问题,对特征本身没有处理的能力,当隐藏层数加多时,网络甚至能自己去提取特征,而不用再经过特征预处理的阶段。这里的深度指的是层数的深度,其实并没有特定的规模,比如:4层网络能分类语音信号,而用于图像分类的网络通常需要20层才能够满足条件。
在层数较多的情况下, 训练时候很容易出现“梯度消失”现象,如果激活函数是sigmoid函数,使用BP反向传播梯度算法训练,对于幅度为1,的前一层输入,到后一层的时候,会减少为0.25,当层数一多时,低层信号就接受不到有效的训练信号了。
为了克服梯度消失,ReLU、maxout等传输函数代替了sigmoid。这大约DNN的结构

RNN

事物的发展是按照时间序列展开的,即前一刻发生的事物会对未来的事情的发展产生影响。,对于MLP结构而言无法捕获处理序列数据所需的输入数据中的顺序信息。样本出现的时间顺序对于自然语言处理、语音识别、手写体识别等应用非常重要,此类问题可以用RNN来处理。
所谓的RNN就是以下结构的感知机网络。
image.png
可以看到,每个感知机的输入,会加上上次这个感知机的上次输出结果。但是这种结构也有问题,比如一个时间点的信号,可能过去5轮,这个点的输出就已经消失了,同样也是梯度消失的问题,因此这种结构只对短时的时间序列有效,如果需要长时间记忆,需要采用LSTM模型(长短时记忆单元)。

CNN(卷积神经网络)


image.png
 图中是一个图形识别的CNN模型。可以看出最左边的船的图像就是我们的输入层,计算机理解为输入若干个矩阵,这点和DNN基本相同。

卷积层(Convolution Layer)

这个是CNN特有的,我们后面专门来讲。卷积层的激活函数使用的是ReLU。我们在DNN中介绍过ReLU的激活函数,它其实很简单,就是ReLU(x)=max(0,x)

image.png
单个卷积核的结果。

池化

池化和卷积类似,但是池化是没有激活函数的。
 相比卷积层的复杂,池化层则要简单的多,所谓的池化,个人理解就是对输入张量的各个子矩阵进行压缩。假如是2x2的池化,那么就将子矩阵的每2x2个元素变成一个元素,如果是3x3的池化,那么就将子矩阵的每3x3个元素变成一个元素,这样输入矩阵的维度就变小了。
要想将输入子矩阵的每nxn个元素变成一个元素,那么需要一个池化标准。常见的池化标准有2个,MAX或者是Average。即取对应区域的最大值或者平均值作为池化后的元素值。
image.png

如何组合

卷积层+池化层的组合可以在隐藏层出现很多次,上图中出现两次。而实际上这个次数是根据模型的需要而来的。当然我们也可以灵活使用使用卷积层+卷积层,或者卷积层+卷积层+池化层的组合,这些在构建模型的时候没有限制。但是最常见的CNN都是若干卷积层+池化层的组合,如上图中的CNN结构。 在若干卷积层+池化层后面是全连接层(Fully Connected Layer, 简称FC),全连接层其实就是我们前面讲的DNN结构,只是输出层使用了Softmax激活函数来做图像识别的分类,这点我们在DNN中也有讲述。

CNN及其派生模型原理和应用 历史版本:
上次修改时间: 2022-02-09 09:47:25

参考

alexnet
alexnet
fast-rcnn
yolo
本文主要描述了CNN及其派生网络的结构以及应用。

CNN

CNN就是卷积神经网络,其网络结构模式如下:
image.png CNN主要由卷积层,池化层,以及后面的传统多层感知机组成,事实上CNN有多个分支:

  1. LeNet、AlexNet、VGG、GoogLeNet等模型,主要用于图像分类。
  2. RCNN、Fast RCNN、Faster RCNN、YOLO、YOLOv2、SSD等主要用于目标识别。

这些分支其实都由卷积层,池化层和MLP单元组成,只不过组成的结构不同。

图像分类: 和传统的分类任务一样,输出是一个离散的label值。
目标识别: 输出是多个对象的坐标和及其分类。

目标检测的方法

分为:

  1. One-stage: 直接回归物体的类别概率和位置坐标值(无region proposal),但准确度低,速度相遇two-stage快。
  2. two-stage: 先由算法生成一系列作为样本的候选框,再通过卷积神经网络进行样本分类。

卷积层

传统的MLP的输入是一个列向量,但在CNN将输入看成一个nxm的矩阵,这是利用根据图像结构来提取特征。

image.png
卷积的结果在MLP结构下称谓隐藏层,CNN的隐藏层结构也是一个矩阵,计算方法如下:
image.png
从上面的计算方法得到:如果输入层是尺寸为28X28的图像,卷积核的大小为5X5,那么得到的第一个隐藏层的大小是24X24。
我们知道单个神经元的输入加权和是:

image.png
输出是加权和加上偏移的对于激活函数映射的像。

$$f(uk + bias)$$

卷积层的输入是mxn的矩阵,假设卷积核大小lxl,那么输出就是:

$$(m-l)*(n-l)$$

的矩阵作为输出。
单个卷积核只能检测某个特定的特征,当然单个特征不能用于检测一个图片。
因此可能有多个特征,这时候输出就变成了:

$$ ((m-l)(n-l)p) $$


这时候输出就是一个3阶的张量。

卷积层的个数,一般卷积核要到达6个以上,比如我们认为5个方向的特征就能完整描述一个特征
image.png
一个卷积层的结果例子:
image.png
经过激活函数后的结果:
image.png

池化

池化层(pooling layers) 池化层通常紧随卷积层之后使用,池化分为两种,Max Pooling 最大池化、Average Pooling平均池化。顾名思义,最大池化就是取最大值,平均池化就是取平均值。

其作用是简化卷积层的输出。例如,池化层中的每一个神经元可能将前一层的一个2X2区域内的神经元求和。
而另一个经常使用的max-pooling,该池化单元简单地将一个2X2的输入域中的最大激励输出,如下图所示:
image.png
如果卷积层的输出包含24X24个神经元,那么在池化后可得到12X12个神经元。每一个特征映射后分别有一个池化处理,前面所述的卷积层池化后的结构为:
image.png

全连接层

在池化之后,就是接上传统的MLP结构:

image.png
由于mlp结构只接受行向量作为输入,因此要将池化层的结果转为行向量,如上图,输入是3x12x12个像素也就是432个输入节点。

怎么训练

训练是对全连接层的进行训练,有BP反向传播算法。
还是老家伙误差函数,每次训练的权值改变为:
image.png
其中image.png是训练的步长度。

bp反向传播算法

应用

CNN的优点:

  • 共享卷积核,处理高维数据无压力。
  • 可以自动进行特征提取。

缺点:

  • 池化层会丢失大量有价值信息,忽略局部与整体之间关联性,如果对待测样本进行旋转,或者遮住一部分,可能无法正确识别。
  • 卷积只能位置无关的特征,当遇到位置相关的特征的时候(比如人脸,人眼,鼻子,嘴巴都是有结构的放置的)卷积获取到的特征就容易出现识别错误,比如把嘴巴放在鼻子上面,很可能也被认为是人脸。

应用:

  • minist手写数字识别(图像分类)
  • NLP(词性分类)

AlexNet

AlexNet一共有8层,网络结构图:
image.png
前五层为卷积层:
image.png
后三层为全连接层:
image.png AlexNet的特点在于:

  • 使用了非线性激活函数:ReLU
  • 防止过拟合的方法:Dropout,数据扩充(Data augmentation)

AlexNet的最后一层全连接层的输出是1000维softmax的输入,softmax会产生1000个类别预测的值。
AlexNet的每层需要的参数量和计算量:
image.png

R-CNN

RCNN MATLAB项目
R-CNN是2014年出现的。它是将CNN用于对象检测的起源,能够基于丰富的特征层次结构进行目标精确检测和语义分割来源,比如:
image.png
RCNN 是传统的two-state算法,包含了候选区回归,和具体的分类两个步骤,候选区回归的会找到一些候选区,但毕竟只是候选,等真正识别出其中的对象以后,还要对候选区进行微调,使之更接近真实的bounding box。这个过程就是边框回归:将候选区bounding box调整到更接近真实的bounding box。

R-CNN的模型如下:
image.png
流程如下:
image.png

R-CNN等包括YOLO模型在传统CNN网络前端加上一个区域提取阶段,称为区域建议网络,图片中的一小部分作为其输入数据,由于CNN网络的输入图像尺寸必须是固定的某一个大小(否则全连接时没法计算),因此候选框子图必须将图像裁剪缩放到相同尺寸大小,然后对图像中每个区域进行CNN分类,提取特征的坐标也作为输出,因此可以得到目标的坐标和目标的分类,对于最后的分类阶段,一般是用一个SVM分类器,因为这些预编码好的分类肯定是线性可分的。
R-CNN模型速度较慢,因为对于每次的region propersol都需要进行一次CNN计算。

训练

(1)在数据集上训练CNN 。R-CNN论文中使用的CNN网络是AlexNet,数据集为ImageNet 。
(2)在目标检测的数据集上,对训练好的CNN做微调。
(3)用Selective Search搜索候选区域,统一使用微调后的CNN对这些区域提取特征,并将提取到的特征存储起来。
(4)使用存储起来的特征,训练SVM分类器。

Faster R-CNN架构

Faster R-CNN的计算流程如下:
image.png

faster-r-cnn相对于r-cnn的改进如下:

  1. 卷积不再是对每个region proposal进行,而是直接对整张图像,这样减少了很多重复计算。原来RCNN是对每个region proposal分别做卷积,因为一张图像中有2000左右的region proposal,肯定相互之间的重叠率很高,因此产生重复计算。
  2. 用ROI pooling进行特征的尺寸变换,因为全连接层的输入要求尺寸大小一样,因此不能直接把region proposal作为输入。
  3. 将regressor放进网络一起训练,每个类别对应一个regressor,同时用softmax代替原来的SVM分类器。

卷积神经网络直接产生region proposal,使用的方法本质上就是滑动窗口。RPN只需在最后的卷积层上滑动一遍,因为anchor机制和边框回归可以得到多尺度、多长宽比的region proposal,3*3滑窗对应的每个特征区域同时预测输入图像3种尺度(128,256,512),3种长宽比(1:1,1:2,2:1)的region proposal,这种映射的机制称为anchor。
image.png
faster-r-cnn的网络结构如下,特点就是卷积层针对的是整个图片而不是某个区域

image.png

  1. 卷积层。原始图片先经过conv-relu-pooling的多层卷积神经网络,提取出特征图。供后续的RPN网络和全连接层使用。faster R-CNN不像R-CNN需要对每个子图进行卷积层特征提取,它只需要对全图进行一次提取就可以了,从而大大减小了计算时间。
  2. RPN层,region proposal networks。RPN层用于生成候选框,并利用softmax判断候选框是前景还是背景,从中选取前景候选框(因为物体一般在前景中),并利用bounding box regression调整候选框的位置,从而得到特征子图,称为proposals。
  3. ROI层,fast R-CNN中已经讲过了ROI层了,它将大小尺寸不同的proposal池化成相同的大小,然后送入后续的全连接层进行物体分类和位置调整回归
  4. 分类层。利用ROI层输出的特征图proposal,判断proposal的类别,同时再次对bounding box进行regression从而得到精确的形状和位置。
训练

整个Faster RCNN训练过程可分为4步:

  1. 用在ImageNet数据集上训练好的model初始化模型,训练一个RPN网络;
  2. 用在ImageNet数据集上训练好的model初始化模型,同时用第一步中训练好的RPN网络生成的region proposal作为输入,训练一个Fast RCNN;
  3. 用第二步训练好的Fast RCNN的网络参数初始化RPN网络,但是将RPN与Fast RCNN共享的网络层的learning rate设置为0,仅微调RPN独有的网络层。
  4. :固定共享的网络层,仅微调Fast RCNN所独有的fc层。

yolo系列:you only look once

YOLO将物体检测作为一个回归问题进行求解,输入图像经过一次inference,便能得到图像中所有物体的位置和其所属类别及相应的置信概率。而rcnn/fast rcnn/faster rcnn将检测结果分为两部分求解:物体类别(分类问题),物体位置即bounding box(回归问题)。
去掉候选区这个步骤以后,YOLO的结构非常简单,就是单纯的卷积、池化最后加了两层全连接。最大的差异是最后输出层用线性函数做激活函数,因为需要预测bounding box的位置(数值型),而不仅仅是对象的概率。YOLO网络结构由24个卷积层与2个全连接层构成,网络入口为448x448(v2为416x416),图片进入网络先经过resize,网络的输出结果为一个张量,维度为:

image.png.
其中,S为划分网格数,B为每个网格负责的边框个数,C为类别个数。每个小格会对应B个边界框,边界框的宽高范围为全图,表示以该小格为中心寻找物体的边界框位置。每个边界框对应一个分值,代表该处是否有物体及定位准确度:image.png,每个小格会对应C个概率值,找出最大概率对应的类别P(Class|object),并认为小格中包含该物体或者该物体的一部分。

实际上,YOLO并没有真正去掉候选区,而是采用了预定义的候选区(准确点说应该是预测区,因为并不是Faster RCNN所采用的Anchor)。比如将图片划分为 77=49 个网格(grid),每个网格允许预测出2个边框(bounding box,包含某个对象的矩形框),总共 492=98 个bounding box。可以理解为98个候选区,它们很粗略的覆盖了图片的整个区域。

image.png

输入:

输入就是原始图像,唯一的要求是缩放到448448的大小。主要是因为YOLO的网络中,卷积层最后接了两个全连接层,全连接层是要求固定大小的向量作为输入,所以倒推回去也就要求原始图像有固定的尺寸。那么YOLO设计的尺寸就是448448。

输出

输入图像被划分为 77 的网格(grid),输出张量中的 77 就对应着输入图像的 77 网格。或者我们把 77*30 的张量看作49个30维的向量,也就是输入图像中的每个网格对应输出一个30维的向量。参考上图,比如输入图像左上角的网格对应到输出张量中左上角的向量。
要注意的是,并不是说仅仅网格内的信息被映射到一个30维向量。经过神经网络对输入图像信息的提取和变换,网格周边的信息也会被识别和整理,最后编码到那个30维向量中。其中包含了:
image.png

  • 20个对象分类的概率
  • 2个bounding box的位置
  • 2个bounding box的置信度

训练

YOLO先使用ImageNet数据集对前20层卷积网络进行预训练,然后使用完整的网络,在PASCAL VOC数据集上进行对象识别和定位的训练和预测。YOLO的网络结构如下图所示:</br>

image.png

过拟合和欠拟合 历史版本:
上次修改时间: 2022-02-09 09:46:42

引用

过拟合现象的产生

超参数

参数是被数据和算法训练出来的。而超参数(比如学习速率)不是被训练出来的,而是人为手工调整的。调整超参数更像是一种艺术,而不是科学,常见的超参数是:

  • 树的数量或树的深度
  • 矩阵分解中潜在因素的数量
  • 学习率(多种模式)
  • 深层神经网络隐藏层数
  • k均值聚类中的簇数

模型的复杂程度决定拟合程度

模型的复杂程度本身就是一个超参数。
image.png
模型简单,导致偏差变大,称为高偏差,欠拟合。
模型复杂,导致方差变大,称为高方差,过拟合。

过拟合

也称为过拟合-高方差。

过拟合现象

过拟合现象可以总结为:

  • 模型在训练集上面的误差很小。
  • 模型在验证集上的误差非常大。

产生原因


当我们构建模型时,总会希望假设空间参数尽可能多,系统越复杂,拟合得越好嘛!我们还希望我们的优化算法能使我们的模型产生的损失函数的值尽可能小(即我们的假设空间能够贴合每一个训练样本点)。但这样真的好吗?奥卡姆剃刀貌似又胜利了。然而假设我们的模型达成了上述的情况,有很大概率产生一个ML界非常令人头疼的一件事:过拟合(Overfitting)。
举一个简单的例子:我们设计了一个模型来判断一件物品是否为树叶。喂养这个模型的数据集中含有几张带有尖刺边缘的树叶。模型的设计者希望模型能满足每一个训练数据,模型就将尖刺边缘也纳入了参数中。当我们测试这个模型的泛化性能时,就会发现效果很差,因为模型钻牛角尖,它认为树叶必须带有尖刺边缘,所以它排除了所有没有带有尖刺边缘的树叶,但事实上,我们知道树叶并不一定带有尖刺边缘。结果为什么会这样?因为模型设计者的强迫症使得这个模型过分贴合整个训练集,结果把噪音点也拟合上了。
一个线性回归的例子:
![image.png](https://www.testingcloud.club/sapi/api/image_download/54a09291-6e0d-11eb-b83e-525400dc6cec.png)
实际上第二个效果的更好,模型更简单,第三个模型追求最小化误差函数,却把本身的误差也拟合了。

模型出现过拟合现象的主要原因是:

  1. 建模样本选取有误,比如相对于特征维度样本数量太少,选样方法错误,样本标签错误等,导致选取的样本数据不足以代表预定的分类规则 样本噪音干扰过大,使得机器将部分噪音认为是特征从而扰乱了预设的分类规则
  2. 假设的模型无法合理存在,或者说是假设成立的条件实际并不成立
  3. 参数太多,模型复杂度过高
  4. 对于决策树模型,如果我们对于其生长没有合理的限制,其自由生长有可能使节点只包含单纯的事件数据(event)或非事件数据(no event),使其虽然可以完美匹配(拟合)训练数据,但是无法适应其他数据集
  5. 对于神经网络模型:a)对样本数据可能存在分类决策面不唯一,随着学习的进行,,BP算法使权值可能收敛过于复杂的决策面;b)权值学习迭代次数足够多(Overtraining),拟合了训练数据中的噪声和训练样例中没有代表性的特征.

过拟合的解决方法:

  1. 正则化(Regularization)(L1和L2)
  2. 数据扩增,即增加训练数据样本
  3. Dropout
  4. Early stopping

正则化

在模型训练的过程中,需要降低 loss 以达到提高 accuracy 的目的。此时,使用正则化之类的方法直接将权值的大小加入到 loss 里,在训练的时候限制权值变大。训练过程需要降低整体的 loss,这时候,一方面能降低实际输出与样本之间的误差,也能降低权值大小
正则化方法包括 L0 正则、 L1 正则和 L2 正则,而正则一般是在目标函数之后加上对于的范数。但是在机器学习中一般使用 L2 正则:
image.png
L2 范数是指向量各元素的平方和然后求平方根。可以使得 W 的每个元素都很小,都接近于0,但不会让它等于0,而是接近于0。 L2 正则项起到使得参数 W 变小加剧的效果,关于它为什么能防止过拟合简答的理解为:更小的参数值 W 意味着模型的复杂度更低,对训练数据的拟合刚刚好,不会过分拟合训练数据,从而使得不会过拟合,以提高模型的泛化能力

数据扩增

这是解决过拟合最有效的方法,只要给足够多的数据,让模型「看见」尽可能多的「例外情况」,它就会不断修正自己,从而得到更好的结果

如何获取更多数据,可以有以下几个方法

  1. 从数据源头获取更多数据
  2. 根据当前数据集估计数据分布参数,使用该分布产生更多数据:这个一般不用,因为估计分布参数的过程也会代入抽样误差
  3. 数据增强(Data Augmentation):通过一定规则扩充数据。如在物体分类问题里,物体在图像中的位置、姿态、尺度,整体图片明暗度等都不会影响分类结果。我们就可以通过图像平移、翻转、缩放、切割等手段将数据库成倍扩充

Dropout

在训练时,每次随机(如50%概率)忽略隐层的某些节点;这样,我们相当于随机从 2^n(n个神经元的网络) 个模型中采样选择模型

Early stopping

Early stopping便是一种迭代次数截断的方法来防止过拟合的方法,即在模型对训练数据集迭代收敛之前停止迭代来防止过拟合。

具体做法是,在每一个Epoch结束时计算validation data的accuracy,当accuracy不再提高时,就停止训练。当然我们并不会在accuracy一降低的时候就停止训练,因为可能经过这个Epoch后,accuracy降低了,但是随后的Epoch又让accuracy又上去了,所以不能根据一两次的连续降低就判断不再提高。一般的做法是,在训练的过程中,记录到目前为止最好的validation accuracy,当连续10次Epoch(或者更多次)没达到最佳accuracy时,则可以认为accuracy不再提高了。此时便可以停止迭代了(Early Stopping)。这种策略也称为“No-improvement-in-n”,n即Epoch的次数,可以根据实际情况取,如10、20、30……

欠拟合

欠拟合就是模型没有很好地捕捉到数据特征,不能够很好地拟合数据,例如下面的例子:
image.pngimage.png
欠拟合出现的原因:

  • 模型复杂度过低
  • 特征量过少

欠拟合的情况比较容易克服,常见解决方法有:

  1. 增加新特征,可以考虑加入进特征组合、高次特征,来增大假设空间
  2. 添加多项式特征,这个在机器学习算法里面用的很普遍,例如将线性模型通过添加二次项或者三次项使模型泛化能力更强
  3. 减少正则化参数,正则化的目的是用来防止过拟合的,但是模型出现了欠拟合,则需要减少正则化参数
  4. 使用非线性模型,比如核SVM 、决策树、深度学习等模型
  5. 调整模型的容量(capacity),通俗地,模型的容量是指其拟合各种函数的能力
  6. 容量低的模型可能很难拟合训练集;使用集成学习方法,如Bagging ,将多个弱学习器Bagging

过拟合的解决方案:

  1. 正则化(Regularization)(L1和L2)
  2. 数据扩增,即增加训练数据样本
  3. Dropout
  4. Early stopping
XGBoost 历史版本:
上次修改时间: 2022-02-09 09:42:10

目录

1. 什么是XGBoost

XGBoost是陈天奇等人开发的一个开源机器学习项目,高效地实现了GBDT算法并进行了算法和工程上的许多改进,被广泛应用在Kaggle竞赛及其他许多机器学习竞赛中并取得了不错的成绩。

说到XGBoost,不得不提GBDT(Gradient Boosting Decision Tree)。因为XGBoost本质上还是一个GBDT,但是力争把速度和效率发挥到极致,所以叫X (Extreme) GBoosted。包括前面说过,两者都是boosting方法。

关于GBDT,这里不再提,可以查看我前一篇的介绍,点此跳转

1.1 XGBoost树的定义

先来举个例子,我们要预测一家人对电子游戏的喜好程度,考虑到年轻和年老相比,年轻更可能喜欢电子游戏,以及男性和女性相比,男性更喜欢电子游戏,故先根据年龄大小区分小孩和大人,然后再通过性别区分开是男是女,逐一给各人在电子游戏喜好程度上打分,如下图所示。

就这样,训练出了2棵树tree1和tree2,类似之前gbdt的原理,两棵树的结论累加起来便是最终的结论,所以小孩的预测分数就是两棵树中小孩所落到的结点的分数相加:2 + 0.9 = 2.9。爷爷的预测分数同理:-1 + (-0.9)= -1.9。具体如下图所示:

恩,你可能要拍案而起了,惊呼,这不是跟上文介绍的GBDT乃异曲同工么?

事实上,如果不考虑工程实现、解决问题上的一些差异,XGBoost与GBDT比较大的不同就是目标函数的定义。XGBoost的目标函数如下图所示:

其中:

  • 红色箭头所指向的L 即为损失函数(比如平方损失函数:)
  • 红色方框所框起来的是正则项(包括L1正则、L2正则)
  • 红色圆圈所圈起来的为常数项
  • 对于f(x),XGBoost利用泰勒展开三项,做一个近似。f(x)表示的是其中一颗回归树。

看到这里可能有些读者会头晕了,这么多公式,我在这里只做一个简要式的讲解,具体的算法细节和公式求解请查看这篇博文,讲得很仔细通俗理解kaggle比赛大杀器xgboost

XGBoost的核心算法思想不难,基本就是:

  1. 不断地添加树,不断地进行特征分裂来生长一棵树,每次添加一个树,其实是学习一个新函数**f(x)**,去拟合上次预测的残差。
  2. 当我们训练完成得到k棵树,我们要预测一个样本的分数,其实就是根据这个样本的特征,在每棵树中会落到对应的一个叶子节点,每个叶子节点就对应一个分数
  3. 最后只需要将每棵树对应的分数加起来就是该样本的预测值。

显然,我们的目标是要使得树群的预测值尽量接近真实值,而且有尽量大的泛化能力。类似之前GBDT的套路,XGBoost也是需要将多棵树的得分累加得到最终的预测得分(每一次迭代,都在现有树的基础上,增加一棵树去拟合前面树的预测结果与真实值之间的残差)。

那接下来,我们如何选择每一轮加入什么 f 呢?答案是非常直接的,选取一个 f 来使得我们的目标函数尽量最大地降低。这里 f 可以使用泰勒展开公式近似。

实质是把样本分配到叶子结点会对应一个obj,优化过程就是obj优化。也就是分裂节点到叶子不同的组合,不同的组合对应不同obj,所有的优化围绕这个思想展开。到目前为止我们讨论了目标函数中的第一个部分:训练误差。接下来我们讨论目标函数的第二个部分:正则项,即如何定义树的复杂度。

1.2 正则项:树的复杂度

XGBoost对树的复杂度包含了两个部分:

  • 一个是树里面叶子节点的个数T
  • 一个是树上叶子节点的得分w的L2模平方(对w进行L2正则化,相当于针对每个叶结点的得分增加L2平滑,目的是为了避免过拟合)

我们再来看一下XGBoost的目标函数(损失函数揭示训练误差 + 正则化定义复杂度):

正则化公式也就是目标函数的后半部分,对于上式而言,是整个累加模型的输出,正则化项∑kΩ(ft)是则表示树的复杂度的函数,值越小复杂度越低,泛化能力越强。

1.3 树该怎么长

很有意思的一个事是,我们从头到尾了解了xgboost如何优化、如何计算,但树到底长啥样,我们却一直没看到。很显然,一棵树的生成是由一个节点一分为二,然后不断分裂最终形成为整棵树。那么树怎么分裂的就成为了接下来我们要探讨的关键。对于一个叶子节点如何进行分裂,XGBoost作者在其原始论文中给出了一种分裂节点的方法:枚举所有不同树结构的贪心法

不断地枚举不同树的结构,然后利用打分函数来寻找出一个最优结构的树,接着加入到模型中,不断重复这样的操作。这个寻找的过程使用的就是贪心算法。选择一个feature分裂,计算loss function最小值,然后再选一个feature分裂,又得到一个loss function最小值,你枚举完,找一个效果最好的,把树给分裂,就得到了小树苗。

总而言之,XGBoost使用了和CART回归树一样的想法,利用贪婪算法,遍历所有特征的所有特征划分点,不同的是使用的目标函数不一样。具体做法就是分裂后的目标函数值比单子叶子节点的目标函数的增益,同时为了限制树生长过深,还加了个阈值,只有当增益大于该阈值才进行分裂。从而继续分裂,形成一棵树,再形成一棵树,每次在上一次的预测基础上取最优进一步分裂/建树。

1.4 如何停止树的循环生成

凡是这种循环迭代的方式必定有停止条件,什么时候停止呢?简言之,设置树的最大深度、当样本权重和小于设定阈值时停止生长以防止过拟合。具体而言,则

  1. 当引入的分裂带来的增益小于设定阀值的时候,我们可以忽略掉这个分裂,所以并不是每一次分裂loss function整体都会增加的,有点预剪枝的意思,阈值参数为(即正则项里叶子节点数T的系数);
  2. 当树达到最大深度时则停止建立决策树,设置一个超参数max_depth,避免树太深导致学习局部样本,从而过拟合;
  3. 样本权重和小于设定阈值时则停止建树。什么意思呢,即涉及到一个超参数-最小的样本权重和min_child_weight,和GBM的 min_child_leaf 参数类似,但不完全一样。大意就是一个叶子节点样本太少了,也终止同样是防止过拟合;

2. XGBoost与GBDT有什么不同

除了算法上与传统的GBDT有一些不同外,XGBoost还在工程实现上做了大量的优化。总的来说,两者之间的区别和联系可以总结成以下几个方面。

  1. GBDT是机器学习算法,XGBoost是该算法的工程实现。
  2. 在使用CART作为基分类器时,XGBoost显式地加入了正则项来控制模 型的复杂度,有利于防止过拟合,从而提高模型的泛化能力。
  3. GBDT在模型训练时只使用了代价函数的一阶导数信息,XGBoost对代 价函数进行二阶泰勒展开,可以同时使用一阶和二阶导数。
  4. 传统的GBDT采用CART作为基分类器,XGBoost支持多种类型的基分类 器,比如线性分类器。
  5. 传统的GBDT在每轮迭代时使用全部的数据,XGBoost则采用了与随机 森林相似的策略,支持对数据进行采样。
  6. 传统的GBDT没有设计对缺失值进行处理,XGBoost能够自动学习出缺 失值的处理策略。

3. 为什么XGBoost要用泰勒展开,优势在哪里?

XGBoost使用了一阶和二阶偏导, 二阶导数有利于梯度下降的更快更准. 使用泰勒展开取得函数做自变量的二阶导数形式, 可以在不选定损失函数具体形式的情况下, 仅仅依靠输入数据的值就可以进行叶子分裂优化计算, 本质上也就把损失函数的选取和模型算法优化/参数选择分开了. 这种去耦合增加了XGBoost的适用性, 使得它按需选取损失函数, 可以用于分类, 也可以用于回归。

4. 代码实现

GitHub:点击进入

5. 参考文献

通俗理解kaggle比赛大杀器xgboost

作者:@mantchs

GitHub:https://github.com/NLP-LOVE/ML-NLP

欢迎大家加入讨论!共同完善此项目!群号:【541954936】NLP面试学习群

贝叶斯网络 历史版本:
上次修改时间: 2022-02-09 09:42:01

目录

1. 对概率图模型的理解

概率图模型是用图来表示变量概率依赖关系的理论,结合概率论与图论的知识,利用图来表示与模型有关的变量的联合概率分布。由图灵奖获得者Pearl开发出来。

如果用一个词来形容概率图模型(Probabilistic Graphical Model)的话,那就是“优雅”。对于一个实际问题,我们希望能够挖掘隐含在数据中的知识。概率图模型构建了这样一幅图,用观测结点表示观测到的数据,用隐含结点表示潜在的知识,用边来描述知识与数据的相互关系,最后基于这样的关系图获得一个概率分布,非常“优雅”地解决了问题。

概率图中的节点分为隐含节点和观测节点,边分为有向边和无向边。从概率论的角度,节点对应于随机变量,边对应于随机变量的依赖或相关关系,其中有向边表示单向的依赖,无向边表示相互依赖关系

概率图模型分为贝叶斯网络(Bayesian Network)和马尔可夫网络(Markov Network)两大类。贝叶斯网络可以用一个有向图结构表示,马尔可夫网络可以表 示成一个无向图的网络结构。更详细地说,概率图模型包括了朴素贝叶斯模型、最大熵模型、隐马尔可夫模型、条件随机场、主题模型等,在机器学习的诸多场景中都有着广泛的应用。

2. 细数贝叶斯网络

2.1 频率派观点

长久以来,人们对一件事情发生或不发生的概率,只有固定的0和1,即要么发生,要么不发生,从来不会去考虑某件事情发生的概率有多大,不发生的概率又是多大。而且概率虽然未知,但最起码是一个确定的值。比如如果问那时的人们一个问题:“有一个袋子,里面装着若干个白球和黑球,请问从袋子中取得白球的概率是多少?”他们会想都不用想,会立马告诉你,取出白球的概率就是1/2,要么取到白球,要么取不到白球,即θ只能有一个值,而且不论你取了多少次,取得白球的概率θ始终都是1/2,即不随观察结果X 的变化而变化。

这种频率派的观点长期统治着人们的观念,直到后来一个名叫Thomas Bayes的人物出现。

2.2 贝叶斯学派

托马斯·贝叶斯Thomas Bayes(1702-1763)在世时,并不为当时的人们所熟知,很少发表论文或出版著作,与当时学术界的人沟通交流也很少,用现在的话来说,贝叶斯就是活生生一民间学术“屌丝”,可这个“屌丝”最终发表了一篇名为“An essay towards solving a problem in the doctrine of chances”,翻译过来则是:机遇理论中一个问题的解。你可能觉得我要说:这篇论文的发表随机产生轰动效应,从而奠定贝叶斯在学术史上的地位。

这篇论文可以用上面的例子来说明,“有一个袋子,里面装着若干个白球和黑球,请问从袋子中取得白球的概率θ是多少?”贝叶斯认为取得白球的概率是个不确定的值,因为其中含有机遇的成分。比如,一个朋友创业,你明明知道创业的结果就两种,即要么成功要么失败,但你依然会忍不住去估计他创业成功的几率有多大?你如果对他为人比较了解,而且有方法、思路清晰、有毅力、且能团结周围的人,你会不由自主的估计他创业成功的几率可能在80%以上。这种不同于最开始的“非黑即白、非0即1”的思考方式,便是贝叶斯式的思考方式。

先简单总结下频率派与贝叶斯派各自不同的思考方式:

  • 频率派把需要推断的参数θ看做是固定的未知常数,即概率虽然是未知的,但最起码是确定的一个值,同时,样本X 是随机的,所以频率派重点研究样本空间,大部分的概率计算都是针对样本X 的分布;
  • 而贝叶斯派的观点则截然相反,他们认为参数是随机变量,而样本X 是固定的,由于样本是固定的,所以他们重点研究的是参数的分布。

贝叶斯派既然把看做是一个随机变量,所以要计算的分布,便得事先知道的无条件分布,即在有样本之前(或观察到X之前),有着怎样的分布呢?

比如往台球桌上扔一个球,这个球落会落在何处呢?如果是不偏不倚的把球抛出去,那么此球落在台球桌上的任一位置都有着相同的机会,即球落在台球桌上某一位置的概率服从均匀分布。这种在实验之前定下的属于基本前提性质的分布称为先验分布,或着无条件分布

其中,先验信息一般来源于经验跟历史资料。比如林丹跟某选手对决,解说一般会根据林丹历次比赛的成绩对此次比赛的胜负做个大致的判断。再比如,某工厂每天都要对产品进行质检,以评估产品的不合格率θ,经过一段时间后便会积累大量的历史资料,这些历史资料便是先验知识,有了这些先验知识,便在决定对一个产品是否需要每天质检时便有了依据,如果以往的历史资料显示,某产品的不合格率只有0.01%,便可视为信得过产品或免检产品,只每月抽检一两次,从而省去大量的人力物力。

后验分布π(θ|X)一般也认为是在给定样本X的情况下的θ条件分布,而使π(θ|X)达到最大的值θMD称为最大后验估计,类似于经典统计学中的极大似然估计

综合起来看,则好比是人类刚开始时对大自然只有少得可怜的先验知识,但随着不断观察、实验获得更多的样本、结果,使得人们对自然界的规律摸得越来越透彻。所以,贝叶斯方法既符合人们日常生活的思考方式,也符合人们认识自然的规律,经过不断的发展,最终占据统计学领域的半壁江山,与经典统计学分庭抗礼。

2.3 贝叶斯定理

条件概率(又称后验概率)就是事件A在另外一个事件B已经发生条件下的发生概率。条件概率表示为P(A|B),读作“在B条件下A的概率”。

比如上图,在同一个样本空间Ω中的事件或者子集A与B,如果随机从Ω中选出的一个元素属于B,那么这个随机选择的元素还属于A的概率就定义为在B的前提下A的条件概率:

联合概率:

边缘概率(先验概率):P(A)或者P(B)

2.4 贝叶斯网络

贝叶斯网络(Bayesian network),又称信念网络(Belief Network),或有向无环图模型(directed acyclic graphical model),是一种概率图模型,于1985年由Judea Pearl首先提出。它是一种模拟人类推理过程中因果关系的不确定性处理模型,其网络拓朴结构是一个有向无环图(DAG)。

贝叶斯网络的有向无环图中的节点表示随机变量

它们可以是可观察到的变量,或隐变量、未知参数等。认为有因果关系(或非条件独立)的变量或命题则用箭头来连接。若两个节点间以一个单箭头连接在一起,表示其中一个节点是“因(parents)”,另一个是“果(children)”,两节点就会产生一个条件概率值。

例如,假设节点E直接影响到节点H,即E→H,则用从E指向H的箭头建立结点E到结点H的有向弧(E,H),权值(即连接强度)用条件概率P(H|E)来表示,如下图所示:

简言之,把某个研究系统中涉及的随机变量,根据是否条件独立绘制在一个有向图中,就形成了贝叶斯网络。其主要用来描述随机变量之间的条件依赖,用圈表示随机变量(random variables),用箭头表示条件依赖(conditional dependencies)。

此外,对于任意的随机变量,其联合概率可由各自的局部条件概率分布相乘而得出:

2.4.1 贝叶斯网络的结构形式

1. head-to-head

依上图,所以有:P(a,b,c) = P(a)*P(b)*P(c|a,b)成立,即在c未知的条件下,a、b被阻断(blocked),是独立的,称之为head-to-head条件独立。

2. tail-to-tail

考虑c未知,跟c已知这两种情况:

  1. 在c未知的时候,有:P(a,b,c)=P(c)*P(a|c)*P(b|c),此时,没法得出P(a,b) = P(a)P(b),即c未知时,a、b不独立。
  2. 在c已知的时候,有:P(a,b|c)=P(a,b,c)/P(c),然后将P(a,b,c)=P(c)*P(a|c)*P(b|c)带入式子中,得到:P(a,b|c)=P(a,b,c)/P(c) = P(c)*P(a|c)*P(b|c) / P(c) = P(a|c)*P(b|c),即c已知时,a、b独立。

3. head-to-tail

还是分c未知跟c已知这两种情况:

  1. c未知时,有:P(a,b,c)=P(a)*P(c|a)*P(b|c),但无法推出P(a,b) = P(a)P(b),即c未知时,a、b不独立。

  2. c已知时,有:P(a,b|c)=P(a,b,c)/P(c),且根据P(a,c) = P(a)*P(c|a) = P(c)*P(a|c),可化简得到:

    所以,在c给定的条件下,a,b被阻断(blocked),是独立的,称之为head-to-tail条件独立。

    这个head-to-tail其实就是一个链式网络,如下图所示:

    根据之前对head-to-tail的讲解,我们已经知道,在xi给定的条件下,xi+1的分布和x1,x2…xi-1条件独立。意味着啥呢?意味着:xi+1的分布状态只和xi有关,和其他变量条件独立。通俗点说,当前状态只跟上一状态有关,跟上上或上上之前的状态无关。这种顺次演变的随机过程,就叫做马尔科夫链(Markov chain)。对于马尔科夫链我们下一节再细讲。

2.4.2 因子图

wikipedia上是这样定义因子图的:将一个具有多变量的全局函数因子分解,得到几个局部函数的乘积,以此为基础得到的一个双向图叫做因子图(Factor Graph)。

通俗来讲,所谓因子图就是对函数进行因子分解得到的一种概率图。一般内含两种节点:变量节点和函数节点。我们知道,一个全局函数通过因式分解能够分解为多个局部函数的乘积,这些局部函数和对应的变量关系就体现在因子图上。

举个例子,现在有一个全局函数,其因式分解方程为:

其中fA,fB,fC,fD,fE为各函数,表示变量之间的关系,可以是条件概率也可以是其他关系。其对应的因子图为:

在概率图中,求某个变量的边缘分布是常见的问题。这问题有很多求解方法,其中之一就是把贝叶斯网络或马尔科夫随机场转换成因子图,然后用sum-product算法求解。换言之,基于因子图可以用sum-product 算法高效的求各个变量的边缘分布。

详细的sum-product算法过程,请查看博文:从贝叶斯方法谈到贝叶斯网络

2.5 朴素贝叶斯

朴素贝叶斯(Naive Bayesian)是经典的机器学习算法之一,也是为数不多的基于概率论的分类算法。朴素贝叶斯原理简单,也很容易实现,多用于文本分类,比如垃圾邮件过滤。**朴素贝叶斯可以看做是贝叶斯网络的特殊情况:即该网络中无边,各个节点都是独立的。 **

朴素贝叶斯朴素在哪里呢? —— 两个假设

  • 一个特征出现的概率与其他特征(条件)独立;
  • 每个特征同等重要。

贝叶斯公式如下:

下面以一个例子来解释朴素贝叶斯,给定数据如下:

现在给我们的问题是,如果一对男女朋友,男生想女生求婚,男生的四个特点分别是不帅,性格不好,身高矮,不上进,请你判断一下女生是嫁还是不嫁?

这是一个典型的分类问题,转为数学问题就是比较p(嫁|(不帅、性格不好、身高矮、不上进))与p(不嫁|(不帅、性格不好、身高矮、不上进))的概率,谁的概率大,我就能给出嫁或者不嫁的答案!这里我们联系到朴素贝叶斯公式:

我们需要求p(嫁|(不帅、性格不好、身高矮、不上进),这是我们不知道的,但是通过朴素贝叶斯公式可以转化为好求的三个量,这三个变量都能通过统计的方法求得。

等等,为什么这个成立呢?学过概率论的同学可能有感觉了,这个等式成立的条件需要特征之间相互独立吧!对的!这也就是为什么朴素贝叶斯分类有朴素一词的来源,朴素贝叶斯算法是假设各个特征之间相互独立,那么这个等式就成立了!

但是为什么需要假设特征之间相互独立呢?

  1. 我们这么想,假如没有这个假设,那么我们对右边这些概率的估计其实是不可做的,这么说,我们这个例子有4个特征,其中帅包括{帅,不帅},性格包括{不好,好,爆好},身高包括{高,矮,中},上进包括{不上进,上进},那么四个特征的联合概率分布总共是4维空间,总个数为233*2=36个。

    36个,计算机扫描统计还可以,但是现实生活中,往往有非常多的特征,每一个特征的取值也是非常之多,那么通过统计来估计后面概率的值,变得几乎不可做,这也是为什么需要假设特征之间独立的原因。

  2. 假如我们没有假设特征之间相互独立,那么我们统计的时候,就需要在整个特征空间中去找,比如统计p(不帅、性格不好、身高矮、不上进|嫁),我们就需要在嫁的条件下,去找四种特征全满足分别是不帅,性格不好,身高矮,不上进的人的个数,这样的话,由于数据的稀疏性,很容易统计到0的情况。 这样是不合适的。

根据上面俩个原因,朴素贝叶斯法对条件概率分布做了条件独立性的假设,由于这是一个较强的假设,朴素贝叶斯也由此得名!这一假设使得朴素贝叶斯法变得简单,但有时会牺牲一定的分类准确率。

朴素贝叶斯优点

  • 算法逻辑简单,易于实现(算法思路很简单,只要使用贝叶斯公式转化即可!)
  • 分类过程中时空开销小(假设特征相互独立,只会涉及到二维存储)

朴素贝叶斯缺点

理论上,朴素贝叶斯模型与其他分类方法相比具有最小的误差率。但是实际上并非总是如此,这是因为朴素贝叶斯模型假设属性之间相互独立,这个假设在实际应用中往往是不成立的,在属性个数比较多或者属性之间相关性较大时,分类效果不好。

朴素贝叶斯模型(Naive Bayesian Model)的**朴素(Naive)的含义是"很简单很天真"**地假设样本特征彼此独立. 这个假设现实中基本上不存在, 但特征相关性很小的实际情况还是很多的, 所以这个模型仍然能够工作得很好。

3. 基于贝叶斯的一些问题

  1. 解释朴素贝叶斯算法里面的先验概率、似然估计和边际似然估计?
    • 先验概率:就是因变量(二分法)在数据集中的比例。这是在你没有任何进一步的信息的时候,是对分类能做出的最接近的猜测。
    • 似然估计:似然估计是在其他一些变量的给定的情况下,一个观测值被分类为1的概率。例如,“FREE”这个词在以前的垃圾邮件使用的概率就是似然估计。
    • 边际似然估计:边际似然估计就是,“FREE”这个词在任何消息中使用的概率。

4. 生成式模型和判别式模型的区别

  • 判别模型(discriminative model)通过求解条件概率分布P(y|x)或者直接计算y的值来预测y。

    线性回归(Linear Regression),逻辑回归(Logistic Regression),支持向量机(SVM), 传统神经网络(Traditional Neural Networks),线性判别分析(Linear Discriminative Analysis),条件随机场(Conditional Random Field)

  • 生成模型(generative model)通过对观测值和标注数据计算联合概率分布P(x,y)来达到判定估算y的目的。

    朴素贝叶斯(Naive Bayes), 隐马尔科夫模型(HMM),贝叶斯网络(Bayesian Networks)和隐含狄利克雷分布(Latent Dirichlet Allocation)、混合高斯模型

5. 代码实现

新闻分类 GitHub:点击进入

6. 参考文献

从贝叶斯方法谈到贝叶斯网络

作者:@mantchs

GitHub:https://github.com/NLP-LOVE/ML-NLP

欢迎大家加入讨论!共同完善此项目!群号:【541954936】NLP面试学习群

RNN 历史版本:
上次修改时间: 2022-02-09 09:41:54

目录

1. 什么是RNN

循环神经网络(Recurrent Neural Network, RNN)是一类以序列(sequence)数据为输入,在序列的演进方向进行递归(recursion)且所有节点(循环单元)按链式连接的递归神经网络(recursive neural network)

1.1 RNN的应用

  • 文本生成(生成序列)
  • 机器翻译
  • 看图说话
  • 文本(情感)分析
  • 智能客服
  • 聊天机器人
  • 语音识别
  • 搜索引擎
  • 个性化推荐

1.2 为什么有了CNN,还要RNN?

  • 传统神经网络(包括CNN),输入和输出都是互相独立的。图像上的猫和狗是分隔开的,但有些任务,后续的输出和之前的内容是相关的。例如:我是中国人,我的母语是____。这是一道填空题,需要依赖于之前的输入。
  • 所以,RNN引入“记忆”的概念,也就是输出需要依赖于之前的输入序列,并把关键输入记住。循环2字来源于其每个元素都执行相同的任务。
  • 它并⾮刚性地记忆所有固定⻓度的序列,而是通过隐藏状态来存储之前时间步的信息。

1.3 RNN的网络结构

首先先上图,然后再解释:

现在我们考虑输⼊数据存在时间相关性的情况。假设 是序列中时间步t的小批量输⼊, 是该时间步的隐藏变量。那么根据以上结构图当前的隐藏变量的公式如下:

从以上公式我们可以看出,这⾥我们保存上⼀时间步的隐藏变量 ,并引⼊⼀个新的权重参数,该参数⽤来描述在当前时间步如何使⽤上⼀时间步的隐藏变量。具体来说,时间步 t 的隐藏变量的计算由当前时间步的输⼊和上⼀时间步的隐藏变量共同决定。 函数其实就是激活函数。

我们在这⾥添加了 ⼀项。由上式中相邻时间步的隐藏变量 ![](https://latex.codecogs.com/gif.latex?H_t 和H_{t-1})之间的关系可知,这⾥的隐藏变量能够捕捉截⾄当前时间步的序列的历史信息,就像是神经⽹络当前时间步的状态或记忆⼀样。因此,该隐藏变量也称为隐藏状态。由于隐藏状态在当前时间步的定义使⽤了上⼀时间步的隐藏状态,上式的计算是循环的。使⽤循环计算的⽹络即循环神经⽹络(recurrent neural network)。

在时间步t,输出层的输出和多层感知机中的计算类似:

1.4 双向RNN

之前介绍的循环神经⽹络模型都是假设当前时间步是由前⾯的较早时间步的序列决定的,因此它 们都将信息通过隐藏状态从前往后传递。有时候,当前时间步也可能由后⾯时间步决定。例如, 当我们写下⼀个句⼦时,可能会根据句⼦后⾯的词来修改句⼦前⾯的⽤词。双向循环神经⽹络通过增加从后往前传递信息的隐藏层来更灵活地处理这类信息。下图演⽰了⼀个含单隐藏层的双向循环神经⽹络的架构。

在双向循环神经⽹络的架构中,设该时间步正向隐藏状态为 (正向隐藏单元个数为h),反向隐藏状态为 (反向隐藏单元个数为h)。我们可以分别 计算正向隐藏状态和反向隐藏状态:

然后我们连结两个⽅向的隐藏状态 来得到隐藏状态 ,并将其输⼊到输出层。输出层计算输出 (输出个数为q):

双向循环神经⽹络在每个时间步的隐藏状态同时取决于该时间步之前和之后的⼦序列(包 括当前时间步的输⼊)。

1.5 BPTT算法

image

在之前你已经见过对于前向传播(上图蓝色箭头所指方向)怎样在神经网络中从左到右地计算这些激活项,直到输出所有地预测结果。而对于反向传播,我想你已经猜到了,反向传播地计算方向(上图红色箭头所指方向)与前向传播基本上是相反的。

我们先定义一个元素损失函数:

整个序列的损失函数:

在这个计算图中,通过 可以计算对应的损失函数,于是计算出第一个时间步的损失函数,然后计算出第二个时间步的损失函数,然后是第三个时间步,一直到最后一个时间步,最后为了计算出总体损失函数,我们要把它们都加起来,通过等式计算出最后的𝐿,也就是把每个单独时间步的损失函数都加起来。然后你就可以通过导数相关的参数,用梯度下降法来更新参数。

在这个反向传播的过程中,最重要的信息传递或者说最重要的递归运算就是这个从右到左的运算,这也就是为什么这个算法有一个很别致的名字,叫做“通过(穿越)时间反向传播(backpropagation through time)”。取这个名字的原因是对于前向传播,你需要从左到右进行计算,在这个过程中,时刻𝑡不断增加。而对于反向传播,你需要从右到左进行计算,就像时间倒流。“通过时间反向传播”,就像穿越时光,这种说法听起来就像是你需要一台时光机来实现这个算法一样。

2. 其它类型的RNN

  • One to one:这个可能没有那么重要,这就是一个小型的标准的神经网络,输入𝑥然后得到输出𝑦。

  • One to many:音乐生成,你的目标是使用一个神经网络输出一些音符。对应于一段音乐,输入𝑥

    可以是一个整数,表示你想要的音乐类型或者是你想要的音乐的第一个音符,并且如果你什么都不想输入,𝑥可以是空的输入,可设为 0 向量。

  • Many to one:句子分类问题,输入文档,输出文档的类型。

  • Many to many():命名实体识别。

  • Many to many():机器翻译。

image

3. CNN与RNN的区别

类别 特点描述
相同点 1、传统神经网络的扩展。
2、前向计算产生结果,反向计算模型更新。
3、每层神经网络横向可以多个神经元共存,纵向可以有多层神经网络连接。
不同点 1、CNN空间扩展,神经元与特征卷积;RNN时间扩展,神经元与多个时间输出计算
2、RNN可以用于描述时间上连续状态的输出,有记忆功能,CNN用于静态输出

4. 为什么RNN 训练的时候Loss波动很大

由于RNN特有的memory会影响后期其他的RNN的特点,梯度时大时小,learning rate没法个性化的调整,导致RNN在train的过程中,Loss会震荡起伏,为了解决RNN的这个问题,在训练的时候,可以设置临界值,当梯度大于某个临界值,直接截断,用这个临界值作为梯度的大小,防止大幅震荡。

5. 实例代码

TensorFlow实现RNN


作者:@mantchs

GitHub:https://github.com/NLP-LOVE/ML-NLP

欢迎大家加入讨论!共同完善此项目!群号:【541954936】NLP面试学习群

CNN 历史版本:
上次修改时间: 2022-02-09 09:41:48

目录

1. 什么是CNN

卷积神经网络(Convolutional Neural Networks, CNN)是一类包含卷积计算且具有深度结构的前馈神经网络(Feedforward Neural Networks),是深度学习(deep learning)的代表算法之一。

我们先来看卷积神经网络各个层级结构图:

image.png

上图中CNN要做的事情是:给定一张图片,是车还是马未知,是什么车也未知,现在需要模型判断这张图片里具体是一个什么东西,总之输出一个结果:如果是车 那是什么车。

  • 最左边是数据输入层(input layer),对数据做一些处理,比如去均值(把输入数据各个维度都中心化为0,避免数据过多偏差,影响训练效果)、归一化(把所有的数据都归一到同样的范围)、PCA/白化等等。CNN只对训练集做“去均值”这一步。
  • CONV:卷积计算层(conv layer),线性乘积求和。
  • RELU:激励层(activation layer),下文有提到:ReLU是激活函数的一种。
  • POOL:池化层(pooling layer),简言之,即取区域平均或最大。
  • FC:全连接层(FC layer)。

这几个部分中,卷积计算层是CNN的核心。

1.1 输入层

在做输入的时候,需要把图片处理成同样大小的图片才能够进行处理。

常见的处理数据的方式有:

  1. 去均值(常用)

    • AlexNet:训练集中100万张图片,对每个像素点求均值,得到均值图像,当训练时用原图减去均值图像。
    • VGG:对所有输入在三个颜色通道R/G/B上取均值,只会得到3个值,当训练时减去对应的颜色通道均值。(此种方法效率高)

    **TIPS:**在训练集和测试集上减去训练集的均值。

  2. 归一化

    幅度归一化到同样的范围。

  3. PCA/白化(很少用)

    • 用PCA降维
    • 白化是对数据每个特征轴上的幅度归一化。

1.2 卷积计算层(conv)

对图像(不同的数据窗口数据)和滤波矩阵(一组固定的权重:因为每个神经元的多个权重固定,所以又可以看做一个恒定的滤波器filter)做内积(逐个元素相乘再求和)的操作就是所谓的『卷积』操作,也是卷积神经网络的名字来源。

不同的滤波器filter会得到不同的输出数据,比如颜色深浅、轮廓。相当于提取图像的不同特征,模型就能够学习到多种特征。用不同的滤波器filter,提取想要的关于图像的特定信息:颜色深浅或轮廓。如下图所示。

image.png

在CNN中,滤波器filter(带着一组固定权重的神经元)对局部输入数据进行卷积计算。每计算完一个数据窗口内的局部数据后,数据窗口不断平移滑动,直到计算完所有数据。这个过程中,有这么几个参数:

  • 深度depth:神经元个数,决定输出的depth厚度。同时代表滤波器个数。
  • 步长stride:决定滑动多少步可以到边缘。
  • 填充值zero-padding:在外围边缘补充若干圈0,方便从初始位置以步长为单位可以刚好滑倒末尾位置,通俗地讲就是为了总长能被步长整除。

image.png

  • 参数共享机制

    假设每个神经元连接数据窗的权重是固定对的。固定每个神经元连接权重,可以看做模板,每个神经元只关注**一个特性(模板)**,这使得需要估算的权重个数减少:一层中从1亿到3.5万。

  • 一组固定的权重和不同窗口内数据做内积:卷积

  • 作用在于捕捉某一种模式,具体表现为很大的值。

卷积操作的本质特性包括稀疏交互和参数共享

1.3 激励层

把卷积层输出结果做非线性映射。

激活函数有:

UTOOLS1556084241657.png

  • sigmoid:在两端斜率接近于0,梯度消失。
  • ReLu:修正线性单元,有可能出现斜率为0,但概率很小,因为mini-batch是一批样本损失求导之和。

TIPS:

  • CNN慎用sigmoid!慎用sigmoid!慎用sigmoid!
  • 首先试RELU,因为快,但要小心点。
  • 如果RELU失效,请用 Leaky ReLU或者Maxout。
  • 某些情况下tanh倒是有不错的结果,但是很少。

1.4 池化层

也叫下采样层,就算通过了卷积层,纬度还是很高 ,需要进行池化层操作。

  • 夹在连续的卷积层中间。
  • 压缩数据和参数的量,降低维度。
  • 减小过拟合。
  • 具有特征不变性。

方式有:Max pooling、average pooling

image

Max pooling

取出每个部分的最大值作为输出,例如上图左上角的4个黄色方块取最大值为3作为输出,以此类推。

average pooling

每个部分进行计算得到平均值作为输出,例如上图左上角的4个黄色方块取得平均值2作为输出,以此类推。

1.5 全连接层

全连接层的每一个结点都与上一层的所有结点相连,用来把前边提取到的特征综合起来。由于其全连接的特性,一般全连接层的参数也是最多的。

  • 两层之间所有神经元都有权重连接
  • 通常全连接层在卷积神经网络尾部

1.6 层次结构小结

CNN层次结构 作用
输入层 卷积网络的原始输入,可以是原始或预处理后的像素矩阵
卷积层 参数共享、局部连接,利用平移不变性从全局特征图提取局部特征
激活层 将卷积层的输出结果进行非线性映射
池化层 进一步筛选特征,可以有效减少后续网络层次所需的参数量
全连接层 用于把该层之前提取到的特征综合起来。

1.7 CNN优缺点

优点:

  • 共享卷积核,优化计算量。
  • 无需手动选取特征,训练好权重,即得特征。
  • 深层次的网络抽取图像信息丰富,表达效果好。
  • 保持了层级网络结构。
  • 不同层次有不同形式与功能。

缺点:

  • 需要调参,需要大样本量,GPU等硬件依赖。
  • 物理含义不明确。

与NLP/Speech共性:

都存在局部与整体的关系,由低层次的特征经过组合,组成高层次的特征,并且得到不同特征之间的空间相关性。

2. 典型CNN发展历程

  • LeNet,这是最早用于数字识别的CNN
  • AlexNet, 2012 ILSVRC比赛远超第2名的CNN,比LeNet更深,用多层小卷积层叠加替换单大卷积层。
  • ZF Net, 2013 ILSVRC比赛冠军
  • GoogLeNet, 2014 ILSVRC比赛冠军
  • VGGNet, 2014 ILSVRC比赛中的模型,图像识别略差于GoogLeNet,但是在很多图像转化学习问题(比如objectdetection)上效果很好
  • ResNet(深度残差网络(Deep Residual Network,ResNet)), 2015ILSVRC比赛冠军,结构修正(残差学习)以适应深层次CNN训练。
  • DenseNet, CVPR2017 best paper,把ResNet的add变成concat

3. 图像相关任务

image

3.1 图像识别与定位

  1. classification:C个类别识别

    • input:Image
    • Output:类别标签
    • Evaluation metric:准确率
  2. Localization定位)

    • Input:Image

    • Output:物体边界框(x,y,w,h)

    • Evaluation metric:交并准则(IOU) > 0.5 图中阴影部分所占面积

      image

3.1.1 思路1:识别+定位过程

  1. 识别可以看作多分类问题(用softmax),用别人训练好的CNN模型做fine-tune

  2. 定位的目标是(x,y,w,h)是连续值,当回归问题解决(mse)

    1的CNN尾部展开(例如把最后一层拿开),接上一个(x,y,w,h)的神经网络,成为classification+regression的模型

    更细致的识别可以提前规定好有k个组成部分,做成k个部分的回归,

    例如:框出两只眼睛和两条腿,4元祖*4=16(个连续值)

  3. Regression部分用欧氏距离损失,使用SGD训练。

image

3.1.2 思路2:图窗+识别

  • 类似刚才的classification+regression思路
  • 咱们取不同大小的“框”
  • 让框出现在不同的位置
  • 判定得分
  • 按照得分的高低对“结果框”做抽样和合并

image.png

3.2 物体检测(object detection)

3.2.1 过程

当图像有很多物体怎么办的?难度可是一下暴增啊。

那任务就变成了:多物体识别+定位多个物体,那把这个任务看做分类问题?

image.png

看成分类问题有何不妥?

  • 你需要找很多位置, 给很多个不同大小的框
  • 你还需要对框内的图像分类
  • 当然, 如果你的GPU很强大, 恩, 那加油做吧…

边缘策略:想办法先找到可能包含内容的图框(候选框),然后进行分类问题的识别。

方法:根据RGB值做区域融合。fast-CNN,共享图窗,从而加速候选框的形成。

  • R-CNN => fast-CNN => faster-RCNN 速度对比

image.png

3.2.2 R-CNN

R-CNN的简要步骤如下:

  1. 输入测试图像。
  2. 利用选择性搜索Selective Search算法在图像中从下到上提取2000个左右的可能包含物体的候选区域Region Proposal。
  3. 因为取出的区域大小各自不同,所以需要将每个Region Proposal缩放(warp)成统一的227x227的大小并输入到CNN,将CNN的fc7层的输出作为特征。
  4. 将每个Region Proposal提取到的CNN特征输入到SVM进行分类。

3.2.3 SPP-Net

SPP:Spatial Pyramid Pooling(空间金字塔池化),SPP-Net是出自2015年发表在IEEE上的论文。

众所周知,CNN一般都含有卷积部分和全连接部分,其中,卷积层不需要固定尺寸的图像,而全连接层是需要固定大小的输入。所以当全连接层面对各种尺寸的输入数据时,就需要对输入数据进行crop(crop就是从一个大图扣出网络输入大小的patch,比如227×227),或warp(把一个边界框bounding box(红框)的内容resize成227×227)等一系列操作以统一图片的尺寸大小,比如224224(ImageNet)、3232(LenNet)、96*96等。

所以才如你在上文中看到的,在R-CNN中,“因为取出的区域大小各自不同,所以需要将每个Region Proposal缩放(warp)成统一的227x227的大小并输入到CNN”。

但warp/crop这种预处理,导致的问题要么被拉伸变形、要么物体不全,限制了识别精确度。没太明白?说句人话就是,一张16:9比例的图片你硬是要Resize成1:1的图片,你说图片失真不?

SPP Net的作者Kaiming He等人逆向思考,既然由于全连接FC层的存在,普通的CNN需要通过固定输入图片的大小来使得全连接层的输入固定。那借鉴卷积层可以适应任何尺寸,为何不能在卷积层的最后加入某种结构,使得后面全连接层得到的输入变成固定的呢?

这个“化腐朽为神奇”的结构就是spatial pyramid pooling layer。

它的特点有两个:

  1. 结合空间金字塔方法实现CNNs的多尺度输入。

    SPP Net的第一个贡献就是在最后一个卷积层后,接入了金字塔池化层,保证传到下一层全连接层的输入固定。

    换句话说,在普通的CNN机构中,输入图像的尺寸往往是固定的(比如224*224像素),输出则是一个固定维数的向量。SPP Net在普通的CNN结构中加入了ROI池化层(ROI Pooling),使得网络的输入图像可以是任意尺寸的,输出则不变,同样是一个固定维数的向量。

    简言之,CNN原本只能固定输入、固定输出,CNN加上SSP之后,便能任意输入、固定输出。神奇吧?

  2. 只对原图提取一次卷积特征

    在R-CNN中,每个候选框先resize到统一大小,然后分别作为CNN的输入,这样是很低效的。

    而SPP Net根据这个缺点做了优化:只对原图进行一次卷积计算,便得到整张图的卷积特征feature map,然后找到每个候选框在feature map上的映射patch,将此patch作为每个候选框的卷积特征输入到SPP layer和之后的层,完成特征提取工作。

如此这般,R-CNN要对每个区域计算卷积,而SPPNet只需要计算一次卷积,从而节省了大量的计算时间,比R-CNN有一百倍左右的提速。

3.2.4 Fast R-CNN

SPP Net真是个好方法,R-CNN的进阶版Fast R-CNN就是在R-CNN的基础上采纳了SPP Net方法,对R-CNN作了改进,使得性能进一步提高。

R-CNN有一些相当大的缺点(把这些缺点都改掉了,就成了Fast R-CNN)。

大缺点:由于每一个候选框都要独自经过CNN,这使得花费的时间非常多。

解决:共享卷积层,现在不是每一个候选框都当做输入进入CNN了,而是输入一张完整的图片,在第五个卷积层再得到每个候选框的特征。

原来的方法:许多候选框(比如两千个)-->CNN-->得到每个候选框的特征-->分类+回归

现在的方法:一张完整图片-->CNN-->得到每张候选框的特征-->分类+回归

所以容易看见,Fast R-CNN相对于R-CNN的提速原因就在于:不过不像R-CNN把每个候选区域给深度网络提特征,而是整张图提一次特征,再把候选框映射到conv5上,而SPP只需要计算一次特征,剩下的只需要在conv5层上操作就可以了。

算法步骤:

  1. 在图像中确定约1000-2000个候选框 (使用选择性搜索)。
  2. 对整张图片输进CNN,得到feature map。
  3. 找到每个候选框在feature map上的映射patch,将此patch作为每个候选框的卷积特征输入到SPP layer和之后的层。
  4. 对候选框中提取出的特征,使用分类器判别是否属于一个特定类。
  5. 对于属于某一类别的候选框,用回归器进一步调整其位置。

3.2.5 Faster R-CNN

Fast R-CNN存在的问题:存在瓶颈:选择性搜索,找出所有的候选框,这个也非常耗时。那我们能不能找出一个更加高效的方法来求出这些候选框呢?

解决:加入一个提取边缘的神经网络,也就说找到候选框的工作也交给神经网络来做了。

所以,rgbd在Fast R-CNN中引入Region Proposal Network(RPN)替代Selective Search,同时引入anchor box应对目标形状的变化问题(anchor就是位置和大小固定的box,可以理解成事先设置好的固定的proposal)。这就是Faster R-CNN。

算法步骤:

  1. 对整张图片输进CNN,得到feature map。
  2. 卷积特征输入到RPN,得到候选框的特征信息。
  3. 对候选框中提取出的特征,使用分类器判别是否属于一个特定类。
  4. 对于属于某一类别的候选框,用回归器进一步调整其位置。

3.2.6 YOLO

Faster R-CNN的方法目前是主流的目标检测方法,但是速度上并不能满足实时的要求。YOLO一类的方法慢慢显现出其重要性,这类方法使用了回归的思想,利用整张图作为网络的输入,直接在图像的多个位置上回归出这个位置的目标边框,以及目标所属的类别。

我们直接看上面YOLO的目标检测的流程图:

  1. 给个一个输入图像,首先将图像划分成7*7的网格。
  2. 对于每个网格,我们都预测2个边框(包括每个边框是目标的置信度以及每个边框区域在多个类别上的概率)。
  3. 根据上一步可以预测出772个目标窗口,然后根据阈值去除可能性比较低的目标窗口,最后NMS去除冗余窗口即可。

小结:YOLO将目标检测任务转换成一个回归问题,大大加快了检测的速度,使得YOLO可以每秒处理45张图像。而且由于每个网络预测目标窗口时使用的是全图信息,使得false positive比例大幅降低(充分的上下文信息)。

但是YOLO也存在问题:没有了Region Proposal机制,只使用7*7的网格回归会使得目标不能非常精准的定位,这也导致了YOLO的检测精度并不是很高。

3.2.7 SSD

SSD: Single Shot MultiBox Detector。上面分析了YOLO存在的问题,使用整图特征在7*7的粗糙网格内回归对目标的定位并不是很精准。那是不是可以结合region proposal的思想实现精准一些的定位?SSD结合YOLO的回归思想以及Faster R-CNN的anchor机制做到了这点。

上图是SSD的一个框架图,首先SSD获取目标位置和类别的方法跟YOLO一样,都是使用回归,但是YOLO预测某个位置使用的是全图的特征,SSD预测某个位置使用的是这个位置周围的特征(感觉更合理一些)。

那么如何建立某个位置和其特征的对应关系呢?可能你已经想到了,使用Faster R-CNN的anchor机制。如SSD的框架图所示,假如某一层特征图(图b)大小是88,那么就使用33的滑窗提取每个位置的特征,然后这个特征回归得到目标的坐标信息和类别信息(图c)。

不同于Faster R-CNN,这个anchor是在多个feature map上,这样可以利用多层的特征并且自然的达到多尺度(不同层的feature map 3*3滑窗感受野不同)。

小结:SSD结合了YOLO中的回归思想和Faster R-CNN中的anchor机制,使用全图各个位置的多尺度区域特征进行回归,既保持了YOLO速度快的特性,也保证了窗口预测的跟Faster R-CNN一样比较精准。SSD在VOC2007上mAP可以达到72.1%,速度在GPU上达到58帧每秒。

3.3 语义(图像)分割

识别图上pixel的类别,用全卷积网络。

image

4. 代码实现CNN

cifar10数据集分类--CNN

5. 参考文献

  1. 基于深度学习的目标检测技术演进:R-CNN、Fast R-CNN、Faster R-CNN、YOLO、SSD
  2. 通俗理解卷积神经网络

作者:@mantchs

GitHub:https://github.com/NLP-LOVE/ML-NLP

欢迎大家加入讨论!共同完善此项目!群号:【541954936】NLP面试学习群

深度学习参数优化 历史版本:
上次修改时间: 2022-02-09 09:41:38

目录

1. 训练误差和泛化误差

机器学习模型在训练数据集和测试数据集上的表现。如果你改变过实验中的模型结构或者超参数,你也许发现了:当模型在训练数据集上更准确时,它在测试数据集上却不⼀定更准确。这是为什么呢?

因为存在着训练误差和泛化误差:

  • 训练误差:模型在训练数据集上表现出的误差。
  • 泛化误差:模型在任意⼀个测试数据样本上表现出的误差的期望,并常常通过测试数据集上的误差来近似。

训练误差的期望小于或等于泛化误差。也就是说,⼀般情况下,由训练数据集学到的模型参数会使模型在训练数据集上的表现优于或等于在测试数据集上的表现。由于⽆法从训练误差估计泛化误差,⼀味地降低训练误差并不意味着泛化误差⼀定会降低。

机器学习模型应关注降低泛化误差。

2. 该如何选择模型

在机器学习中,通常需要评估若⼲候选模型的表现并从中选择模型。这⼀过程称为模型选择(model selection)。可供选择的候选模型可以是有着不同超参数的同类模型。以多层感知机为例,我们可以选择隐藏层的个数,以及每个隐藏层中隐藏单元个数和激活函数。为了得到有效的模型,我们通常要在模型选择上下⼀番功夫。

2.1 验证数据集

从严格意义上讲,测试集只能在所有超参数和模型参数选定后使⽤⼀次。不可以使⽤测试数据选择模型,如调参。由于⽆法从训练误差估计泛化误差,因此也不应只依赖训练数据选择模型。鉴于此,我们可以预留⼀部分在训练数据集和测试数据集以外的数据来进⾏模型选择。这部分数据被称为验证数据集,简称验证集(validation set)。例如,我们可以从给定的训练集中随机选取⼀小部分作为验证集,而将剩余部分作为真正的训练集。

可以通过预留这样的验证集来进行模型选择,判断验证集在模型中的表现能力。

2.2 K 折交叉验证

由于验证数据集不参与模型训练,当训练数据不够⽤时,预留⼤量的验证数据显得太奢侈。⼀种改善的⽅法是K折交叉验证(K-fold cross-validation)。在K折交叉验证中,我们把原始训练数据集分割成K个不重合的⼦数据集,然后我们做K次模型训练和验证。每⼀次,我们使⽤⼀个⼦数据集验证模型,并使⽤其他K − 1个⼦数据集来训练模型。在这K次训练和验证中,每次⽤来验证模型的⼦数据集都不同。最后,我们对这K次训练误差和验证误差分别求平均。

3. ⽋拟合和过拟合

  • 欠拟合:模型⽆法得到较低的训练误差。
  • 过拟合:是模型的训练误差远小于它在测试数据集上的误差。

给定训练数据集,

  • 如果模型的复杂度过低,很容易出现⽋拟合;
  • 如果模型复杂度过⾼,很容易出现过拟合。

应对⽋拟合和过拟合的⼀个办法是针对数据集选择合适复杂度的模型。

训练数据集⼤⼩

影响⽋拟合和过拟合的另⼀个重要因素是训练数据集的⼤小。⼀般来说,如果训练数据集中样本数过少,特别是⽐模型参数数量(按元素计)更少时,过拟合更容易发⽣。此外,泛化误差不会随训练数据集⾥样本数量增加而增⼤。因此,在计算资源允许的范围之内,我们通常希望训练数据集⼤⼀些,特别是在模型复杂度较⾼时,例如层数较多的深度学习模型。

正则化

应对过拟合问题的常⽤⽅法:权重衰减(weight decay),权重衰减等价于L2范数正则化(regularization)。正则化通过为模型损失函数添加惩罚项使学出的模型参数值较小,是应对过拟合的常⽤⼿段。

4. 丢弃法(Dropout)

除了上面提到的权重衰减以外,深度学习模型常常使⽤丢弃法(dropout)来应对过拟合问题。丢弃法有⼀些不同的变体。本节中提到的丢弃法特指倒置丢弃法(inverted dropout)。

回忆⼀下,“多层感知机”描述了⼀个单隐藏层的多层感知机。其中输⼊个数为4,隐藏单元个数为5,且隐藏单元hi(i = 1, . . . , 5)的计算表达式为:

这⾥ϕ是激活函数,x1, . . . , x4是输⼊,隐藏单元i的权重参数为w1i, . . . , w4i,偏差参数为bi。当对该隐藏层使⽤丢弃法时,该层的隐藏单元将有⼀定概率被丢弃掉。设丢弃概率为p,那么有p的概率hi会被清零,有1 − p的概率hi会除以1 − p做拉伸。丢弃概率是丢弃法的超参数。具体来说,设随机变量ξi为0和1的概率分别为p和1 − p。使⽤丢弃法时我们计算新的隐藏单元

由于E(ξi) = 1 − p,因此:

即丢弃法不改变其输⼊的期望值。让我们对隐藏层使⽤丢弃法,⼀种可能的结果如下图所⽰,其中h2和h5被清零。这时输出值的计算不再依赖h2和h5,在反向传播时,与这两个隐藏单元相关的权重的梯度均为0。由于在训练中隐藏层神经元的丢弃是随机的,即h1, . . . , h5都有可能被清零,输出层的计算⽆法过度依赖h1, . . . , h5中的任⼀个,从而在训练模型时起到正则化的作⽤,并可以⽤来应对过拟合。在测试模型时,我们为了拿到更加确定性的结果,⼀般不使⽤丢弃法。

5. 梯度消失/梯度爆炸(Vanishing / Exploding gradients)

训练神经网络,尤其是深度神经所面临的一个问题就是梯度消失或梯度爆炸,也就是你训练神经网络的时候,导数或坡度有时会变得非常大,或者非常小,甚至于以指数方式变小,这加大了训练的难度。

本质上,梯度消失和爆炸是一种情况。在深层网络中,由于网络过深,如果初始得到的梯度过小,或者传播途中在某一层上过小,则在之后的层上得到的梯度会越来越小,即产生了梯度消失。梯度爆炸也是同样的。一般地,不合理的初始化以及激活函数,如sigmoid等,都会导致梯度过大或者过小,从而引起消失/爆炸。

解决方案

  1. 预训练加微调

    其基本思想是每次训练一层隐节点,训练时将上一层隐节点的输出作为输入,而本层隐节点的输出作为下一层隐节点的输入,此过程就是逐层“预训练”(pre-training);在预训练完成后,再对整个网络进行“微调”(fine-tunning)。

    此方法有一定的好处,但是目前应用的不是很多了。

  2. 梯度剪切、正则

    梯度剪切这个方案主要是针对梯度爆炸提出的,其思想是设置一个梯度剪切阈值,然后更新梯度的时候,如果梯度超过这个阈值,那么就将其强制限制在这个范围之内。这可以防止梯度爆炸。

    另外一种解决梯度爆炸的手段是采用权重正则化(weithts regularization)比较常见的是L1和L2正则。

  3. ReLu、leakReLu等激活函数

    ReLu:其函数的导数在正数部分是恒等于1,这样在深层网络中,在激活函数部分就不存在导致梯度过大或者过小的问题,缓解了梯度消失或者爆炸。同时也方便计算。当然,其也存在存在一些缺点,例如过滤到了负数部分,导致部分信息的丢失,输出的数据分布不在以0为中心,改变了数据分布。

    leakrelu:就是为了解决relu的0区间带来的影响,其数学表达为:leakrelu=max(k*x,0)其中k是leak系数,一般选择0.01或者0.02,或者通过学习而来。

  4. Batch Normalization

    Batch Normalization是深度学习发展以来提出的最重要的成果之一了,目前已经被广泛的应用到了各大网络中,具有加速网络收敛速度,提升训练稳定性的效果,Batch Normalization本质上是解决反向传播过程中的梯度问题。Batch Normalization,简称BN,即批规范化,通过规范化操作将输出信号x规范化到均值为0,方差为1保证网络的稳定性。

    • 有一些从 0 到 1 而不是从 1 到 1000 的特征值,通过归一化所有的输入特征值𝑥,以获得类似范围的值,可以加速学习。所以 Batch 归一化起的作用的原因,直观的一点就是,它在做类似的工作,但不仅仅对于这里的输入值,还有隐藏单元的值。
    • 它可以使权重比你的网络更滞后或更深层,比如,第 10 层的权重更能经受得住变化。
  5. 残差结构

    残差的方式,能使得深层的网络梯度通过跳级连接路径直接返回到浅层部分,使得网络无论多深都能将梯度进行有效的回传。

  6. LSTM

    LSTM全称是长短期记忆网络(long-short term memory networks),是不那么容易发生梯度消失的,主要原因在于LSTM内部复杂的“门”(gates)。在计算时,将过程中的梯度进行了抵消。

6. 随机梯度下降法(SGD)

6.1 mini-batch梯度下降

你可以把训练集分割为小一点的子集训练,这些子集被取名为 mini-batch,假设每一个子集中只有 1000 个样本,那么把其中的𝑥 (1)到𝑥 (1000)取出来,将其称为第一个子训练集,也叫做 mini-batch,然后你再取出接下来的 1000 个样本,从𝑥 (1001)到𝑥 (2000),然后再取 1000个样本,以此类推。

在训练集上运行 mini-batch 梯度下降法,你运行 for t=1……5000,因为我们有5000个各有 1000 个样本的组,在 for 循环里你要做得基本就是对𝑋 {𝑡}和𝑌 {𝑡}执行一步梯度下降法。

  • batch_size=1,就是SGD。
  • batch_size=n,就是mini-batch
  • batch_size=m,就是batch

其中1<n<m,m表示整个训练集大小。

优缺点:

  • batch:相对噪声低些,幅度也大一些,你可以继续找最小值。
  • SGD:大部分时候你向着全局最小值靠近,有时候你会远离最小值,因为那个样本恰好给你指的方向不对,因此随机梯度下降法是有很多噪声的,平均来看,它最终会靠近最小值,不过有时候也会方向错误,因为随机梯度下降法永远不会收敛,而是会一直在最小值附近波动。一次性只处理了一个训练样本,这样效率过于低下。
  • mini-batch:实践中最好选择不大不小的 mini-batch,得到了大量向量化,效率高,收敛快。

首先,如果训练集较小,直接使用 batch 梯度下降法,这里的少是说小于 2000 个样本。一般的 mini-batch 大小为 64 到 512,考虑到电脑内存设置和使用的方式,如果 mini-batch 大小是 2 的𝑛次方,代码会运行地快一些。

6.2 调节 Batch_Size 对训练效果影响到底如何?

  1. Batch_Size 太小,模型表现效果极其糟糕(error飙升)。
  2. 随着 Batch_Size 增大,处理相同数据量的速度越快。
  3. 随着 Batch_Size 增大,达到相同精度所需要的 epoch 数量越来越多。
  4. 由于上述两种因素的矛盾, Batch_Size 增大到某个时候,达到时间上的最优。
  5. 由于最终收敛精度会陷入不同的局部极值,因此 Batch_Size 增大到某些时候,达到最终收敛精度上的最优。

7. 优化算法

7.1 动量法

在每次迭代中,梯度下降根据⾃变量当前位置,沿着当前位置的梯度更新⾃变量。然而,如果⾃变量的 迭代⽅向仅仅取决于⾃变量当前位置,这可能会带来⼀些问题。

让我们考虑⼀个输⼊和输出分别为⼆维向量x = [x1, x2]⊤和标量的⽬标函数 。,这⾥将系数从1减小到了0.1。下⾯实现基于这个⽬标函数的梯度下降,并演⽰使⽤学习率为0.4时⾃变量的迭代轨迹。

可以看到,同⼀位置上,⽬标函数在竖直⽅向(x2轴⽅向)⽐在⽔平⽅向(x1轴⽅向)的斜率的绝对值更⼤。因此,给定学习率,梯度下降迭代⾃变量时会使⾃变量在竖直⽅向⽐在⽔平⽅向移动幅度更⼤。那么,我们需要⼀个较小的学习率从而避免⾃变量在竖直⽅向上越过⽬标函数最优解。然而,这会造成⾃变量在⽔平⽅向上朝最优解移动变慢。

动量法的提出是为了解决梯度下降的上述问题。由于小批量随机梯度下降⽐梯度下降更为⼴义,本章后续讨论将沿⽤“小批量随机梯度下降”⼀节中时间步t的小批量随机梯度gt的定义。设时间步t的⾃变量为xt,学习率为ηt。在时间步0,动量法创建速度变量v0,并将其元素初始化成0。在时间步t > 0,动量法对每次迭代的步骤做如下修改:

其中,动量超参数γ满⾜0 ≤ γ < 1。当γ = 0时,动量法等价于小批量随机梯度下降。在梯度下降时候使用动量法后的迭代轨迹:

可以看到使⽤较小的学习率η = 0.4和动量超参数γ = 0.5时,动量法在竖直⽅向上的移动更加平滑,且在⽔平⽅向上更快逼近最优解。

所以,在动量法中,⾃变量在各个⽅向上的移动幅度不仅取决当前梯度,还取决于过去的各个梯度在各个⽅向上是否⼀致。在本节之前⽰例的优化问题中,所有梯度在⽔平⽅向上为正(向右),而在竖直⽅向上时正(向上)时负(向下)。这样,我们就可以使⽤较⼤的学习率,从而使⾃变量向最优解更快移动。

7.2 AdaGrad算法

优化算法中,⽬标函数⾃变量的每⼀个元素在相同时间步都使⽤同⼀个学习率来⾃我迭代。在“动量法”⾥我们看到当x1和x2的梯度值有较⼤差别时,需要选择⾜够小的学习率使得⾃变量在梯度值较⼤的维度上不发散。但这样会导致⾃变量在梯度值较小的维度上迭代过慢。动量法依赖指数加权移动平均使得⾃变量的更新⽅向更加⼀致,从而降低发散的可能。本节我们介绍AdaGrad算法,它根据⾃变量在每个维度的梯度值的⼤小来调整各个维度上的学习率,从而避免统⼀的学习率难以适应所有维度的问题。

AdaGrad算法会使⽤⼀个小批量随机梯度gt按元素平⽅的累加变量st。在时间步0,AdaGrad将s0中每个元素初始化为0。在时间步t,⾸先将小批量随机梯度gt按元素平⽅后累加到变量st:

其中⊙是按元素相乘。接着,我们将⽬标函数⾃变量中每个元素的学习率通过按元素运算重新调整⼀下:

其中η是学习率,ϵ是为了维持数值稳定性而添加的常数,如10的-6次方。这⾥开⽅、除法和乘法的运算都是按元素运算的。这些按元素运算使得⽬标函数⾃变量中每个元素都分别拥有⾃⼰的学习率。

需要强调的是,小批量随机梯度按元素平⽅的累加变量st出现在学习率的分⺟项中。因此,

  • 如果⽬标函数有关⾃变量中某个元素的偏导数⼀直都较⼤,那么该元素的学习率将下降较快;
  • 反之,如果⽬标函数有关⾃变量中某个元素的偏导数⼀直都较小,那么该元素的学习率将下降较慢。

然而,由于st⼀直在累加按元素平⽅的梯度,⾃变量中每个元素的学习率在迭代过程中⼀直在降低(或不变)。所以,当学习率在迭代早期降得较快且当前解依然不佳时,AdaGrad算法在迭代后期由于学习率过小,可能较难找到⼀个有⽤的解。

7.3 RMSProp算法

当学习率在迭代早期降得较快且当前解依然不佳时,AdaGrad算法在迭代后期由于学习率过小,可能较难找到⼀个有⽤的解。为了解决这⼀问题,RMSProp算法对AdaGrad算法做了⼀点小小的修改。

不同于AdaGrad算法⾥状态变量st是截⾄时间步t所有小批量随机梯度gt按元素平⽅和,RMSProp算法将这些梯度按元素平⽅做指数加权移动平均。具体来说,给定超参数0 ≤ γ < 1,RMSProp算法在时间步t > 0计算:

和AdaGrad算法⼀样,RMSProp算法将⽬标函数⾃变量中每个元素的学习率通过按元素运算重新调整,然后更新⾃变量:

其中η是学习率,ϵ是为了维持数值稳定性而添加的常数,如10的-6次方。因为RMSProp算法的状态变量st是对平⽅项gt ⊙ gt的指数加权移动平均,所以可以看作是最近1/(1 − γ)个时间步的小批量随机梯度平⽅项的加权平均。如此⼀来,⾃变量每个元素的学习率在迭代过程中就不再⼀直降低(或不变)。

7.4 AdaDelta算法

除了RMSProp算法以外,另⼀个常⽤优化算法AdaDelta算法也针对AdaGrad算法在迭代后期可能较难找到有⽤解的问题做了改进。有意思的是,AdaDelta算法没有学习率这⼀超参数。

AdaDelta算法也像RMSProp算法⼀样,使⽤了小批量随机梯度gt按元素平⽅的指数加权移动平均变量st。在时间步0,它的所有元素被初始化为0。给定超参数0 ≤ ρ < 1(对应RMSProp算法中的γ),在时间步t > 0,同RMSProp算法⼀样计算:

与RMSProp算法不同的是,AdaDelta算法还维护⼀个额外的状态变量∆xt,其元素同样在时间步0时被初始化为0。我们使⽤∆xt−1来计算⾃变量的变化量:

最后,我们使⽤∆xt来记录⾃变量变化量 按元素平⽅的指数加权移动平均:

可以看到,如不考虑ϵ的影响,AdaDelta算法与RMSProp算法的不同之处在于使⽤ 来替代超参数η。

7.5 Adam算法

Adam算法在RMSProp算法基础上对小批量随机梯度也做了指数加权移动平均。

Adam算法使⽤了动量变量vt和RMSProp算法中小批量随机梯度按元素平⽅的指数加权移动平均变量st,并在时间步0将它们中每个元素初始化为0。给定超参数0 ≤ β1 < 1(算法作者建议设为0.9),时间步t的动量变量vt即小批量随机梯度gt的指数加权移动平均:

![](https://latex.codecogs.com/gif.latex?v_t=eta_1v_{t-1}+(1-eta_1)g_t)

和RMSProp算法中⼀样,给定超参数0 ≤ β2 < 1(算法作者建议设为0.999),将小批量随机梯度按元素平⽅后的项gt ⊙ gt做指数加权移动平均得到st:

由于我们将 v0 和 s0 中的元素都初始化为 0,在时间步 t 我们得到 ![](https://latex.codecogs.com/gif.latex?v_t=(1-eta_1)sum_{i=1}^teta_1^{t-i}g_i)。将过去各时间步小批量随机梯度的权值相加,得到 ![](https://latex.codecogs.com/gif.latex?(1-eta_1)sum_{i=1}^teta_1^{t-i}=1-eta_1^t)。需要注意的是,当 t 较小时,过去各时间步小批量随机梯度权值之和会较小。例如,当β1 = 0.9时,v1 = 0.1g1。为了消除这样的影响,对于任意时间步 t,我们可以将 vt 再除以 ![](https://latex.codecogs.com/gif.latex?1-eta_1^t),从而使过去各时间步小批量随机梯度权值之和为1。这也叫作偏差修正。在Adam算法中,我们对变量 vt 和 st 均作偏差修正:

![](https://latex.codecogs.com/gif.latex?check{v}_t=frac{v_t}{1-eta_1^t})

![](https://latex.codecogs.com/gif.latex?check{s}_t=frac{s_t}{1-eta_2^t})

接下来,Adam算法使⽤以上偏差修正后的变量vˆtsˆt,将模型参数中每个元素的学习率通过按元素运算重新调整:

其中η是学习率,ϵ是为了维持数值稳定性而添加的常数,如10的-8次方。和AdaGrad算法、RMSProp算法以及AdaDelta算法⼀样,⽬标函数⾃变量中每个元素都分别拥有⾃⼰的学习率。最后,使⽤迭代⾃变量:

7.6 局部最优--鞍点问题

一个具有高维度空间的函数,如果梯度为 0,那么在每个方向,它可能是凸函数,也可能是凹函数。如果你在 2 万维空间中,那么想要得到局部最优,所有的 2 万个方向都需要是这样,但发生的机率也许很小,也许是2的-20000次方,你更有可能遇到有些方向的曲线会这样向上弯曲,另一些方向曲线向下弯,而不是所有的都向上弯曲,因此在高维度空间,你更可能碰到鞍点。

而不会碰到局部最优。至于为什么会把一个曲面叫做鞍点,你想象一下,就像是放在马背上的马鞍一样,如果这是马,这是马的头,这就是马的眼睛,画得不好请多包涵,然后你就是骑马的人,要坐在马鞍上,因此这里的这个点,导数为 0 的点,这个点叫做鞍点。我想那确实是你坐在马鞍上的那个点,而这里导数为 0。

鞍点中的平稳段是一个问题,这样使得学习十分缓慢,这也是像 Momentum 或是RMSprop,Adam 这样的算法,能够加速学习算法的地方。在这些情况下,更成熟的优化算法,如 Adam 算法,能够加快速度,让你尽早往下走出平稳段。

8. 如何解决训练样本少的问题

  1. 利用预训练模型进行迁移微调(fine-tuning),预训练模型通常在特征上拥有很好的语义表达。此时,只需将模型在小数据集上进行微调就能取得不错的效果。CV有ImageNet,NLP有BERT等。
  2. 数据集进行下采样操作,使得符合数据同分布。
  3. 数据集增强、正则或者半监督学习等方式来解决小样本数据集的训练问题。

9. 如何提升模型的稳定性?

  1. 正则化(L2, L1, dropout):模型方差大,很可能来自于过拟合。正则化能有效的降低模型的复杂度,增加对更多分布的适应性。
  2. 前停止训练:提前停止是指模型在验证集上取得不错的性能时停止训练。这种方式本质和正则化是一个道理,能减少方差的同时增加的偏差。目的为了平衡训练集和未知数据之间在模型的表现差异。
  3. 扩充训练集:正则化通过控制模型复杂度,来增加更多样本的适应性。
  4. 特征选择:过高的特征维度会使模型过拟合,减少特征维度和正则一样可能会处理好方差问题,但是同时会增大偏差。

10. 有哪些改善模型的思路

  1. **数据角度 **

    增强数据集。无论是有监督还是无监督学习,数据永远是最重要的驱动力。更多的类型数据对良好的模型能带来更好的稳定性和对未知数据的可预见性。对模型来说,“看到过的总比没看到的更具有判别的信心”。

  2. 模型角度

    模型的容限能力决定着模型可优化的空间。在数据量充足的前提下,对同类型的模型,增大模型规模来提升容限无疑是最直接和有效的手段。

  3. 调参优化角度

    如果你知道模型的性能为什么不再提高了,那已经向提升性能跨出了一大步。 超参数调整本身是一个比较大的问题。一般可以包含模型初始化的配置,优化算法的选取、学习率的策略以及如何配置正则和损失函数等等。

  4. 训练角度

    在越大规模的数据集或者模型上,诚然一个好的优化算法总能加速收敛。但你在未探索到模型的上限之前,永远不知道训练多久算训练完成。所以在改善模型上充分训练永远是最必要的过程。充分训练的含义不仅仅只是增大训练轮数。有效的学习率衰减和正则同样是充分训练中非常必要的手段。

11. 如何提高深度学习系统的性能

  1. 提高模型的结构。
  2. 改进模型的初始化方式,保证早期梯度具有某些有益的性质,或者具备大量的稀疏性,或者利用线性代数原理的优势。
  3. 择更强大的学习算法。

12. 参考文献


作者:@mantchs

GitHub:https://github.com/NLP-LOVE/ML-NLP

欢迎大家加入讨论!共同完善此项目!群号:【541954936】NLP面试学习群

LSTM 历史版本:
上次修改时间: 2022-02-09 10:56:29

目录

1. 什么是LSTM

在你阅读这篇文章时候,你都是基于自己已经拥有的对先前所见词的理解来推断当前词的真实含义。我们不会将所有的东西都全部丢弃,然后用空白的大脑进行思考。我们的思想拥有持久性。LSTM就是具备了这一特性。

这篇将介绍另⼀种常⽤的⻔控循环神经⽹络:⻓短期记忆(long short-term memory,LSTM)[1]。它⽐⻔控循环单元的结构稍微复杂⼀点,也是为了解决在RNN网络中梯度衰减的问题,是GRU的一种扩展。

可以先理解GRU的过程,在来理解LSTM会容易许多,链接地址:三步理解--门控循环单元(GRU)

LSTM 中引⼊了3个⻔,即输⼊⻔(input gate)、遗忘⻔(forget gate)和输出⻔(output gate),以及与隐藏状态形状相同的记忆细胞(某些⽂献把记忆细胞当成⼀种特殊的隐藏状态),从而记录额外的信息。

2. 输⼊⻔、遗忘⻔和输出⻔

与⻔控循环单元中的重置⻔和更新⻔⼀样,⻓短期记忆的⻔的输⼊均为当前时间步输⼊Xt与上⼀时间步隐藏状态Ht−1,输出由激活函数为sigmoid函数的全连接层计算得到。如此⼀来,这3个⻔元素的值域均为[0, 1]。如下图所示:

具体来说,假设隐藏单元个数为 h,给定时间步 t 的小批量输⼊ (样本数为n,输⼊个数为d)和上⼀时间步隐藏状态 。三个门的公式如下:

输入门:

遗忘问:

输出门:

3. 候选记忆细胞

接下来,⻓短期记忆需要计算候选记忆细胞 ![](https://latex.codecogs.com/gif.latex? ilde{C}_t)。它的计算与上⾯介绍的3个⻔类似,但使⽤了值域在[−1, 1]的tanh函数作为激活函数,如下图所示:

具体来说,时间步t的候选记忆细胞计算如下:

![](https://latex.codecogs.com/gif.latex? ilde{C}_t=tanh(X_tWxc+H_{t-1}W_{hc}+b_c))

4. 记忆细胞

我们可以通过元素值域在[0, 1]的输⼊⻔、遗忘⻔和输出⻔来控制隐藏状态中信息的流动,这⼀般也是通过使⽤按元素乘法(符号为⊙)来实现的。当前时间步记忆细胞的计算组合了上⼀时间步记忆细胞和当前时间步候选记忆细胞的信息,并通过遗忘⻔和输⼊⻔来控制信息的流动:

![](https://latex.codecogs.com/gif.latex?C_t=F_t⊙C_{t-1}+I_t⊙ ilde{C}_t)

如下图所⽰,遗忘⻔控制上⼀时间步的记忆细胞Ct−1中的信息是否传递到当前时间步,而输⼊⻔则控制当前时间步的输⼊Xt通过候选记忆细胞C˜t如何流⼊当前时间步的记忆细胞。如果遗忘⻔⼀直近似1且输⼊⻔⼀直近似0,过去的记忆细胞将⼀直通过时间保存并传递⾄当前时间步。这个设计可以应对循环神经⽹络中的梯度衰减问题,并更好地捕捉时间序列中时间步距离较⼤的依赖关系。

5. 隐藏状态

有了记忆细胞以后,接下来我们还可以通过输出⻔来控制从记忆细胞到隐藏状态Ht的信 息的流动:

这⾥的tanh函数确保隐藏状态元素值在-1到1之间。需要注意的是,当输出⻔近似1时,记忆细胞信息将传递到隐藏状态供输出层使⽤;当输出⻔近似0时,记忆细胞信息只⾃⼰保留。下图展⽰了⻓短期记忆中隐藏状态的全部计算:

6. LSTM与GRU的区别

LSTM与GRU二者结构十分相似,不同在于

  1. 新的记忆都是根据之前状态及输入进行计算,但是GRU中有一个重置门控制之前状态的进入量,而在LSTM里没有类似门;
  2. 产生新的状态方式不同,LSTM有两个不同的门,分别是遗忘门(forget gate)和输入门(input gate),而GRU只有一种更新门(update gate);
  3. LSTM对新产生的状态可以通过输出门(output gate)进行调节,而GRU对输出无任何调节。
  4. GRU的优点是这是个更加简单的模型,所以更容易创建一个更大的网络,而且它只有两个门,在计算性上也运行得更快,然后它可以扩大模型的规模。
  5. LSTM更加强大和灵活,因为它有三个门而不是两个。

7. LSTM可以使用别的激活函数吗?

关于激活函数的选取,在LSTM中,遗忘门、输入门和输出门使用Sigmoid函数作为激活函数;在生成候选记忆时,使用双曲正切函数Tanh作为激活函数。

值得注意的是,这两个激活函数都是饱和的,也就是说在输入达到一定值的情况下,输出就不会发生明显变化了。如果是用非饱和的激活函数,例如ReLU,那么将难以实现门控的效果。

Sigmoid函数的输出在0~1之间,符合门控的物理定义。且当输入较大或较小时,其输出会非常接近1或0,从而保证该门开或关。在生成候选记忆时,使用Tanh函数,是因为其输出在−1~1之间,这与大多数场景下特征分布是0中心的吻合。此外,Tanh函数在输入为0附近相比Sigmoid函数有更大的梯度,通常使模型收敛更快。

激活函数的选择也不是一成不变的,但要选择合理的激活函数。

8. 代码实现

MIST数据分类--TensorFlow实现LSTM

9. 参考文献

《动手学--深度学习》


作者:@mantchs

GitHub:https://github.com/NLP-LOVE/ML-NLP

欢迎大家加入讨论!共同完善此项目!群号:【541954936】NLP面试学习群

GRU 历史版本:
上次修改时间: 2022-02-09 10:57:27

目录

1. 什么是GRU

在循环神经⽹络中的梯度计算⽅法中,我们发现,当时间步数较⼤或者时间步较小时,循环神经⽹络的梯度较容易出现衰减或爆炸。虽然裁剪梯度可以应对梯度爆炸,但⽆法解决梯度衰减的问题。通常由于这个原因,循环神经⽹络在实际中较难捕捉时间序列中时间步距离较⼤的依赖关系。

门控循环神经⽹络(gated recurrent neural network)的提出,正是为了更好地捕捉时间序列中时间步距离较⼤的依赖关系。它通过可以学习的⻔来控制信息的流动。其中,门控循环单元(gatedrecurrent unit,GRU)是⼀种常⽤的门控循环神经⽹络。

2. ⻔控循环单元

2.1 重置门和更新门

GRU它引⼊了重置⻔(reset gate)和更新⻔(update gate)的概念,从而修改了循环神经⽹络中隐藏状态的计算⽅式。

门控循环单元中的重置⻔和更新⻔的输⼊均为当前时间步输⼊ 与上⼀时间步隐藏状态,输出由激活函数为sigmoid函数的全连接层计算得到。 如下图所示:

具体来说,假设隐藏单元个数为 h,给定时间步 t 的小批量输⼊ (样本数为n,输⼊个数为d)和上⼀时间步隐藏状态 。重置⻔ 和更新⻔ 的计算如下:

sigmoid函数可以将元素的值变换到0和1之间。因此,重置⻔ 和更新⻔ 中每个元素的值域都是[0*,* 1]。

2.2 候选隐藏状态

接下来,⻔控循环单元将计算候选隐藏状态来辅助稍后的隐藏状态计算。我们将当前时间步重置⻔的输出与上⼀时间步隐藏状态做按元素乘法(符号为)。如果重置⻔中元素值接近0,那么意味着重置对应隐藏状态元素为0,即丢弃上⼀时间步的隐藏状态。如果元素值接近1,那么表⽰保留上⼀时间步的隐藏状态。然后,将按元素乘法的结果与当前时间步的输⼊连结,再通过含激活函数tanh的全连接层计算出候选隐藏状态,其所有元素的值域为[-1,1]。

具体来说,时间步 t 的候选隐藏状态 ![](https://latex.codecogs.com/gif.latex? ilde{H}in_{}mathbb{R}^{n*h})的计算为:

![](https://latex.codecogs.com/gif.latex? ilde{H}t=tanh(X_tW_{xh}+(R_t⊙H_{t-1})W{hh}+b_h))

从上⾯这个公式可以看出,重置⻔控制了上⼀时间步的隐藏状态如何流⼊当前时间步的候选隐藏状态。而上⼀时间步的隐藏状态可能包含了时间序列截⾄上⼀时间步的全部历史信息。因此,重置⻔可以⽤来丢弃与预测⽆关的历史信息。

2.3 隐藏状态

最后,时间步t的隐藏状态 的计算使⽤当前时间步的更新⻔ 来对上⼀时间步的隐藏状态 和当前时间步的候选隐藏状态 ![](https://latex.codecogs.com/gif.latex? ilde{H}_t)做组合:

值得注意的是,更新⻔可以控制隐藏状态应该如何被包含当前时间步信息的候选隐藏状态所更新,如上图所⽰。假设更新⻔在时间步之间⼀直近似1。那么,在时间步间的输⼊信息⼏乎没有流⼊时间步 t 的隐藏状态 实际上,这可以看作是较早时刻的隐藏状态 直通过时间保存并传递⾄当前时间步 t。这个设计可以应对循环神经⽹络中的梯度衰减问题,并更好地捕捉时间序列中时间步距离较⼤的依赖关系。

我们对⻔控循环单元的设计稍作总结:

  • 重置⻔有助于捕捉时间序列⾥短期的依赖关系;
  • 更新⻔有助于捕捉时间序列⾥⻓期的依赖关系。

3. 代码实现GRU

MNIST--GRU实现

4. 参考文献

《动手学--深度学习》


作者:@mantchs

GitHub:https://github.com/NLP-LOVE/ML-NLP

欢迎大家加入讨论!共同完善此项目!群号:【541954936】NLP面试学习群

常见框架导出的模型格式,概念解析 历史版本:
上次修改时间: 2022-05-14 18:37:23
Format export.py --include Model
PyTorch - pt
TorchScript torchscript *.torchscript
ONNX onnx *.onnx
OpenVINO openvino *.yolov5s_openvino_model
TensorRT engine *.engine
CoreML coreml *.mlmodel
TensorFlow SavedModel saved_model *
TensorFlow GraphDef pb *.pb
TensorFlow Lite tflite *.tflite
TensorFlow Edge TPU edgetpu *.tflite
TensorFlow.js tfjs *

常见的模型评价参数,以yolo为例子

  • size (pixels)
  • mAPval 0.5:0.95
  • mAPval 0.5
  • Speed CPU b1 (ms)
  • Speed V100 b1(ms)
  • Speed V100 b32(ms)
  • params (M)
  • FLOPs@640 (B)

mAP含义

关于Ground Truth:ground truth包括图像中物体的类别以及该图像中每个物体的真实边界框。
mAP含义及计算:如何量化呢? 采用IoU(Intersection over Union),IoU是预测框与ground truth的交集和并集的比值。这个量也被称为Jaccard指数,并于20世纪初由Paul Jaccard首次提出。
image.png

TP TN FP FN是什么意思?

T或者N代表的是该样本是否被分类分对,P或者N代表的是该样本被分为什么

TP(True Positives)意思我们倒着来翻译就是“被分为正样本,并且分对了”,TN(True Negatives)意思是“被分为负样本,而且分对了”,FP(False Positives)意思是“被分为正样本,但是分错了”,FN(False Negatives)意思是“被分为负样本,但是分错了”。

按下图来解释,左半矩形是正样本,右半矩形是负样本。一个2分类器,在图上画了个圆,分类器认为圆内是正样本,圆外是负样本。那么左半圆分类器认为是正样本,同时它确实是正样本,那么就是“被分为正样本,并且分对了”即TP,左半矩形扣除左半圆的部分就是分类器认为它是负样本,但是它本身却是正样本,就是“被分为负样本,但是分错了”即FN。右半圆分类器认为它是正样本,但是本身却是负样本,那么就是“被分为正样本,但是分错了”即FP。右半矩形扣除右半圆的部分就是分类器认为它是负样本,同时它本身确实是负样本,那么就是“被分为负样本,而且分对了”即TN
image.png
有了上面TP TN FP FN的概念,这个Precision和Recall的概念一张图就能说明。
image.png

mAP定义及相关概念

  • mAP: mean Average Precision, 即各类别AP的平均值
  • AP: PR曲线下面积,后文会详细讲解
  • PR曲线: Precision-Recall曲线
  • Precision: TP / (TP + FP)
  • Recall: TP / (TP + FN)
  • TP: IoU>0.5的检测框数量(同一Ground Truth只计算一次)
  • FP: IoU<=0.5的检测框,或者是检测到同一个GT的多余检测框的数量
  • FN: 没有检测到的GT的数量,IoU=0
mAP如何计算?

由前面定义,我们可以知道,要计算mAP必须先绘出各类别PR曲线,计算出AP。而如何采样PR曲线,VOC采用过两种不同方法。参见:The PASCAL Visual Object Classes Challenge 2012 (VOC2012) Development Kit
在VOC2010以前,只需要选取当Recall >= 0, 0.1, 0.2, ..., 1共11个点时的Precision最大值,然后AP就是这11个Precision的平均值。
在VOC2010及以后,需要针对每一个不同的Recall值(包括0和1),选取其大于等于这些Recall值时的Precision最大值,然后计算PR曲线下面积作为AP值。

mAP计算示例

假设,对于Aeroplane类别,我们网络有以下输出(BB表示BoundingBox序号,IoU>0.5时GT=1):
``` BB | confidence | GT

BB1 | 0.9 | 1

BB2 | 0.9 | 1

BB1 | 0.8 | 1

BB3 | 0.7 | 0

BB4 | 0.7 | 0

BB5 | 0.7 | 1

BB6 | 0.7 | 0

BB7 | 0.7 | 0

BB8 | 0.7 | 1

BB9 | 0.7 | 1

因此,我们有 TP=5 (BB1, BB2, BB5, BB8, BB9), FP=5 (重复检测到的BB1也算FP)。除了表里检测到的5个GT以外,我们还有2个GT没被检测到,因此: FN = 2. 这时我们就可以按照Confidence的顺序给出各处的PR值,如下:

rank=1 precision=1.00 and recall=0.14

rank=2 precision=1.00 and recall=0.29

rank=3 precision=0.66 and recall=0.29

rank=4 precision=0.50 and recall=0.29

rank=5 precision=0.40 and recall=0.29

rank=6 precision=0.50 and recall=0.43

rank=7 precision=0.43 and recall=0.43

rank=8 precision=0.38 and recall=0.43

rank=9 precision=0.44 and recall=0.57

rank=10 precision=0.50 and recall=0.71











8种主流深度学习框架介绍 历史版本:
上次修改时间: 2023-07-03 13:49:01

TensorFlow

TensorFlow是目前深度学习的主流框架,其主要特性如下所述:

  1. TensorFlow支持Python、JavaScript、C ++、Java、Go、C#、Julia和R等多种编程语言。
  2. TensorFlow不仅拥有强大的计算集群,还可以在iOS和Android等移动平台上运行模型。TensorFlow编程入门难度较大。初学者需要仔细考虑神经网络的架构,正确评估输入和输出数据的维度和数量。
  3. TensorFlow使用静态计算图进行操作。也就是说,我们需要先定义图形,然后运行计算,如果我们需要对架构进行更改,则需要重新训练模型。选择这样的方法是为了提高效率,但是许多现代神经网络工具已经能够在学习过程中改进,并且不会显著降低学习速度。在这方面,TensorFlow的主要竞争对手是PyTorch

Keras

Keras是一个对小白用户非常友好且简单的深度学习框架。如果想快速入门深度学习, Keras将是不错的选择。
Keras是TensorFlow高级集成API,可以非常方便地和TensorFlow进行融合。
Keras在高层可以调用TensorFlow、CNTK、Theano,还有更多优秀的库也在被陆续支持中。
Keras的特点是能够快速搭建模型,是高效地进行科学研究的关键。Keras的基本特性如下:

  • 高度模块化,搭建网络非常简洁;
  • API简单,具有统一的风格;
  • 易扩展,易于添加新模块,只需要仿照现有模块编写新的类或函数即可。R

Studio提供了R与Keras的API接口,RStudio的官网及GitHub上也提供了Keras扩展包的学习资料。

Caffe

Caffe是由AI科学家贾扬清在加州大学伯克利分校读博期间主导开发的,是以C++/CUDA代码为主的早期深度学习框架之一,比TensorFlow、MXNet、PyTorch等都要早。
Caffe需要进行编译安装,支持命令行、Python和Matlab接口,单机多卡、多机多卡等都可以很方便使用。
Caffe的基本特性如下:

  • 以C++/CUDA/Python代码为主,速度快,性能高。
  • 工厂设计模式,代码结构清晰,可读性和可拓展性强。
  • 支持命令行、Python和Matlab接口,使用方便。CPU和GPU之间切换方便,多GPU训练方便。工具丰富,社区活跃。

同时,Caffe的缺点也比较明显,主要包括如下几点。

  • 源代码修改门槛较高,需要实现正向/反向传播。
  • 不支持自动求导。
  • 不支持模型级并行,只支持数据级并行。
  • 不适合非图像任务。

PyTorch

PyTroch主要提供以下两种核心功能:支持GPU加速的张量计算;方便优化模型的自动微分机制。PyTorch的主要优点如下:

  • 简洁易懂:PyTorch的API设计相当简洁一致,基本上是tensor、autograd、nn三级封装,学习起来非常容易。
  • 便于调试:PyTorch采用动态图,可以像普通Python代码一样进行调试。不同于TensorFlow,PyTorch的报错说明通常很容易看懂。强大高效:PyTorch提供了非常丰富的模型组件,可以快速实现想法。

Theano

CNTK

CNTK(Microsoft Cognitive Toolkit)是微软开源的深度学习工具包,它通过有向图将神经网络描述为一系列计算步骤。在有向图中,叶节点表示输入值或网络参数,其他节点表示其输入上的矩阵运算。
CNTK允许用户非常轻松地实现和组合流行的模型,包括前馈神经网络(DNN)、卷积神经网络(CNN)和循环神经网络(RNN、LSTM)。与目前大部分框架一样,CNTK实现了自动求导,利用随机梯度下降方法进行优化。
CNTK的基本特性如下。CNTK性能较好,按照其官方的说法,它比其他的开源框架性能都要好。适合做语音任务,CNTK本就是微软语音团队开源的,自然更适合做语音任务,便于在使用RNN等模型以及时空尺度时进行卷积。

MXNet

MXNet框架允许混合符号和命令式编程,以最大限度地提高效率和生产力。MXNet的核心是一个动态依赖调度程序,可以动态地自动并行化符号和命令操作。
其图形优化层使符号执行更快,内存效率更高。
MXNet的基本特性如下:

  • 灵活的编程模型:支持命令式和符号式编程模型。多语言支持:支持C++、Python、R、Julia、JavaScript、Scala、Go、Perl等。事实上,它是唯一支持所有R函数的构架。
  • 本地分布式训练:支持在多CPU/GPU设备上的分布式训练,使其可充分利用云计算的规模优势。性
  • 能优化:使用一个优化的C++后端引擎实现并行I/O和计算,无论使用哪种语言都能达到最佳性能。云端友好:可直接与S3、HDFS和Azure兼容。

PaddlePaddle

Deeplearning4j

ONNX

0条评�?
全部评论

关于博主

an actually real engineer

通信工程专业毕业,7年开发经验

技术栈:

精通c/c++

精通golang

熟悉常见的脚本,js,lua,python,php

熟悉电路基础,嵌入式,单片机

耕耘领域:

服务端开发

嵌入式开发

git

>

gin接口代码CURD生成工具

sql ddl to struct and markdown,将sql表自动化生成代码内对应的结构体和markdown表格格式,节省宝贵的时间。

输入ddl:
输出代码:

qt .ui文件转css文件

duilib xml 自动生成绑定控件代码

协议调试器

基于lua虚拟机的的协议调试器软件 支持的协议有:

串口

tcp客户端/服务端

udp 组播/udp节点

tcp websocket 客户端/服务端

软件界面

使用例子: 通过脚本来获得接收到的数据并写入文件和展示在界面上

下载地址和源码

duilib版本源码 qt qml版本源码 二进制包

webrtc easy demo

webrtc c++ native 库 demo 实现功能:

基于QT

webrtc摄像头/桌面捕获功能

opengl渲染/多播放窗格管理

janus meeting room

下载地址和源码

源码 二进制包

wifi,蓝牙 - 无线开关

实现功能:

通过wifi/蓝牙实现远程开关电器或者其他电子设备

电路原理图:

实物图:

深度学习验证工具

vtk+pcl 点云编辑工具

实现功能:

1. 点云文件加载显示(.pcd obj stl)

2. 点云重建

3. 点云三角化

4. 点云缩放

下载地址:

源码 二进制包

虚拟示波器

硬件实物图:

实现原理

基本性能

采集频率: 取决于外部adc模块和ebaz4205矿板的以太网接口速率,最高可以达到100M/8 约为12.5MPS

上位机实现功能: 采集,显示波形,存储wave文件。

参数可运行时配置

上位机:

显示缓冲区大小可调

刷新率可调节

触发显示刷新可调节

进程守护工具

基本功能:

1. 守护进程,被守护程序崩溃后自动重启。

2. 进程输出获取,显示在编辑框中。

二进制包

openblt 烧录工具

基本功能:

1. 加载openblt 文件,下载到具有openblt bootloader 运行的单片机中。

二进制包

opencv 功能验证工具(开源项目二次开发)

基本功能:

1. 插件化图像处理流程,支持自定义图像处理流程。 2. 完善的日志和权限管理

二进制包

又一个modbus调试工具

最近混迹物联网企业,发现目前缺少一个简易可用的modbus调试工具,本软件旨在为开发者提供一个简单modbus测试工具。
主打一个代码简单易修改。
特点:

1. 基于QT5

2. 基于libmodbus

3. 三方库完全跨平台,linux/windows。

二进制包

屏幕录制工具

1. 基于QT5

2. 基于ffmpeg

3. 支持自定义录屏

源代码

开源plutosdr 板卡

1. 完全开源

2. 提高固件定制服务

3. 硬件售价450 手焊产量有线

测试数据

内部DDS回环测试

接收测试

外部发送500MHZ FM波形

硬件原理图

matlab测试

2TRX版本

大部分plutosdr应用场景都是讲plutosdr板卡作为射频收发器来使用。
实际上plutosdr板卡本身运行linux 操作系统。是具有一定脱机运算的能力。 对于一些微型频谱检测,简单射频信号收发等应用完全可以将应用层直接实现在板卡上
相较于通过网卡或者USB口传输具有更稳定,带宽更高等优点。
本开源板卡由于了SD卡启动,较原版pluto支持了自定义启动应用的功能。
提供了应用层开发SDK(编译器,buildroot文件系统)。
通过usb连接电脑,经过RNDIS驱动可以近似为通过网卡连接
(支持固件的开发定制)。

二次开发例子

``` all:
arm-linux-gnueabihf-gcc -mfloat-abi=hard --sysroot=/root/v0.32_2trx/buildroot/output/staging -std=gnu99 -g -o pluto_stream ad9361-iiostream.c -lpthread -liio -lm -Wall -Wextra -lrt
clean:
rm pluto_stream

bsdiff算法补丁生成器

1. 官方bsdiff算法例子自带bzip压缩方式

2. 本例子没有压缩,直接生成补丁文件

3. 图形化界面基于DUILIB

二进制文件

版面分析即分析出图片内的具体文件元素,如文档标题,文档内容,文档页码等,本工具基于cnstd模型

Base64 Image

. 闽ICP备19002644号