内容概要
本周课程主要介绍以下四个方面的内容:
序列模型简介
循环神经网络
语言模型和序列生成
1. 序列模型简介
自然语言,语音和视频等具有天然的序列属性,因此基于深度学习的序列模型在以上各个领域应用非常广泛。
Andrew 以命名实体识别 (Named Entity Recognition,NER) 为例介绍了序列数据的表示形式。对于 NER 来说,就是为序列打标签 (Sequence labeling) 的过程,通常使用 IOBES 表示,课程中为了简单起见只用 I 和 O 表示一个字符属不属于实体。现阶段基于Bidirectional LSTM + CRF是 NER 的标准解决方案,具体代码实现可参考 [1]。
NER 属于自然语言处理 (Natural Language Processing, NLP) 的经典问题之一。说到 NLP,第一个需要解决的问题是如何表示每个单词。这时候需要一个词表 Vocabulary 或字典 Dictionary,存储的单词基于语料的词频大小或者字母表顺序排序。词表大小通常为 3w 或 5w, 10w 甚至百万。有了单词,接下来使用one-hot向量表示每个单词。额外的,通常使用表示词表外的单词,
表示 padding 字符,表示句子的结尾。
值得注意的是,one-hot 表示方法是sparse的,两个单词的 one-hot 向量内积为零,无法表示其相似性,因此word2vec或者glove提出使用dense的向量表示每个单词,词向量也成为了深度学习模型的第一步输入。词向量的具体内容将在下周课程中介绍。
1.1 序列建模
如何对序列进行建模呢?可以首先尝试使用普通的神经网络对序列建模,将每个单词当作一个 feature 处理,但是这样有两个问题:
第一个问题是输入和输出序列长度一般是变化的,因此输入特征是变化的,导致不方便建模。虽然可以 padding 到同一最大长度,此时模型的参数量也是巨大的。
第二个问题是在某个位置学到的特征不能应用到其他位置上。这是由于在普通神经网络中不同神经元之间没有 “交集”,没有考虑序列具有的顺序 (order) 特性。卷积神经网络 (Convolution Neural Networks, CNNs) 的一大特点是权值共享:在图片不同位置可以同时检测出同样的特征。可以使用循环神经网络 (Recurrent Neural Networks, RNNs) 将权值共享策略应用到序列上,并解决序列变化长度问题。
2.循环神经网络
2.1 基本概念
RNNs 从左到右依次扫描序列的每个单词,每一步称作一个 time step。
数学公式表示为:
注意:
[1] 隐藏状态 a^ 的初始值通常为零向量。
[2] tanh是RNNs通常选用的激活函数。
[3]扫描过程中的参数是共享的,即 W_aa, W_ax, W_ya 在每一个 time step 都是一样的。
[4] 使用 Backpropagation through time (BPTT) 进行模型训练。与具有较多隐藏层的普通神经网络一样,普通的 RNNs 通常会遇到梯度消失 (Vanishing gradients)和梯度爆炸 (Exploding gradients) 的问题。梯度爆炸的表现是数值溢出导致的 NaN 问题。梯度消失问题导致无法捕捉长距离依赖。梯度裁剪 (Gradients clipping) 可以有效解决梯度爆炸问题。通过 Xavier/He 初始化和 GRU/LSTM 模型等可以有效解决梯度消失问题。
2.2 网络结构类型
RNNs 具有不同的结构类型:
语音识别,机器翻译,NER 等都属于 many-to-many 结构,但是只有 NER 的输入和输出序列长度是相同的,机器翻译更属于 seq2seq 框架的范畴;文本分类/情感分析属于 many-to-one;音乐生成,文本生成属于 one-to-many。
2.3 GRU, LSTM, Bidirectional RNNs, Deep RNNs
关于 LSTM 和 GRU,网上的资源非常多,最出名的当属 colah 的Understanding LSTM Networks[2],还可以参考我以前写的 RNNs 用于文本分类的文章1和文章2.
使用一个 RNNs 从左到右扫描只考虑了前面的单词,也可以使用另外一个RNNs 从右往左扫描,将两个 RNNs 的结果合并,这就是双向RNNs (Bidirectional RNNs).
与 Deep NN 一样,可以在一层 RNNs 上再加一层 RNNs,形成 Deep RNNs 的网络结构,但是与 CNNs 不同,Deep RNNs 的层数不深。
目前,在深度学习领域,双向 LSTM 是最广泛使用的模型,最多使用三层网络叠加即可。
3.语言模型和序列生成
语言模型能够预测一句话的概率,即:
语言模型的构建是 NLP 的基础工作之一,RNNs 可以很好地胜任这个工作。语言模型在语音识别和机器翻译等领域扮演着重要的角色。值得一提的是,在深度学习之前人们使用基于统计的n-gram模型创建语言模型。
建立语言模型首先需要一个包含大量文本的语料,然后 tokenize (对于中文来说要进行中文分词),构建词表,将文本转换为对应的数字 (词表中的位置),不在词典中的词记为 ,在句尾加上 标志 (PS: 个人觉得在句头加上 更好)。构建词表时,可以考虑也可以不考虑标点符号。
RNNs 语言模型的训练是基于当前词预测下一个词,损失函数是交叉熵损失。
RNNs 语言模型构建好之后可以用于序列生成,每次生成的词作为下一个 step 的输入,进而产生下一个 step 的输出,依次往复。当生成出 或者固定长度的序列时即可判断一段序列生成完毕。序列生成过程中可能会产生 ,此时丢弃该词重新生成新词即可。
3.1 Word-level 和 Character-level 比较
对于英文来说,除了基于每个单词 (Word-level) 构建语言模型外,还可以基于每个字符 (Character-level) 构建语言模型。若构建基于字符的语言模型,其词表比较小,通常包括如 [a, b, c, ..., z; 0, 1, ..., 9; ,, ., !, ...; A, B, C, ..., Z]
基于字符的语言模型的优点是不会生成 单词;缺点是需要更长时间去训练 (由于生成同样的序列,基于字符的 RNNs 语言模型需要更多的 time step 去预测),因此基于单词的 RNNs 语言模型能获取更长的依赖。
目前,基于单词的模型用的更多,但是当有特别多的专有名词或者 UNK 时需要使用基于字符的模型。
文献 [3]基于 char-rnn 和 tensorflow 生成周杰伦歌词,给出了基于中文单个字的序列生成例子。
参考文献
[1] https://github.com/gaoisbest/NLP-Projects/tree/master/Sequence%20labeling%20-%20NER
[2] http://colah.github.io/posts/2015-08-Understanding-LSTMs/
[3]https://github.com/leido/char-rnn-cn
2017 年我们坚持共同学习了 Andrew ng 深度学习工程师课,cs231n,cs224n 和李宏毅机器学习课,3 月 5 号我们继续共同讨论学习啦。为了更好的讨论学习,创造一个良好的学习环境,我们这次更新了学习方式,具体请参考文章。感兴趣想一起共同学习的同学请加群,我们会以共同学习的形式坚持下去。
领取专属 10元无门槛券
私享最新 技术干货