吴恩达序列模型课程笔记(Week1)

下面开始学习吴恩达深度学习之序列模型系列课程。学习资源

examples of sequence data
在这里插入图片描述
序列模型常用于处理监督学习问题,输入x和输出y均为序列,但对应长度可以相等也可以不相等。

定义标识
以Named-entity recognition(常用于搜索引擎中) 为例,即从一个序列中识别出人名。
在这里插入图片描述
如上图所示,输入一串文本序列,输出要求是对应每个单词给出一个标记,表明该单词是否位于人名的一部分。

x < t > x^{<t>} 表示输入序列中的第t个单词,用 y < t > y^{<t>} 表示输出序列中的第t个item, T x T y T_x、T_y 表示输入、输出的item数目。
x ( i ) x^{(i)} 表示第i个训练样本, x ( i ) < t > x^{(i)<t>} 表示训练样本i的序列中第t个元素; T x ( i ) T_x^{(i)} 表示第i个样本的输入长度;相应地输出序列也用如下表示。

表示单词
对于输入的语句,需要制作一张词表,在商业中30000到50000词的词表比较常见。制作词表可以用两种方法:一种是遍历训练集找到频率最高的前10000词,一种是查阅网络字典找到前10000字。得到词表后,可用one-hot 表示单词。

为什么不使用标准网络处理文本问题
将输入序列通过一个标准的网络,经过多层的处理,得到对应的输出,如下图所示。
在这里插入图片描述
结果表明,这种方法并不好,问题在于:

  1. 输入和输出在不同的例子中的长度可能不同
  2. 不能共享从文本不同位置学到的特征
    第二种问题要求就是在 x < 1 > x^{<1>} 学到识别出现某人名时,那当该人名出现在其他位置时也能识别出来。

此外,利用基础的网络时,输入会十分庞大(输入语句的最大长度*词典长),同时参数数目也极为庞大。

RNN 网络结构(基础版Tx=Ty)
在下面这个例子中,构建了一个输入和输出个数相等的RNN结构:当前输入 x < t > x^{<t>} 的输出 y < t > y^{<t>} 不仅受 x < t > x^{<t>} 的影响,还受到 x < 1 > , x < 2 > , . . . , x < t 1 > x^{<1>},x^{<2>},...,x^{<t-1>} 的影响。此外在该模型中,所有参数是共享的,也就是在每一层中,都用到同意参数 w a x w_{ax} 。这种模型结构限定了在某一时刻的预测仅收到受到序列之前信息的影响而没有使用序列中后部分的信息。(改进模型:BRNN)在这里插入图片描述
接下来简述 RNN结构的计算内容:
RNN的前向传播
其中用 w a x w_{ax} 表示某个a类型的参数且作用于X变量, g ( ) g(\cdot) 表示激活函数。
在这里插入图片描述
这些公式定义了RNN的前向传播方式。下面简化上述的表达,用矩阵乘法的形式表示公式。
在这里插入图片描述
RNN的反向传播
在这里插入图片描述
L表示损失函数,每一步的输出都可以算出一个损失Lt,其中Lt 是用logits 损失函数定义的,最终整个模型的loss是对每一步的loss求平均。绿色标记部分为前向传播时运用到的参数,红色箭头为反向传播的路径。具体传输过程,梯度计算可见文末作业

其他RNN结构
在这里插入图片描述
many-to-many 结构表示输入和输出都是一个序列,且图上绘制的序列结构用于处理Tx=Ty的情况;many-to-one表示输入一个序列但只在最后做一个输出,输出为一个tag,例如情感分析;one-to-one与标准的神经网络几乎没有差异,表示一对一输出。

在这里插入图片描述
上图展示了one-to-many结构,这种结构常用于生成音乐;many-to-one 结构,这种结构主要处理 Tx != Ty时的模型。

语言模型和序列生成
构建语言模型需要有训练集(文本语料库);对于文本的处理包括对每个句子做Tokenize : 为每个单词做一个编码(不重要的标点符号可以不加编码);在每个句子末尾增加 < EOS >;对语料库中不存在的单词标记为< UNK >。

