• [吴恩达深度学习课程笔记13]序列模型-循环序列模型


    05. 序列模型

    第一周 循环序列模型

    1.1 序列数据

    有大量的任务处理的都是序列数据,所以我们需要一个序列模型。(按吴恩达老是这么说,我做的视频任务应该也是序列数据)

    1.2 符号表示

    以自然语言处理(NLP)任务为例,一个句子记为一个样本( x^{(i)} ),句子中的每个词记为( x^{(i)<t>} ),句子的长度记为( T_x^{(i)} )。

    怎么表示句子中的单词呢?首先我们要有一个词典,例如10000词,然后用one-hot形式表示一个单词出现在词典中的位置,所以一个单词可以用一个10000维的向量来表示,这个向量中只有一个非零元素1.

    1.3 & 1.4 循环神经网络模型

    不采用标准神经网络处理文本的原因:输入和输出的长度都不确定(其实可以填充到最大长度);在文本不同位置学习到的特征并不共享(重复的词)。

    循环神经网络(recurrent neural network, RNN)的结构如下:

    在处理文本时,每个时间步的输出不仅取决于当前时刻的词,还要利用前一时刻激活值。这也是循环神经网络的缺点,只能利用之前时刻的信息,看不到之后的信息。

    前向传播的计算过程:

    ( a^{<0>} = 0 )

    ( a^{<t>} = g_1(W_{aa}a^{<t-1>} + W_{ax}x^{<t>} + b_a) )

    ( hat{y}^{<t>} = g_2(W_{ya}a^{<t>} + b_y) )

    RNN中常用tanh作为激活函数,其中( g_1, g_2 )可以不一样,(g_2)的选择要依赖于输出形式,可能是sigmoid或者softmax.

    借助于矩阵运算的话,上述的算式可以简化为:

    ( a^{<t>} = g_1(W_{a} egin{bmatrix}a^{<t-1>} \ x^{<t>} end{bmatrix} + b_a) )

    ( hat{y}^{<t>} = g_2(W_{y}a^{<t>} + b_y) )

    ( W_a = [W_{aa} vdots W_{ax}] )

    定义单步的损失函数:( L^{<t>} (hat{y}^{<t>}, y^{<t>}) = - y^{<t>} log (hat{y}^{<t>}) - (1 - y^{<t>}) log (1 - hat{y}^{<t>}) )

    整体的代价函数:( egin{gathered} L(hat{y}, y) = sum_{t = 1}^{T_x}L^{<t>}(hat{y}^{<t>},y^{<t>}) end{gathered})

    完整的前向传播和反向传播流程:

    注意每个时间步的 ( a^{<t>} ),都要传给下个时间步,而网络参数其实只有一套,所以是有一个循环结构的,只不过这里按时间展开了。

    反向传播则是按照相反的方向进行。

    1.5 不同类型的循环神经网络

    前面讲的RNN处理的是输入和输出长度相同的任务,对于不同的输入和输出长度有各种网络结构:

    一对多:比如音乐生成;多对一:比如评论打分;多对多:机器翻译(输入和输出长度可能不同)。

    1.6 & 1.7 语言模型

    语言模型就是对于文本完整性或者正确性的理解,比如能够判断 "The apple and pair salad." 和 "The apple and pear salad." 两个句子的出现的概率哪个更高。

    我们可以用RNN对文本进行建模,当输入一段文本时,模型能够给出每个词的概率,从而能够得到整个句子的概率。这其中包含很多工作:

    • 要有一个用于训练的语料库(corpus),里面全是文本;
    • 利用词典将文本转化为词向量,可能需要标记句子的结尾(EOS),以及词典中不存在的词(UNK);

    具体的步骤:

    第一个时间步,输入( x^{<1>} = 0, a^{<0>} = 0 ),输出softmax的结果表示文本第一个词可能为某一个词的概率,比如10002个概率(词典加特殊符号)。

    第二个时间步,我们会告诉模型第一个词是什么,即( x^{<2>} = y^{<1>} ),让它预测第二个词某个词的概率,依此类推。

    最后整个文本的概率( P(y^{<1>}, P^{<2>}, P^{<3>}) = P(y^{<1>})P(y^{<2>}|y^{<1>})P(y^{<3>}|y^{<1>}, y^{<2>}) )

    注意,在上面介绍的语言模型中,第一个时间步我们得到了词典中各种词的概率分布,可以自己选择一些词作为第二个时间步的输入,然后再对第二个时间步的输出进行采样作为第三个时间步的输出,以此类推,生成一个文本序列,这就得到了一个采样序列,通过这种方法我们可以用语言模型生成一段文本。

    采样序列的结束可以是遇到EOS,也可以是固定长度。同时还要避免句子中出现不确定单词UNK。

    这是基于单词的语言模型,还有基于字符的语言模型,在生成的时候需要一个字符一个字符的生成,比如a,p,p,l,e等,这种模型不用担心UNK,但是很难捕捉较长的语义,而且训练更加耗费资源。

    1.8 RNN的梯度消失

    我们知道神经网络越深越难训练,而且会出现梯度爆炸和梯度消失的问题,其中梯度消失是相对更难的问题。

    RNN也有同样的问题,它无法捕捉长期依赖(long-term dependency),例如一个很长的句子:

    The cat, which ..., ate ..., was full. 如果要模型能够根据之前的主语选择was/were就要解决这种长期依赖问题。

    1.9 GRU

    为了解决梯度消失的问题,引入记忆单元( c^{<t>} )和其候选值(  ilde{c}^{<t>} )。

    记忆单元相当于之前的( a^{<t>} ),不过通过一些门控机制来控制更新。这里的门控(gate)指的是一组介于0~1之间的数,观察下面记忆单元的更新公式,发现候选值和旧的记忆正是通过门控( Gamma_u )来组合形成新的记忆,比如之前的例子中,cat可能会被一直保留在记忆中,能够正确输出was.

    完整的GRU公式:

    ( Gamma_u = sigma left( W_u  egin{bmatrix}c^{<t-1>} \ x^{<t>} end{bmatrix} + b_u ight) )

    ( Gamma_r =  sigma left( W_r  egin{bmatrix}c^{<t-1>} \ x^{<t>} end{bmatrix} + b_r ight) )

    ( ilde{c}^{<t>} = tanh(W_c  egin{bmatrix}Gamma_r * c^{<t-1>} \ x^{<t>} end{bmatrix} + b_c) )

    ( c^{<t>} = Gamma_u * ilde{c}^{<t>} + (1 - Gamma_u) * c^{<t-1>} )

    *表示元素乘积,另一个门控( Gamma_r )表示对候选值的控制,这个其实是经验之选。其中( c^{<t>} )保持不断更新,而网络的输出( ilde{y}^{<t>} )则是基于( c^{<t>} )增加softmax层或者其它层得到的。

    1.10 LSTM

    LSTM和GRU很相似(其实是先有的LSTM),完整公式如下:

    ( Gamma_u = sigma left( W_u  egin{bmatrix}a^{<t-1>} \ x^{<t>} end{bmatrix} + b_u ight) )

    ( Gamma_f =  sigma left( W_f  egin{bmatrix}a^{<t-1>} \ x^{<t>} end{bmatrix} + b_f ight) )

    ( Gamma_o = sigma left( W_o  egin{bmatrix}a^{<t-1>} \ x^{<t>} end{bmatrix} + b_o ight) )

    ( ilde{c}^{<t>} = tanh(W_c  egin{bmatrix}Gamma_r * c^{<t-1>} \ x^{<t>} end{bmatrix} + b_c) )

    ( c^{<t>} = Gamma_u * ilde{c}^{<t>} + Gamma_f * c^{<t-1>} )

    ( a^{<t>} = Gamma_o * c^{<t>} )

    注意一些不同点:

    • 区分 ( a^{<t>}, c^{<t>} );
    • 使用两个门控 ( Gamma_u, Gamma_f ) 来控制 ( c^{<t>} ) 的更新。

    从整个时序上去看:

    横贯多个时间步的那条线就是确保模型捕获长期依赖的关键。

    LSTM比GRU更有效,门控更多,更复杂;GRU比较简单,可以构建更大的网络。大家的首选还是LSTM。

    1.11 双向神经网络

    前面讲RNN还有一个问题就是只能利用之前的信息,有些句子如果只看前面的话很难去理解,这时候可以采用双向的结构:

    有了前面的标准RNN/GRU/LSTM结构,不仅从前往后计算一遍( overrightarrow{a}^{<t>} ),还要从后往前计算一遍( overleftarrow{a}^{<t>} ),最后网络的输出变成:

    ( hat{y}^{<t>} = g(W_y egin{bmatrix}overrightarrow{a}^{<t>} \ overleftarrow{a}^{<t>} end{bmatrix} + b_y) )

    有个要求:你需要完整的文本才可以。

    1.12 深层循环神经网络

    前面已经说过了,图中横着那一长串其实不是我们以往理解的那种“深层”,真正的深层网络如下:

    对于RNN来说,这样叠加三层已经够用了,由于时间维度上可能很长,所以网络的规模可能很大。

    基本单元不一定是RNN,可以换成GRU,LSTM甚至构建双向网络。

    另一种常见的结构是在上面每个时间步的后面加一个比较深的网络,但是这些深层网络没有时间维度上的连接。

  • 相关阅读:
    python的进阶--爬虫小试
    【centos 7】搭FTP服务和web访问
    centos 7 安装python3.5
    centos 6.5 安装mysql 5.6.35--libc.so.6(GLIBC_2.14)(64bit)
    windows 10 下安装python 2.7
    centos7-硬盘坏道检测
    centos7 默认进入系统命令行模式修改
    zabbix安装配置(2.4.5)
    Centos 7 mysql 安装使用记
    docker部署angular和asp.net core组成的前后端分离项目
  • 原文地址:https://www.cnblogs.com/tofengz/p/12257685.html
Copyright © 2020-2023  润新知