• Coursera Deep Learning笔记 序列模型(一)循环序列模型[RNN GRU LSTM]


    参考1
    参考2
    参考3

    1. 为什么选择序列模型

    序列模型能够应用在许多领域,例如:

    • 语音识别

    • 音乐发生器

    • 情感分类

    • DNA序列分析

    • 机器翻译

    • 视频动作识别

    • 命名实体识别

    这些序列模型都可以称作使用标签数据(X,Y)作为训练集的监督式学习,输入x和输出y不一定都是序列模型。如果都是序列模型的话,模型长度不一定完全一致。

    2. Notation(标记)

    下面以 命名实体识别 为例,介绍序列模型的命名规则。示例语句为:

    Harry Potter and Hermione Granger invented a new spell.

    该句话包含9个单词,输出 (y) 即为 (1 imes 9) 向量,每位表征对应单词是否为人名的一部分,1表示是,0表示否。很明显,该句话中“Harry”,“Potter”,“Hermione”,“Granger”均是人名成分,所以,对应的输出y可表示为:

    [y=[1 1 0 1 1 0 0 0 0] ]

    一般约定使用 (y^{<t>}) 表示序列对应位置的输出; 使用 (T_y) 表示输出序列长度,则 (1leq tleq T_y)

    对于输入 (x),表示为:

    [[x^{<1>} x^{<2>} x^{<3>} x^{<4>} x^{<5>} x^{<6>} x^{<7>} x^{<8>} x^{<9>}] ]

    同样,(x^{<t>}) 表示序列对应位置的输入,(T_x) 表示输入序列长度。注意,此例中,(T_x=T_y),但是也存在 (T_x eq T_y) 的情况。

    如何表示每个 (x^{<t>})

    • 方法是首先建立一个词汇库vocabulary,尽可能包含更多的词汇。例如一个包含10000个词汇的词汇库为:

    [left[ egin{matrix} a \ and \ cdot \ cdot \ cdot \ harry \ cdot \ cdot \ cdot \ potter \ cdot \ cdot \ cdot \ zulu end{matrix} ight] ]

    • 该词汇库可看成是10000 x 1的向量。ps: 自然语言处理NLP实际应用中的词汇库可达百万级别的词汇量。

    • 然后,使用one-hot编码,例句中的每个单词 (x^{<t>}) 都可以表示成 (10000 imes 1) 的向量,词汇表中与 (x^{<t>}) 对应的位置为1,其它位置为0。

    • (x^{<t>}) 为one-hot向量。如果出现词汇表之外的单词,可以使用UNK或其他字符串来表示。

    • 对于多样本,以上序列模型对应的命名规则可表示为:(X^{(i)<t>}, y^{(i)<t>}, T_x^{(i)}, T_y^{(i)})

      • 其中,(i) 表示第i个样本,不同样本的 (T_x^{(i)})(T_y^{(i)}) 都可能不同.

    3. Recurrent Neural Network Model

    对于序列模型,如果使用标准的神经网络,其模型结构如下:

    Problems:

    1. 不同样本的输入序列长度 或 输出序列长度不同,即 (T_x^{(i)} eq T_x^{(j)})(T_y^{(i)} eq T_y^{(j)}),,造成模型难以统一。

      • 解决:设定一个最大序列长度,对每个输入和输出序列 补零并统一到最大长度。但是这种做法实际效果并不理想。
    2. 标准神经网络结构无法共享序列不同 (x^{<t>}) 之间的特征。

      • 例如,如果某个 (x^{<t>}) 即“Harry”是人名成分,那么句子其它位置出现了“Harry”,也很可能也是人名。这是共享特征的结果。但是,上图所示的网络不具备共享特征的能力。

      • 共享特征还有助于减少神经网络中的参数数量,一定程度上减小了模型的计算复杂度。假设每个 (x^{<t>}) 扩展到最大序列长度为100,且词汇表长度为10000,则输入层就已经包含了100 x 10000个神经元了,权重参数很多,运算量将是庞大的。


    循环神经网络(RNN) 是专门用来 解决序列模型问题的。RNN模型结构如下:

    • 序列模型从左到右,依次传递,此例中,(T_x=T_y).

    • (x^{<t>})(hat y^{<t>}) 之间是隐藏神经元.

    • (a^{<t>}) 会传入到 (t+1) 个元素中,作为输入。 其中, (a^{<0>}) 一般为零向量.

    RNN模型包含三类权重系数

    • 分别是 (W_{ax}, W_{aa}, W_{ya})。且不同元素之间 同一位置 共享同一权重系数.

    RNN的正向传播(Forward Propagation)过程

    [a^{<t>}=g(W_{aa}cdot a^{<t-1>}+W_{ax}cdot x^{<t>}+b_a) \ hat y^{<t>}=g(W_{ya}cdot a^{<t>}+b_y) ]

    • 其中,(g(⋅))表示激活函数,不同的问题需要使用不同的激活函数。

    • 为了简化表达式,可以对 (a^{<t>}) 项进行整合:

    [W_{aa}cdot a^{<t-1>}+W_{ax}cdot x^{<t>}=[W_{aa} W_{ax}]left[ egin{matrix} a^{<t-1>} \ x^{<t>} end{matrix} ight] ightarrow W_a[a^{<t-1>},x^{<t>}] ]

    • 正向传播可表示为:

    [a^{<t>}=g(W_a[a^{<t-1>},x^{<t>}]+b_a) \ hat y^{<t>}=g(W_{y}cdot a^{<t>}+b_y) ]

    • 以上所述的RNN为单向RNN,即按照从左到右顺序,单向进行, (hat y^{<t>}) 只与左边的元素有关,但是,有时候 (hat y^{<t>}) 也可能与右边元素有关。

    • 例如下面两个句子中,单凭前三个单词,无法确定“Teddy”是否为人名,必须根据右边单词进行判断。

      • He said, “Teddy Roosevelt was a great President.”

      • He said, “Teddy bears are on sale!”

    • 还有一种RNN结构是双向RNN,简称为 BRNN(hat y^{<t>}) 与左右元素均有关系

    4. Backpropagation through time

    针对上面识别人名的例子,经过RNN正向传播,单个timestep的Loss function为:

    [L^{<t>}(hat y^{<t>},y^{<t>})=-y^{<t>}log hat y^{<t>}-(1-y^{<t>})log (1-hat y^{<t>}) ]

    该样本所有元素的Loss function为:

    [L(hat y,y)=sum_{t=1}^{T_y}L^{<t>}(hat y^{<t>},y^{<t>}) ]

    然后,反向传播(Backpropagation)过程就是从右到左分别计算 (L(hat y,y)) 对参数 (W_a ,W_y,b_a,b_y) 的偏导数.

    5. Different types of RNNs

    以上介绍的例子中,(T_x=T_y)。但是在很多RNN模型中,(T_x)是不等于(T_y)的。

    根据 (T_x)(T_y) 的关系,RNN模型包含以下几个类型

    • Many to many: (T_x=T_y)

    • Many to many: (T_x eq T_y)

    • Many to one: (T_x>1,T_y=1)

    • One to many: (T_x=1,T_y>1)

    • One to one: (T_x=1,T_y=1)

    不同类型相应的示例结构如下:

    6. Language model and sequence generation(语言模型和序列生成)

    语言模型是自然语言处理(NLP)中最基本和最重要的任务之一。使用RNN能够很好地建立 需要的不同语言风格的语言模型

    对语料库的每条语句进行RNN模型训练,最终得到的模型可以 根据给出语句的前几个单词 预测其余部分,将语句补充完整。

    • 例如,给出“Cats average 15”,RNN模型可能预测完整的语句是 “Cats average 15 hours of sleep a day.”。

    什么是语言模型呢?例,在语音识别中,某句语音有两种翻译:

    • The apple and pair salad.

    • The apple and pear salad.

    显然,第二句话更有可能是正确的翻译.

    • (P(The apple and pair salad) = 3.2 imes 10^{−13})

    • (P(The apple and pear salad) = 5.7 imes 10^{−10})选择概率最大的语句作为正确的翻译.


    RNN如何构建语言模型:

    • 首先,我们需要一个足够大的训练集,训练集由大量的单词语句语料库(corpus)构成.

    • 然后,对corpus的每句话进行切分词(tokenize)

    • 建立vocabulary,对每个单词进行one-hot编码。例如下面这句话:The Egyptian Mau is a bread of cat.

      • 注意,每句话结束末尾,需要加上< EOS >作为语句结束符。
    • 若语句中有词汇表中没有的单词,用< UNK >表示。假设单词“Mau”不在词汇表中,则上面这句话可表示为:

      • The Egyptian < UNK > is a bread of cat. < EOS >
    • 准备好训练集,并对语料库进行切分词等处理之后,接下来构建相应的RNN模型。

    • 语言模型的RNN结构如上图

      • (x^{<1>})(a^{<0>}) 均为零向量

      • softmax输出层 (hat y^{<1>}) 表示出现该语句 第一个单词的概率

      • softmax输出层 (hat y^{<2>}) 表示在第一个单词基础上出现第二个单词的概率,即条件概率,(P(y^{<2>}|y^{<1>}))

      • 以此类推,最后是出现< EOS >的条件概率。

    单个timestep的softmax loss function为:

    [L^{<t>}(hat y^{<t>},y^{<t>})=-sum_iy_i^{<t>}log hat y_i^{<t>} ]

    所有时序样本的Loss function为:

    [L(hat y,y)=sum_tL^{<t>}(hat y^{<t>},y^{<t>}) ]

    整个语句出现的概率 等于 语句中 所有元素出现的条件概率乘积

    • 例如,某个语句包含 (y^{<1>}, y^{<2>}, y^{<3>})

    • 则整个语句出现的概率为:

    [P(y^{<1>},y^{<2>},y^{<3>})=P(y^{<1>})cdot P(y^{<2>}|y^{<1>})cdot P(y^{<3>}|y^{<1>},y^{<2>}) ]

    7. Sampling novel sequences(新序列采样)

    利用训练好的RNN语言模型,可以进行新的序列采样,从而 随机产生新的语句

    相应的RNN模型如下所示:

    1. 首先,从第一个元素输出 (hat y^{<1>}) 的softmax分布中 随机选取一个word作为 新语句的首单词

    2. 然后,(y^{<1>}) 作为 (x^{<2>}),得到 (hat y^{<2>}) 的softmax分布。从中选取概率最大的word作为 (y^{<2>})

    3. 继续将 (y^{<2>}) 作为 (x^{<3>}),以此类推。直到产生< EOS >结束符,则标志语句生成完毕。

    4. 可以设定语句长度上限,达到长度上限即停止生成新的单词。

    5. 最终,根据随机选择的首单词,RNN模型会生成一条新的语句。

    6. 注: 如果不希望新的语句中包含< UNK >标志符,可以在每次产生< UNK >时重新采样,直到生成非< UNK >标志符为止。

    以上介绍的是word level RNN,即每次生成单个word,语句由多个word构成。


    character level RNN 是另一种情况,词汇表由 单个英文字母字符组成,如下所示:

    [Vocabulay=[a,b,c,cdots,z,.,;, ,0,1,cdots,9,A,B,cdots,Z] ]

    Character level RNN与word level RNN区别:

    • (hat y^{<t>}) 由单个字符组成而不是word.

    • 训练集中的每句话都当成是由许多字符组成的.

    • character level RNN的优点:能有效 避免遇到词汇表中不存在的单词< UNK >.

    • character level RNN的缺点:由于是字符表征,每句话的字符数量很大,这种大的跨度 不利于寻找语句前部分和后部分之间的依赖性.

      • character level RNN的在训练时的计算量庞大的。

      • character level RNN 应用不广泛,但在特定应用下仍然有发展的趋势。

    8. Vanisging gradients with RNNs(梯度消失)

    语句中可能存在跨度很大的依赖关系,即某个word可能与它距离较远的某个word具有强依赖关系。例:

    • The cat, which already ate fish, was full.

    • The cats, which already ate fish, were full.

    上面两句话的这种依赖关系,由于跨度很大,普通的RNN网络容易出现 梯度消失,捕捉不到它们之间的依赖,造成语法错误。

    RNN也可能出现梯度爆炸的问题,即gradient过大。解决办法是:设定一个阈值,一旦梯度最大值达到这个阈值,就对整个梯度向量进行尺度缩小。这种做法被称为 gradient clipping

    9. Gated Recurrent Unit(GRU)

    RNN的隐藏层单元结构如下图所示:

    • (a^{<t>}=tanh(W_a[a^{<t-1>},x^{<t>}]+b_a))

    为了解决梯度消失问题,对上述单元进行修改,添加了记忆单元


    GRU(simplified)

    相应的表达式为:

    [ ilde c^{<t>}=tanh(W_c[c^{<t-1>},x^{<t>}]+b_c) \ \ Gamma_u=sigma(W_u[c^{<t-1>},x^{<t>}]+b_u) \ \ c^{<t>}=Gamma* ilde c^{<t>}+(1-Gamma_u)*c^{<t-1>} ]

    其中:

    • (c^{<t-1>}=a^{<t-1>})(c^{<t>}=a^{<t>})

    • (Gamma_u) 为 gate,记忆单元。

      • (Gamma_u=1) 时,代表更新;

      • (Gamma_u=0) 时,代表记忆,保留之前的模块输出。

    • * 是 元素对应的乘积

    上面介绍的是简化的GRU模型.


    Full GRU

    • 添加了另外一个gate,即 (Gamma_r),表达式如下:

    [ ilde c^{<t>}=tanh(W_c[Gamma_r*c^{<t-1>},x^{<t>}]+b_c) \ \ Gamma_u=sigma(W_u[c^{<t-1>},x^{<t>}]+b_u) \ \ Gamma_r=sigma(W_r[c^{<t-1>},x^{<t>}]+b_r) \ \ c^{<t>}=Gamma* ilde c^{<t>}+(1-Gamma_u)*c^{<t-1>} \ \ a^{<t>}=c^{<t>} ]

    10. Long Short Term Memory(LSTM)

    LSTM是另一种更强大的解决梯度消失问题的方法。它对应的RNN隐藏层单元结构如下图所示:


    相应的表达式为:

    [ ilde c^{<t>}=tanh(W_c[a^{<t-1>},x^{<t>}]+b_c) \ \ Gamma_u=sigma(W_u[a^{<t-1>},x^{<t>}]+b_u) \ \ Gamma_f=sigma(W_f[a^{<t-1>},x^{<t>}]+b_f) \ \ Gamma_o=sigma(W_o[a^{<t-1>},x^{<t>}]+b_o) \ \ c^{<t>}=Gamma_u* ilde c^{<t>}+Gamma_f*c^{<t-1>} \ \ a^{<t>}=Gamma_o* tanh c^{<t>} \ ]

    LSTM包含三个gates:

    • (Gamma_u)update gate

    • (Gamma_f)forget gate

    • (Gamma_o)output gate

    如果考虑 (c^{<t-1>})(Gamma_u)(Gamma_f)(Gamma_o) 的影响,可加入peephole connection,对LSTM的表达式进行修改:

    [ ilde c^{<t>}=tanh(W_c[a^{<t-1>},x^{<t>}]+b_c) \ \ Gamma_u=sigma(W_u[a^{<t-1>},x^{<t>},c^{<t-1>}]+b_u) \ \ Gamma_f=sigma(W_f[a^{<t-1>},x^{<t>},c^{<t-1>}]+b_f) \ \ Gamma_o=sigma(W_o[a^{<t-1>},x^{<t>},c^{<t-1>}]+b_o) \ \ c^{<t>}=Gamma_u* ilde c^{<t>}+Gamma_f*c^{<t-1>} \ \ a^{<t>}=Gamma_o* tanh c^{<t>} ]

    GRU可以看成是简化的LSTM,两种方法都具有各自的优势。

    11. Bidirectional RNN(双向循环神经网络 BRNN)

    BRNN 对应的输出 (y^{<t>}) 表达式:

    [hat y^{<t>}=g(W_{y}[a^{ ightarrow <t>},a^{leftarrow <t>}]+b_y) ]

    BRNN 能够同时对序列进行双向处理,性能大大提高。但是计算量较大,且在处理实时语音时,需要等到完整的一句话结束时才能进行分析。

    12. Deep RNNs

    Deep RNNs由多层RNN组成,其结构如下图所示:

    与DNN一样,用上标 ([l]) 表示层数。Deep RNNs中 (a^{[l]<t>})的表达式为:

    [a^{[l]<t>}=g(W_a^{[l]}[a^{[l]<t-1>},a^{[l-1]<t>}]+b_a^{[l]}) ]

    DNN层数可达100多,而Deep RNNs一般没有那么多层,3层RNNs已经较复杂了。

    另一种Deep RNNs结构 是 每个输出层上还有一些垂直单元,如下图所示:

  • 相关阅读:
    MVC设计模式
    NET Core 1.0
    《Nginx文件类型错误解析漏洞--攻击演练》 (转)
    AngularJs 基础(60分钟入门) (转)
    每个线程分配一个stack,每个进程分配一个heap;heap没有结构,因此寻址慢(转)
    声明式编程和命令式编程的比较(转)
    Android SimpleAdapter的参数
    RelativeLayout相对布局
    Tomcat、Apache、IIS这三种Web服务器来讲述3种搭建JSP运行环境的方法
    GitHub已将持续集成服务器Janky开源
  • 原文地址:https://www.cnblogs.com/douzujun/p/13162263.html
Copyright © 2020-2023  润新知