在这里插入图片描述
利用上述的基础RNN模型去训练一个语言模型。第一个输入 x &lt; 1 &gt; x^{&lt;1&gt;} 为0向量,输出为语料库中所有单词被作为第一个输出的概率,接下来输入 x &lt; 2 &gt; x^{&lt;2&gt;} 即Cats 这个单词,此处的 x &lt; 2 &gt; = y &lt; 1 &gt; x^{&lt;2&gt;}=y^{&lt;1&gt;} ,其中 y &lt; 1 &gt; y^{&lt;1&gt;} 即为语句中第一个位置处的实际输出单词,输出 y ^ &lt; 2 &gt; \hat y^{&lt;2&gt;} 输出的是在已知第一个单词为Cats 的情况下,输出各单词的概率,以此类推,直至输入第9个单词Day。

新序列采样
在训练好一个模型后,想了解该模型的学习情况,一个非正式的方法就是进行一次采样,即利用模型重建一个句子。

与training 不同的部分是:从 x &lt; 2 &gt; x^{&lt;2&gt;} 开始的每一步输入都变成 y ^ &lt; 1 &gt; \hat y^{&lt;1&gt;} , y ^ &lt; 2 &gt; \hat y^{&lt;2&gt;} ,…, y ^ &lt; T y 1 &gt; \hat y^{&lt;T_y-1&gt;} ,若词表中包含EOS,则当估计出eos时,过程停止,否则自己限定句长。
在这里插入图片描述
基于字符的语言模型
基于字符的语言模型是以字符为量级做预测,其词表包含大小写字符以及标点字符,虽然这种模型可以处理类似‘mua’这种不在词表内的情况,但由于一个句子可能包含的字符数目过多,导致难以捕捉句子中的依赖关系,即句子的较前部分如何影响较后部分,且难以捕捉长范围的关系;这种模型的训练成本也比较高昂。
在这里插入图片描述

基础RNN模型的梯度消失问题
如果要训练下面这句话:根据前面的cat的形式判断后面的动词形式。
由于两个词中间间隔了很多单词,所以容易发生梯度消失的问题,从而难以根据前面这部分的信息判断后面部分的信息。
在这里插入图片描述
类比于一个一般的网络结构,当网络层数变多时,做反向梯度传导时,会出现梯度消失的问题;同样地,cat和was之间间隔多个单词等同于间隔多个层,那么在做反向梯度传导时就很难通过cat的信息去影响was/were。此外,多层网络下,不仅容易出现梯度消失,还容易出现梯度爆炸,若出现NAN或不是数字的情况就意味着出现了梯度爆炸,一个解决方法就是gradient clipping(梯度修剪),当梯度大于某个阈值时,就进行缩放。通常情况下,梯度消失更难解决。

simplified GRU(Gated Recurrent Unit)
该模型是对RNN模型的一个修正,改变了RNN的隐藏层,使其可以更好的捕捉深层连接,改善梯度消失问题。
GRU是在RNN 模型的基础上对每层的隐藏层输出 a &lt; t &gt; a^{&lt;t&gt;} 做一个改变。首先回顾一下RNN的隐藏层单元:
在这里插入图片描述
简化版的GRU有个新变量c,代表记忆细胞,在GRU中 c &lt; t &gt; = a &lt; t &gt; c^{&lt;t&gt;}=a^{&lt;t&gt;} ,但这里用c和a两个记号分别表示记忆细胞值和激活输出值,虽然在GRU中,两个值的大小是一样的,但在LSTM中代表不同的值。在每一步会有一个c的候选值 c ^ \hat c ,同时增加一个门限Gate γ \gamma ,其取值范围在0-1之间用以表明是否对c
做更新。其中 c &lt; t &gt; γ u c ^ &lt; t &gt; c^{&lt;t&gt;}、\gamma_u、\hat c^{&lt;t&gt;} 的更新公式:

