量化机器学习系列分享(七)深度学习模型
由bq2qbou2创建,最终由bq2qbou2 被浏览 109 用户
1. 前馈神经网络(DNN)
一般来说,深度学习和神经网络是同一个概念
1.1 感知机(Perceptron)
在之前的分享中,我们介绍过一个线性分类器,叫做感知机(Perceptron),并且介绍过它是神经网络的基本单元
感知机的运算公式是:
- 假设我们有F个特征,每个特征一个参数,特征X这个时候也可以叫做输入
- 我们先给特征和参数来一个线性组合:Z = theta0 + theta1 X1 + theta2 X2 + …… + thetaF XF
- 之后把线性组合套在一个激活函数中,Y = f(Z),最终的结果Y我们叫做输出,输出其实并不局限于二分类,多分类和回归也是支持的
1.2 前馈神经网络(Deep Neural Network / Feedforward Neural Network)
前馈神经网络,就是多个感知机拼接在一起,这个拼接,不仅要扩展广度,而且要扩展深度(层数)
- 广度的扩展,可以理解为下图中,从上到下有多个感知机
- 深度的扩展,可以理解为下图中,从左往右有多层感知机
- 最左边的层叫做输入层,为原始数据
- 最右边的层叫做输出层,为预测结果
- 中间的所有层都叫做隐藏层,作用是数据的加工处理
前馈神经网络的强大之处在于,这个结构的模型,可以估计任意一种连续型函数
前馈神经网络中两个相邻层的节点是全连接的(图中的圆圈就是节点)
- 例如上图中,输入层有784个节点,隐藏层1有128个节点,那么这两层之间就一共有784 X 128 = 100352个连接
- 每个连接线其实都代表着一个参数,参数表示该连接的权重,例如上图中,输入层与隐藏层1之间,就有100352个参数
- 当然,每一层还可以加入一个常数项,如果输入层有常数项,就相当于785个节点,但是常数节点只连后层不连前层
1.2.1 前馈神经网络的前向计算
前向计算指的是,神经网络由输入到输出的计算过程
以下是一个简单的前馈神经网络的结构,它的任务是多标签分类:
- 输入层:3特征+1常数项
- 隐藏层1:3节点+1常数项
- 隐藏层2:2节点+1常数项
- 输出层:3节点
除输入层外,每一个节点都是前一层所有节点的线性组合+激活函数,同一层的激活函数是一致的,常用的激活函数包括:
隐藏层:
- Sigmoid函数:
- tanh函数:
- ReLU函数
输出层:
- 二分类问题:Sigmoid函数:
- 多分类问题:Softmax函数:
- 回归问题:Linear函数:
1.2.2 前馈神经网络的后向传播
神经网络的训练,本质上和其他类型的机器学习模型是一致的:
- 模型的预测值和样本真实值之间的偏差,就叫做损失loss,它是由损失函数决定的
- 损失值的出现原因就是模型中的参数值不合适
- 因此损失值会指导模型中参数的更新
例如在上图中的神经网络模型,共有29个参数,损失值会指导所有29个参数的更新
- 输入层到隐藏层1:(3+1) X 3 = 12
- 隐藏层1到隐藏层2:(3+1) X 2 = 8
- 隐藏层2到输出层:(2+1) X 3 = 9
那么具体每个参数更新多少呢,其实也是损失函数相对于每个参数求导算出来的
- 由于神经网络的计算是一层一层递进的
- 所以损失函数对于每一个参数求导,就要用到我们高数中学的求导链式法则
例如下面这个简单的神经网络中,任务是回归,使用的损失函数是Squared Loss
- 输入层到隐藏层的参数我们用u表示,如果没有常数项,共有m X p个参数
- 隐藏层到输出层的参数我们用w表示,如果没有常数项,共有p X 1个参数
当然,求导还并不是对于每个参数的具体更新值,最终的更新值是导数乘以学习率
当然我们还可以使用之前介绍过的高阶优化方法:
- 动量方法(Momentum)
- 自适应梯度方法(AdaGrad)
- 自适应矩估计算法(Adam)
1.3 前馈神经网络中防止过拟合
神经网络是非常容易过拟合的模型,因为参数量大,模型复杂度就大,因此容易过拟合
在前馈神经网络中,防止过拟合,可以使用我们之前提到过的正则化:
- L1正则化:对神经网络中所有参数的绝对值进行惩罚
- L2正则化:对神经网络中所有参数的平方进行惩罚
当然,神经网络还有专属的防止过拟合的方法:随机丢弃(dropout)
- 在神经网络的隐藏层中,每一轮训练中,都会有随机的一批节点不参与训练
- 既不参与前向计算,也不参与后向传播
- 每轮训练中,被丢弃的节点是不同的
- 随机丢弃多少节点,是一个可以设置调整的超参数
1.4 前馈神经网络的问题
前馈神经网络的一个缺点是,模型结构不能根据输入特证数而灵活的调整
- 当我们的输入特征有10个的时候,输入层就有10个节点
- 当输入特征变成20个以后,输入层就叫加节点,加参数,不仅如此,整个模型都要重新训练
因此,我们需要更灵活的网络结构:
- 卷积神经网络:CNN / Convolutional Neural Network
- 循环神经网络:RNN / Recurrent Neural Network
2. 卷积神经网络(CNN)
2.1 二维卷积神经网络
卷积神经网络是图像识别任务的常用的模型,因此最常用的CNN模型都是二维CNN
在二维神经网络中,每一层都是一个二维的矩阵
层与层之间的计算逻辑包括
- 卷积:Convolution
- 池化:Pooling
2.1.1 卷积运算(Convolution)
卷积计算,要使用到卷积核(Kernel),是一个矩阵,矩阵中的元素就是该层的参数
卷积计算,是使用卷积核(我们后面称为核矩阵),在该层的二维矩阵(我们后面称为层矩阵)上进行扫描
- 每扫描一步,核矩阵与层矩阵的对应元素相成,所有元素相乘的结果再进行相加
- 所有扫描结束后,对应扫描位置的结果拼在一起,形成一个新的矩阵,叫做特征图(Feature Map)
- 扫描的步长通常是1,当然也可以是其他步长
例如以下这个卷积运算:
可以看到,参数w、x、y、z,被多次使用,因此CNN卷积核的一个重要作用就是做到参数共享
以上的例子中,我们只使用到了一个卷积核,在同一层中,我们还可以使用多个卷积核
- 多个卷积核的大小是一致的,所以参数量是整数倍增的
- 使用K个卷积层,就会生成K个特征图,在传入下一层前,这K个特征图会进行相加,形成一个新的特征图
除了卷积核可以使用多个,我们还可以设置多个通道(Channel)
- 当本层有M个通道时,本层的数据会有M个版本
- 常见的多通道使用场景是,一张图片中每一个像素点,都有R(红色),G(Green),B(Blue),三个颜色的数据,因此我们需要R,G,B,三个通道
- 每一个通道都有一个版本的Kenel,所以通道数也会让参数量整数倍增
以下是一个多卷积核多通道的例子:
2.1.2 池化运算(Pooling)
在进行下一层的运算前,多个Feature Map会加在一起,形成一个综合的Feature Map,并且Feature Map会进行池化运算
池化运算中就没有参数了,它是使用一个没有重叠的滑动窗口,从左向右从上到下滑动,窗口中的所有值进行一定的运算
- MaxPooling:窗口中的所有值求最大值
- AvgPooling:窗口中的所有值求平均值
池化后的运算结果,才会被输入到下一层
2.1.3 填充(Padding)
CNN中,不论卷积还是池化,都是使用一个滑动窗口(卷积可重叠,池化不重叠)
- 这当中都会遇到一个问题就是,滑动到横向或纵向的最后一步时,数据不够
- 数据不够,就要补齐,补齐通常是在矩阵外围补一圈0,使得矩阵维度可以正好运行卷积或池化运算
2.1 一维卷积神经网络
使用同样的思维,如果我们把每一层的矩阵换为维度为N X 1的列向量,那么二维CNN就变成了一维CNN了
以下是一个一维CNN的示意图
- 这当中我们使用一个维度为3X1的从上到下扫描,得到的Feature Map也是一个1维向量
- 之后Feature Map进行池化,得到本层的输出结果
以前我们提到过前馈神经网络的缺点就是,当模型有增加特征需求的时候,需要引入新的参数,前馈神经网络必须重新训练
- 这一问题可以被卷积神经网络很好的解决
- 不论输入特征有多少,我们使用卷积核从上到下扫描就行了
3. 循环神经网络(RNN)
循环神经网络RNN和卷积神经网络CNN类似,也是涉及到了参数共享
- CNN:将数据排列成一维或二维矩阵,接着使用滑动窗口进行运算
- RNN:数据按顺序,一个一个进入RNN节点中
比起CNN,RNN结构的灵活度是更高的,许多流行的神经网络都是RNN的改版
3.1 普通RNN网络
RNN通常应用于序列型的数据(数据的顺序很重要),可以理解为序列,或者时间
- 时间序列
- 语言文字
一个RNN节点的结构为:
我们通常会将它按照输入顺序展开,就形成了以下示意图,这个图其实是有一点误导性的
- 下图中看似是4个RNN节点
- 但是其实只有1个RNN节点,因为参数共享
RNN在进行训练的时候,使用到的机制是通过时间的反向传播
- 例如图中的RNN进行了4次计算,在进行参数值更新的时候,依然是使用链式法则求导
- 但是此时的链式法则,是loss对第4次运算求导 X 第4次运算对第3次运算求导 X 第3次运算对第2次运算求导 X 第2次运算对第1次运算求导 X 第1次运算对参数求导
这当中有个问题叫做梯度消失
- 当RNN传播的次数太多的时候,链式法则求的导越来越小到最后基本是0了,对参数的更新基本也就没有了
- 解决梯度消失的方法,通常是使用LSTM
在介绍LSTM之前,我们来看一些RNN的变形,来感受一下神经网络的灵活性
- 多层RNN
- 双向RNN
3.2 长的短期记忆网络:LSTM(Long Short-Term Memory)
LSTM和普通RNN结构展开图都是类似的,只不过节点当中的运算更复杂了
LSTM使用一个叫做“门”的结构(Gate)
- 门是一个向量,它当中的元素都在0-1之间(百分比)
- 门和一个同样大小向量,进行逐元素相乘时,门就可以决定这个向量中的各个元素的保留率
一个LSTM节点示意图为
这个结构中,每一个LSTM单元,都有两个输入输出端
- h:模型的输出端
- c:模型的记忆端
LSTM单元的计算逻辑是:
- 输入端ht-1和数据端xt进行拼接之后的产物,比方所我们叫做zt,共进行了四种运算:
- 遗忘门:ft = sigmoid(zt的线性组合):决定上一个阶段的记忆端ct-1,保留多少
- 输入门:it = sigmoid(zt的线性组合):决定本阶段的信息c~t,保留多少
- 本阶段的新信息:c~t = tanh(zt的线性组合)
- 本阶段的记忆端:ct = tanh(zt的线性组合) = ft @ ct-1 + it @ c~t
- 输出门:ot = sigmoid(zt的线性组合)
- 本阶段的输出:ht = ot @ tanh(ct)
对于一个神经网络结构,只要是普通RNN能构建的,LSTM也可以构建
- 因为不论是RNN中的运算,还是LSTM中的运算,都是有输入,有输出
- 只要输入端能对应上,输出端能对应上,就可以,至于节点中进行怎样的运算,都无所谓
- 人们按照此思路,开发了许许多多的类似于RNN的计算节点,只要有输入,有输出,就可以当做一个类似于RNN的计算单元
\