文章目录
- 一、神经网络的基本构成部分
- 1.1 神经元
- 1.2 单层神经网络
- 1.3 多层神经网络
- 1.4 非线性激活函数(activation functions)
- 1.5 输出形式
- 二、神经网络的训练方式
- 2.1 损失函数
- 2.2 梯度下降法
- 2.3 反向传播(Backpropagation)
- 三、词向量:Word2vec
- 3.1 CBOW
- 3.2 Skip-Gram
- 3.3 负采样
- 学习单词嵌入的其他技巧
- 四、常见的神经网络结构
- 4.1 循环神经网络(Recurrent Neural Networks,RNNs)
- 4.1.1 门控循环单元(Gated Recurrent Unit,GRU)
- 4.1.2 长短期记忆网络(Long Short-Term Memory Network,LSTM)
- 4.1.3 双向 RNN(Bidirectional RNNs)
- 4.2 卷积神经网络(Convolutional Neural Networks,CNN)
- 参考
发现了一个有趣的视频集合【官方双语】神经网络基本思想,从零开始理解深度学习!讲解非常非常通俗,还可以锻炼英语听力,BAM!!!
初进该领域,希望能和大家一起交流 o( ̄▽ ̄)ブ,有什么问题可以在下面评论哦😊
一、神经网络的基本构成部分
神经网络的全称是人工神经网络(Artificial Neural Network),是受生物神经网络所启发的。
1.1 神经元
生物中的神经网络主要由一个又一个的神经元的细胞构成的,其中每一个神经元的细胞会从它的树突中去接受来自于其他细胞的若干信号作为输入,这个细胞处理了这些输入之后,会从轴突去输出若干个信号。
受到这个生物里面的神经网络和神经元的启发,我们可以设计出由计算机能够计算的人工神经元(简称神经元)。这个神经元在左边会接受 n 个数作为输入,然后在右边产生一个数的输出。这个神经元由参数 w 和 b 以及激活函数 f 构成。
如下图所示,这个神经元有三个输入 x 1 , x 2 , x 3 x_1,x_2,x_3 x1,x2,x3,对应的三个权重分别为 w 1 , w 2 , w 3 w_1,w_2,w_3 w1,w2,w3。我们会计算一个乘积和 x 1 w 1 + x 2 w 2 + x 3 w 3 x_1w_1+x_2w_2+x_3w_3 x1w1+x2w2+x3w3,然后将这个值与偏置 b b b 相加。这相当于输入有四个,其中第四个恒为1,而第四个输入对应的权重为 b b b,这样偏置的计算可以统一到前面计算乘积和的步骤中。接着,这个乘积和会经过一个非线性的激活函数,然后就会得到这一个神经元的输出。
这个计算过程可以被形式化地表示为下面这个式子: h w , b ( x ) = f ( w T x + b ) h_{\boldsymbol{w},b}(\boldsymbol{x})=f(\boldsymbol{w}^T\boldsymbol{x}+b) hw,b(x)=f(wTx+b) 我们把权重 w \boldsymbol{w} w 和输入 x \boldsymbol{x} x 写成了粗体,表示它们是个向量。
1.2 单层神经网络
利用多个这样的神经元联系在一起,可以构成一个这样只有一层的的神经网络,如下图,这个神经网络是由 3 个神经元构成的。
在具体计算的时候,我们可以认为右边的 3 个神经元可以并行计算,它们按照上面的方式分别得到一个值(如下图中的a1,a2,a3),这时这一层的计算可以用 a = f ( W x + b ) \boldsymbol{a}=f(\boldsymbol{Wx}+\boldsymbol{b}) a=f(Wx+b) 来表示,其中权重从向量变成了一个矩阵( W 12 W_{12} W12 表示这个数和 x 2 x_2 x2 相乘,作为第 1 个神经元的一部分输入),偏置从标量变成了一个向量, f f f 作用在一个向量上时先对其中的每一个值分别进行运算再将结果组成一个同型的向量。
1.3 多层神经网络
在单层神经网络之后,我们还可以继续叠加类似的层,变成一个多层的神经网络,其中每层都有若干个神经元。计算的时候从最左边的输入开始,依次计算每一层的结果,其中每一层的输出结果会作为下一层的输入,这就是前向计算。
我们通常把在输入之上添加的多层网络称之为隐层(hidden layers),然后输入部分称之为输入层(input layer)。隐层的输出通常使用 h \boldsymbol{h} h 来表示,如下图中的 h 1 \boldsymbol{h_1} h1, h 2 \boldsymbol{h_2} h2 和 h 3 \boldsymbol{h_3} h3。
为了得到输出结果,我们需要在神经网络最右边再网络的最后一层,即输出层(output layer)
1.4 非线性激活函数(activation functions)
接下来介绍一下这个非线性的激活函数。
首先我们先假定神经网络中并没有激活函数,神经网络中就只存在线性运算了,比如对于两层的神经网络,两层的运算其实可以被表示成单层的运算,也就是说在这样情况下,多层网络和单层网络的表达能力是相同的。
因此我们需要引入非线性的激活函数,这样可以防止多层神经网络塌缩为一层的神经网络,我们也可以通过更加复杂的激活函数来加强多层网络的表达能力。
一些常见的激活函数有:
- Sigmoid: f ( z ) = 1 1 + e − z f(z)=\frac{1}{1+e^{-z}} f(z)=1+e−z1
f ( 0 ) = 0.5 f(0)=0.5 f(0)=0.5,值域: ( 0 , 1 ) (0,1) (0,1)
- Tanh: f ( z ) = t a n h ( z ) = e z − e − z e z + e − z f(z)=tanh(z)=\frac{e^z-e^{-z}}{e^z+e^{-z}} f(z)=tanh(z)=ez+e−zez−e−z
f ( 0 ) = 0 f(0)=0 f(0)=0,值域: ( − 1 , 1 ) (-1,1) (−1,1)
- ReLU: f ( z ) = m a x ( z , 0 ) f(z)=max(z,0) f(z)=max(z,0)
f ( 0 ) = 0 f(0)=0 f(0)=0,值域: ( 0 , + ∞ ) (0,+∞) (0,+∞)
1.5 输出形式
假设神经网络只有一层隐含层,输出层只有一个神经元,输出方式主要有两种。
第一种不使用激活函数,直接线性输出: y = w T h + b y=\boldsymbol{w}^T\boldsymbol{h}+b y=wTh+b
第二种使用 sigmoid 激活函数: y = σ ( w T h + b ) y=\sigma(\boldsymbol{w}^T\boldsymbol{h}+b) y=σ(wTh+b),这种形式常用于二分类问题,使用 y y y 表示一类,而使用 1 − y 1-y 1−y 表示另外一类
当输出使用 softmax 激活函数,它主要用来解决多分类的问题。对于只有一层隐含层的神经网络,输出层有几个神经元就代表有几种类别,输出相当于一个概率分布。比如下图表示要分类三个类别。
其中具体输出为:
二、神经网络的训练方式
2.1 损失函数
首先我们需要设定一个目标,根据这个目标去不断调节整个神经网络,即不断去最小化损失函数的值。
对于线性回归任务,比如有 N N N 个训练样本 ( x i , y i ) i = 1 N {(x_i, y_i)}^N_{i=1} (xi,yi)i=1N,其中 x i x_i xi 和 y i y_i yi 分别表示一台电脑的属性和价格,我们想要训练的神经网络 F θ ( ⋅ ) F_\theta(·) Fθ(⋅) 将属性 x x x 作为输入,然后输出预测价格 y y y。一个合理的训练目标是最小化均方误差(Mean Squared Error):
其中 θ \theta θ 是神经网络 F θ ( ⋅ ) F_\theta(·) Fθ(⋅) 中的参数。
对于文本分类任务,比如比如有 N N N 个训练样本 ( x i , y i ) i = 1 N {(x_i, y_i)}^N_{i=1} (xi,yi)i=1N,其中 x i x_i xi 和 y i y_i yi 分别表示一个句子和这个句子的情绪标签(比如正面、负面或中性),我们想要训练的神经网络 F θ ( ⋅ ) F_\theta(·) Fθ(⋅) 将句子 x x x 作为输入,然后输出预测情绪标签 y y y,一个合理的训练目标是最小化交叉熵(Cross-entropy):
比如一个句子样本经过 softmax 输出后的结果如下,第一个绿圈表示正面,用 y = 1 y=1 y=1 表示,第二个绿圈表示负面,用 y = 2 y=2 y=2 表示,第一个绿圈表示中性,用 y = 3 y=3 y=3 表示。绿色圆圈中的输出数值则分别表示通过这个给神经网络得出的这个句子为正面、负面和中性的概率。
如果这句话的事实分类是 y = 1 y=1 y=1,则交叉熵为:
如果这句话的事实分类是 y = 2 y=2 y=2,则交叉熵为:
如果这句话的事实分类是 y = 3 y=3 y=3,则交叉熵为:
当有多个样本时,交叉熵会再取一个平均值。
当交叉熵,即这个损失函数越小,表示神经网络进行正确类别预测的概率越大,也就是说这个模型预测得也越准确。
2.2 梯度下降法
为了达到我们得训练目标,我们希望将损失函数最小化。那如何最小化损失函数呢?在神经网络中我们通常使用梯度下降法。
首先我们要求损失函数对于每个模型参数的梯度,这个梯度代表对参数进行单位大小的改动后损失函数变化最快的一个方向,接着我们顺着这个方向的反方向向前走一步,即将模型参数进行小变化,我们就可以降低一点损失函数。这个过程好比爬山,我们选择最陡峭的方向迈出一步,这样会让我们爬得更快一些。由于我们期望损失函数不断降低,因此我们选择得方向是梯度的一个反方向。
那这个步伐应该多大呢?这是由 α \alpha α 这个参数来决定的,这个参数被称为学习率(learning rate),
可以看一下这个视频,非常棒😊
【官方双语】零基础梯度下降法,手把手教你优化损失函数!
现在有 3 个 <Weight,Height> 样本,我们的目标是拟合一条反映身高与体重之间关系的直线,也就是说,我们要找到这条直线的截距(intercept)和斜率(slope),使得损失函数(这里选用平方残差之和)值最小
首先固定斜率,只考虑截距,也就是说只考虑一个变量,步骤见下面的动图:
现在我们理解了梯度下降如何计算截距,接下来讨论如何估计截距和斜率两个变量:
注:多个偏导数就组成了梯度
现在我们理解了梯度下降如何估计截距和斜率两个变量,如果有我们的损失函数有更多的变量,只需要取更多的导数,其他一切保持不变
总结一下:
注:当我们有百万个数据点时,这个过程需要很长时间。因此有一种叫随机梯度下降(Stochastic Gradient Decent)的方法,它在每一步都使用数据的一个随机选取的子集,而不是完整的数据集,这就减少了计算损失函数的导数所花的时间。
接下来详细讲一下梯度的计算。
对于一个具有 1 个输出和 n n n 个输入的函数 F ( x ) = ( x 1 , x 2 , . . . , x n ) F(\boldsymbol{x})=(x_1,x_2,...,x_n) F(x)=(x1,x2,...,xn),它的梯度是各个偏导数组成的向量:
对于一个具有 n n n 个输入 m m m 个输出的函数 F ( x ) = ( F 1 ( x 1 , x 2 , . . . , x n ) , F 2 ( x 1 , x 2 , . . . , x n ) . . . F m ( x 1 , x 2 , . . . , x n ) ) F(\boldsymbol{x})=(F_1(x_1,x_2,...,x_n),F_2(x_1,x_2,...,x_n)...F_m(x_1,x_2,...,x_n)) F(x)=(F1(x1,x2,...,xn),F2(x1,x2,...,xn)...Fm(x1,x2,...,xn)),它的雅可比矩阵(Jacobian matrix)即梯度的泛化是一个由偏导数组成的 m × n m×n m×n 大小的矩阵:
接下来回顾一下链式法则这个概念,这个概念对于在神经网络中求梯度是很有用的。
对于单变量函数,就是进行导数之间乘法运算:
对于多输入多输出的情况,则是进行雅可比之间乘法运算:
2.3 反向传播(Backpropagation)
这个算法其实就是在计算梯度。在介绍反向传播算法之前,我们先了解一下计算图(Computational Graph)这个概念。
计算图可以让我们把神经网络的计算公式画成一个图,其中
- 源节点:表示网络的输入
- 内部节点:表示计算操作
- 有向边:传递计算出来的值
根据输入进行计算得到最终的值的过程被叫做前向传播(Forward Propagation)。
反向传播算法是沿着和这个计算图相反的方向依次计算出<结果>对<每一条边的值>的梯度,知道我们计算到输入的这条边。
假设我们要计算 s s s 对 b \boldsymbol{b} b 的梯度,那么计算过程如下:
具体拿出一个节点来看,假设我们已经得到了 ∂ s ∂ h \frac{\partial s}{\partial \boldsymbol{h}} ∂h∂s,我们把它叫做上游梯度(upstream gradient),为了计算 ∂ s ∂ z \frac{\partial s}{\partial \boldsymbol{z}} ∂z∂s,即下游梯度(downstream gradient),我们先将计算当前节点的输出对当前节点的输入的微分 ∂ h ∂ z \frac{\partial \boldsymbol{h}}{\partial \boldsymbol{z}} ∂z∂h,即,本地梯度(local
gradient),如下图:
然后我们就可以应用链式法则得到 ∂ s ∂ z = ∂ s ∂ h ∂ h ∂ z \frac{\partial s}{\partial \boldsymbol{z}}=\frac{\partial s}{\partial \boldsymbol{h}}\frac{\partial \boldsymbol{h}}{\partial \boldsymbol{z}} ∂z∂s=∂h∂s∂z∂h,即下游梯度=上游梯度×本地梯度。得到这个下游梯度后,我们可以使用相同的方法对更下游的节点进行计算。
举个简单的例子:
细心的你是不是发现这其实就是高数里面求偏导数的方法!
总结一下这一节:
- 通过正向传播得到结果并计算损失函数并保存中间值
- 通过反向传播应用链式法则计算梯度
- 接着利用梯度下降法不断去找最优的参数值。
三、词向量:Word2vec
这是一个神经网络的简单例子。Word2vec 使用了一个非常简单的神经网络进行训练来得到词的向量表示(分布式表示)。它可以捕捉许多语言规律,如下图:
Word2vec 使用沿句子移动的固定大小的滑动窗口,在每个窗口中,中间词是目标词(target word),其他词是上下文词(context words)。
Word2vec 有两种结构:
- Continuous bag-of-words (CBOW):利用上下文词预测目标词
- Continuous skip-gram:利用目标词来预测上下文词
3.1 CBOW
模型假设:上下文词的顺序不影响预测
假设窗口大小为 3,对于句子 Nerver too late to learn
,我们要估计概率 P ( t o o ∣ [ n e v e r , l a t e ] ) P(too|[never,late]) P(too∣[never,late]),即当上下文词是 never
、late
时,目标词是 too
的概率。
下图展示了CBOW 的网络结构。
- step1:我们将
never
和late
这两个词表示为 one-hot 向量; - step2:接着在我们最终要得到的一个词向量矩阵中找到这两个词分别对应的词向量( C 5 C_5 C5 和 C 2 C_2 C2);
- step3:将 C 5 C_5 C5 和 C 2 C_2 C2 进行平均后得到一个新的向量,维度和 C 5 C_5 C5 、 C 2 C_2 C2相同;
- step4:将向量转换为维度为词表大小的向量
- step5:通过 softmax 得到概率分布向量
3.2 Skip-Gram
假设窗口大小为 5,对于句子 Nerver too late to learn
,too
是目标词的话,never
、late
、to
是上下文词,我们就要估计概率 P ( n e v e r ∣ t o o ) P(never|too) P(never∣too)、 P ( l a t e ∣ t o o ) P(late|too) P(late∣too) 和 P ( t o ∣ t o o ) P(to|too) P(to∣too)。
下图展示了Skip-Gram 的网络结构。
3.3 负采样
上面对两个模型中,我们最后都是要得到一个维度为词表大小的概率分布向量。但是当这个词表非常大时,全部的 softmax 过程在计算上是不切实际的,我们需要提高计算效率。
实际上,我们在 word2vec 中不需要完整的概率模型吗,对计算过程可以进行取舍。具体有两种方法:
- 负采样(Negative sampling)
- 分层 softmax(Hierarchical softmax)
负抽样的想法是,每一步只更新一小部分权重,而不是更新全部的权重。
我们按概率选择不在上下文单词列表中的几个单词:
P ( w i ) = f ( w i ) 3 / 4 ∑ j = 1 V f ( w j ) 3 / 4 P(w_i)=\frac{f(w_i)^{3/4}}{\sum_{j=1}^Vf(w_j)^{3/4}} P(wi)=∑j=1Vf(wj)3/4f(wi)3/4
其中 f ( w i ) f(w_i) f(wi) 表示词 w i w_i wi 的频率。公式里的指数 3 / 4 3/4 3/4 是为了低频单词被选择的可能性,防止它们一直都不被选中,这是一个经验值。
下面我们拿 Skip-Gram 模型来举例。假设我们只采样 4 个不在上下文单词列表中的词(negative words),在计算 P ( n e v e r ∣ t o o ) P(never|too) P(never∣too) 是我们只需要得到一个维度为 5 的向量。
学习单词嵌入的其他技巧
- 子采样(Sub-Sampling):稀有词的语义内涵能加丰富,因此,若 f ( w ) f(w) f(w) 表示单词 w w w 的词频,则这个词将以 1 − t / f ( w ) 1-\sqrt{t/f(w)} 1−t/f(w) 的概率被弃用,其中 t t t 可以调节的参数;
- 可变滑动窗口(Soft sliding window):滑动窗口应将较小的权重分配给较远的单词,定义滑动窗口的最大大小为 S m a x S_{max} Smax,对于每个训练样本,实际窗口大小在 1 1 1 和 S m a x S_{max} Smax 之间随机采样。因此,目标单词附近的那些单词更有可能出现在窗口中。
四、常见的神经网络结构
4.1 循环神经网络(Recurrent Neural Networks,RNNs)
可以先看一下这个有趣的小视频:【官方双语】全网最简单易懂的 [RNN循环神经网络] 介绍,一个视频理解梯度消失和梯度爆炸
当输入个数不固定,比如预测明天的天气,我们可能输入前 5 天的数据,也有可以输入 7 天的数据,这种情况下,我们可以使用循环神经网络 RNN。
RNN 的核心是使用了顺序记忆(Sequential Memory)的机制,这是一种使大脑更容易识别序列模式的机制,比如对于 ABCDEFG
这样有顺序的句子我们的大脑很容易理解,而对于我们不熟悉的序列 DEBCFAG
我们的大脑一下就很难读懂。
RNN 简化模型如下:
其中 h 0 h_0 h0 一般是随机初始化的。
我们发现这个网络其实是下图这部分的重复:
我们把这部分称作 RNN 单元(RNN Cell)。其中有这样的表达式:
h i = t a n h ( W x x i + W h h i − 1 + b ) y i = F ( h i ) h_i=\mathrm{tanh}(W_xx_i+W_hh_{i-1}+b) \\ y_i=F(h_i) hi=tanh(Wxxi+Whhi−1+b)yi=F(hi)
注意:每一个 RNN 单元中的 W x W_x Wx、 W h W_h Wh、 b b b 这三个参数都是一样的。
下面我们来看一个 RNN 语言模型的例子,这个模型的目的是根据前面输入的几个词来预测下一个词。和 Word2vec 类似,对于每一个单词我们先用 one-hot 进行编码,根据这个向量在词向量矩阵中找到这个词的向量表示,即 x i = E w i x_i=Ew_i xi=Ewi,接着不断去应用上面描述的法则。
当我们得到 h 4 h_4 h4 时, h 4 h_4 h4 就包含了之前的词序列的信息,最后我们通过 softmax 函数得到预测概率分布向量 y 4 = s o f t m a x ( U h 4 + b 2 ) y_4=softmax(Uh_4+b_2) y4=softmax(Uh4+b2)
接下来我们分析一下这个模型的优点和缺点。
优点
- 输入的长度没有固定
- 模型的大小没有由于输入长度的增加而变大(因为参数共享)
- 理论上,第 i i i 步的计算蕴含着前面几步中的信息(因为传递或者反馈结构)
缺点:
- 计算缓慢(因为输入要依次去计算,输入很多时,计算量也会非常大)
- 实际上,第 i i i 步的计算很难蕴含前面很多步的信息
- 存在梯度爆炸和梯度消失的问题(当 RNN 单元个数巨大是,梯度会存在特别大和特别小的情况,这样我们在进行梯度下降法的时候步伐就会太大和太小)
梯度消失或梯度爆炸的主要解决方案是在递归中使用更复杂的隐藏单位计算。RNN 模型的核心在于 RNN 单元,我们可以针对这个单元进行优化,其中 GRU 和 LSTM 是两个有名比较有名的变体。
4.1.1 门控循环单元(Gated Recurrent Unit,GRU)
GRU 的门控机制允许网络选择性地更新、遗忘和输出信息,使得网络可以更好地处理长期依赖关系。
这里有两个门,分别是更新门(Update gate)和重置门(Reset gate)。这些门用来平衡之前信息和当前信息的比重。
更新门计算过程如下:
z i = σ ( W x ( z ) x i + W h ( z ) h h − 1 + b ( z ) ) z_i=\sigma(W_x^{(z)}x_i+W_h^{(z)}h_{h-1}+b^{(z)}) zi=σ(Wx(z)xi+Wh(z)hh−1+b(z))
重置门计算过程如下:
r i = σ ( W x ( r ) x i + W h ( r ) h h − 1 + b ( r ) ) r_i=\sigma(W_x^{(r)}x_i+W_h^{(r)}h_{h-1}+b^{(r)}) ri=σ(Wx(r)xi+Wh(r)hh−1+b(r))
我们可以看到这两种门有着不同的 W x W_x Wx、 W h W_h Wh 和 b b b。
这里引入了一个新的激活函数,用来表示候选隐藏状态:
最终的隐藏状态 h i h_i hi 计算方法如下:
注:符号 ∗ 表示按位乘法,也称为逐元素乘法。
σ \sigma σ 表示 Sigmoid 函数,函数值处于 ( 0 , 1 ) (0,1) (0,1) 这个范围
下面是一个简单的例子,其中一些参数未明显指出,大家可以结合上面的几个公式自行消化。
可以看一下李沐的讲解视频:56 门控循环单元(GRU)【动手学深度学习v2】
接下来我们对两个门做进一步讨论:
- 重置门 r i r_i ri 控制是否将过去的隐藏层信息忘记(0 表示只考虑当前输入信息)
- 更新门 z i z_i zi 控制当前时间步的输入信息和上一个时间步的隐状态之间的权重(0 表示不考虑以前的隐藏状态)
- 如果重置门 r i r_i ri 中的每个元素都接近于 0,则 h ~ i ≈ t a n h ( W x x i + b ) \tilde{h}_i≈\mathrm{tanh}(W_xx_i+b) h~i≈tanh(Wxxi+b),即忽略了先前的隐藏状态 h i − 1 h_{i-1} hi−1,这表明当前激活与过去无关。比如:在新文章的开头,过去的信息对于当前激活是无用的。
- 如果更新门 z i z_i zi 中的每个元素都接近于 1,则 h i ≈ h i − 1 h_i≈h_{i-1} hi≈hi−1,即只考虑先前的隐藏状态。
- 如果更新门 z i z_i zi 中的每个元素都接近于 0,则 h i ≈ h ~ i h_i≈\tilde{h}_i hi≈h~i,即只接受当前激活。
4.1.2 长短期记忆网络(Long Short-Term Memory Network,LSTM)
LSTM 是一种特殊的 RNN,能够学习像 GRU 这样的长期依赖关系。
我们先来介绍一下 LSTM 中的三个门,我们会发现,这三种门的结构是相同的,只是权重和偏差有所不同。
- 遗忘门(Forget gate): f t = σ ( W f ⋅ [ h t − 1 , x t ] + b f ) f_t=\sigma(W_f·[h_{t-1}, x_t]+b_f) ft=σ(Wf⋅[ht−1,xt]+bf)
- 输入门(Input gate): i t = σ ( W i ⋅ [ h t − 1 , x t ] + b i ) i_t=\sigma(W_i·[h_{t-1}, x_t]+b_i) it=σ(Wi⋅[ht−1,xt]+bi)
- 输出门(Output gate): o t = σ ( W o ⋅ [ h t − 1 , x t ] + b o ) o_t=\sigma(W_o·[h_{t-1}, x_t]+b_o) ot=σ(Wo⋅[ht−1,xt]+bo)
接下来再来看一个新的东西:候选记忆单元:
C ~ t = t a n h ( W C ⋅ [ h t − 1 , x t ] + b C ) \tilde{C}_t=\mathrm{tanh}(W_C·[h_{t-1},x_t]+b_C) C~t=tanh(WC⋅[ht−1,xt]+bC)而真正的记忆单元为:
C t = f t ∗ C t − 1 + i t ∗ C ~ t C_t=f_t*C_{t-1}+i_t*\tilde{C}_t Ct=ft∗Ct−1+it∗C~tGRU 中的状态用 h i h_i hi 来表示,而 LSTM 的状态表示用 h i h_i hi 和 C i C_i Ci 两个来表示。
LSTM 的隐藏态为:
h t = o t ∗ t a n h ( C t ) h_t=o_t*\mathrm{tanh}(C_t) ht=ot∗tanh(Ct)总结一下:
LSTM 功能强大,特别是当堆叠和更深时(每个隐藏层已经由深层内部网络计算),在有大量的数据时非常有用。
4.1.3 双向 RNN(Bidirectional RNNs)
在传统的 RNN 中,当时的状态仅依赖于过去的信息: h t = f ( x t − 1 , . . . , x 2 , x 1 ) h_t=f(x_{t-1},...,x_2,x_1) ht=f(xt−1,...,x2,x1)。但是,在许多的应用比如手写识别、语音识别中,我们需要获取依赖于整个序列的输出。双向 RNN能够同时考虑前向和后向的上下文信息。
双向 RNN 的结构如下:
具体来说,双向 RNN 首先通过在时间步骤上的两个方向上运行两个独立的 RNN,一个从头到尾(前向RNN),另一个从尾到头(反向RNN)。然后,将前向和反向 RNN 的输出拼接起来。
这一节介绍了循环神经网络(Recurrent Neural Network,RNN)的概念及结构,我们知道了 RNN 的关键特点是可以处理变长的序列数据,还知道了 RNN 本身存在的梯度爆炸和梯度消失的问题。对于梯度问题,我们介绍了几种解决办法,即几种 RNN 变体,分别是:门控循环单元(Gated Recurrent Unit,GRU)、长短期记忆网络(Long Short-Term Memory Network,LSTM)和双向 RNN(Bidirectional RNNs)。
4.2 卷积神经网络(Convolutional Neural Networks,CNN)
CNN 最初应用在计算机视觉领域(Computer Vision,CV)中,大家需要点击【官方双语】卷积神经网络CNN进行图像分类,清晰易懂!进行初步的了解。
CNN 擅长提取局部和位置不变模式。局部模式指的是图像中的局部特征,例如边缘、纹理、颜色等。CNN 通过使用卷积层和池化层的组合,可以有效地从图像中提取这些局部模式。位置不变模式是指在图像中,某个特定的模式或者物体不论出现在哪个位置,其特征或者形状都是相似的。
由于 CNN 这样的特点,它可以应用到 NLP 领域,比如关系分类,情感分类等。
CNN 提取局部模式主要通过计算一个句子中所有可能的 N 元组短语的表示,
比如对于句子 The plane is taking off
,
可能的 Bigram 短语有:The plane
、plane is
、is taking
和 taking off
;
可能的 Trigram 短语有:The plane is
、plane is taking
和 is taking off
;
……以此类推我们可以选取更多可能的 N-gram 短语。
我们一般常用的是 Bigram、Trigram 和 4-gram。
CNN 的结构主要有四个部分: 输入层、卷积层、池化层和非线性层
-
输入层(Input Layer):通过单词嵌入(word embeddings)将单词转换为输入表示 x \boldsymbol{x} x, x ∈ R m × d \boldsymbol{x}\in{\boldsymbol{R}^{m×d}} x∈Rm×d,其中 m m m 表示句子的长度(下图中为 6), d d d 表示词向量的维度(下图为 4)
-
卷积层(Convolutional Layer):通过滑动的卷积格(Filter)对向量矩阵进行卷积,提取特征向量
-
池化层(Pooling Layer):对特征向量进行进一步提取,一般是在局部信息中选取最大值或者平均值
-
非线性层(Max-pooling Layer):根据不同任务对上一步输出进行处理
总的一个流程如下:
最后我们总结一下 CNN 和 RNN 的区别:
CNNs | RNNs | |
---|---|---|
优点 | 提取局部和位置不变特征 | 建模长期上下文依赖性 |
参数 | 少 | 多 |
并行化 | 句子内更好的并行化 | 不能在句子中并行化 |
参考
【1】【清华NLP】刘知远团队大模型公开课全网首发|带你从入门到实战
【2】【官方双语】神经网络基本思想,从零开始理解深度学习!
【3】【李沐】 门控循环单元(GRU)【动手学深度学习v2】