在这里插入图片描述
其中 c &lt; t &gt; c^{&lt;t&gt;} , γ u \gamma _u 等都可以是一个向量且他们维度相等,所以其之间的乘法是元素相乘,此外在每一次更新中,可以选择一些特征保持不变(因为ct是多维的,可以存储多个特征。)

以‘The cat, which already ate …, was full.’为例,若想通过GRU模型,使得cat 对后面的was 产生影响,不妨设 c &lt; t &gt; = 1 c^{&lt;t&gt;}=1 (1表示cat,0表示cats),这里要做的就是能尽量保留 c &lt; t &gt; c^{&lt;t&gt;} 的值,直到遇见be动词,并使它选was而不是were作为动词,那这里gate的作用就是告知c从什么时候开始改变(此时gate=1)什么时候开始记忆(此时gate=0)。
在这里插入图片描述
简易GRU单元的可视化:
在这里插入图片描述
Full GRU
增加 γ r \gamma_r 表示 c &lt; t 1 &gt; c^{&lt;t-1&gt;} c ^ &lt; t &gt; \hat c^{&lt;t&gt;} 的相关性。
在这里插入图片描述
LSTM (long short term memory
LSTM也是目前比较常用的序列模型,相比于GRU其效果更好。

相比GRU中仅使用update gate γ u \gamma_u 去更新 c &lt; t &gt; c^{&lt;t&gt;} ,LSTM网络中增加了一个更新权重forget gate γ f \gamma_f (遗忘门)以及output gate γ o \gamma_o 去分别更新 c &lt; t &gt; c^{&lt;t&gt;} a &lt; t &gt; a^{&lt;t&gt;} 。以下是GRU和LSTM的对比,值得注意的是,在计算 c ^ &lt; t &gt; \hat c^{&lt;t&gt;} 时,LSTM不再使用 c &lt; t &gt; c^{&lt;t&gt;} 的值,而是 a &lt; t &gt; a^{&lt;t&gt;} 的值去计算。
在这里插入图片描述
在这里插入图片描述

将多个cell串联起来就可以得到一个完整的过程。可以观察到 c &lt; t &gt; c^{&lt;t&gt;} 的输入输出是可以串连成一条流程线的, c &lt; 0 &gt; c^{&lt;0&gt;} 的值是可以一直传递下去,这也是为什么GRU和LSTM模型善于记忆某个值。

在这里插入图片描述

  • peephole connection(窥孔连接) ? (听得不是很清楚)
    是指 c &lt; t 1 &gt; c^{&lt;t-1&gt;} 可以影响门值

Bidirectional RNN
BRNN 是一个双向传播的过程,在名字识别的RNN 模型中,发现识别当前单词是否为名字的时候,不仅需要前文的信息,可能还需要后文的信息,BRNN是对其的一个改进。
在这里插入图片描述
简而言之,BRNN做的事情就是从左至右做一次传播后得到activation(紫色部分)后,再从右至左传播一次得到activation(绿色部分),最后利用两次传播的激活值计算预测值。这里的block可以是基础RNN结构,也可以是LSTM或者GRU单元。在做NLP时,若文本语句完整,则常用双向LSTM去处理。

deep RNNS
之前提及的基础RNN,LSTM,GRU等序列模型都可以处理问题,但遇到更为复杂的模型时,会考虑利用更深层的RNN处理问题。
在这里插入图片描述
deep RNN 的构造是将多个RNN堆叠在一起,如上图所示,而每层之间可以通过一个激活函数加以连接,一般情况下,deep RNN的模型结构最多可以达到3层,但是若想做更深入的计算,可以在最后一层的每个时间节点叠加训练模型以加深网络层数。

课后练习1
Build a RNN step by step
课后练习包含四个部分,即基础RNN和LSTM的前向传播及后向传播过程,作业中需要用到自定义模块rnn_utils,这部分内容已上传至github,大家可以下载后存放在工作路径中。

Dinosaur Island – Character-level language model
Jazz improvisation with LSTM

猜你喜欢

转载自blog.csdn.net/qq_39446239/article/details/89457676