《深度学习进阶:自然语言处理》啃书系列
第2章 自然语言和单词的分布式表示
第3章 word2vec
第4章 word2vec的高速化
第5章 RNN
第6章 Gated RNN
第7章 基于RNN生成文本
第8章 Attention
本章将使用语言模型进行文本生成。通过组合两个RNN,实现seq2seq(sequence to sequence,从时序到时序)神经网络。
第6章 Gate RNN(LSTM)讲了使用LSTM的语言模型。
例如,我们将LSTMLM在语料库“you say goobye and i say hello.”进行训练之后,我们将“i”作为文本生成的第一且唯一的提示词,此时模型会输出上图左上角的概率分布,我们将概率最大的单词“say”作为下一个时刻的输入,随即生成上图右上角的概率分布,可见概率最大的单词为"hello"。由此循环往复,便可生成指定长度或者指定字符结尾的文本。
每个时刻生成的概率分布,我们可以选择概率最大的单词最为下个时刻的输入,这样对于指定的语言模型,会生成相同的文本。也可以按照概率分布进行抽样,概率大的单词被选中的可能性大,概率小的单词被选中的可能性小,但是都有可能被选中作为下一时刻的输入,这样语言模型就会生成多种多样的文本。
略。(好在不是习题集后的答案 )
略。
进入正题。seq2seq天然就是为了解决上面的问题而生的:根据给定的文本,生成另一段文本。
世界上充斥着序列数据,文本就是有序的序列数据。
seq2seq可以使用多种方式实现。下面介绍使用两个RNN实现的方式。
seq2seq模型也称为Encoder-Decoder模型,有两个模块——Encoder(编码器)和 Decoder(解码器)。简单理解,编码器就是将人能看懂的内容转化为人看不懂的、机器才能读懂的信息,解码器就是将人看不懂的信息翻译为人能看懂的信息。前面说的one-hot编码就是编码方式中的一种,将one-hot与词库对应解析编码对应的字符,就是解码。
下面说明seq2seq中的编码器和解码器是如何工作的。翻译是一个典型的seq2seq场景。
编码器首先对原文进行编码,然后将编码好的信息传递给解码器,由解码器生成目标文本。此时,编码器编码的信息浓缩了翻译所必需的信息,解码器基于这个浓缩的信息生成目标文本。
如果将上一章介绍的LSTM引入作为编码器和解码器,结构如下:
编码器利用RNN将时序数据转换为隐藏状态 h h h,不管原文句子有多长,最终都是转化为相同长度的向量。
而解码器的结构和上一节的神经网络完全相同,额外的不同在于网络会接收隐藏向量 h h h。不过也可以说是上一节的网络接收的是0向量。隐藏状态是两个网络正向传播和反向传播的桥梁。
另外,上面的seq2seq使用了特殊符作为文本的起始和结束符号,也可以使用别的符号。
左边的输入按照字符级进行序列拆分,左边最大长度7,右边最大长度4。
左右的输入都是长度可变的,但是为了实现mini-batch,输入输出数据需要在一个batch内保持长度一致。所以在一个batch内,超出长度的输入需要截断,长度不足的需要补充。
在输出的开始处加上了分隔符“_”(下划线),使得输出数据的字符数统一为5。简单起见,这里我们不使用表示字符输出结束的分隔符,始终输出固定数量的字符。
略
略
据研究,在许多情况下,使用这个技巧后,学习进展得更快,最终的精度也有提高。
虽然理论上不是很清楚,但是直观上可以认为,因为通过反转,输入语句的开始部分和对应的转换后的单词之间的距离变近,所以梯度的传播变得更容易,学习效率也更高。
解码器从编码器获取的唯一信息是最后的隐藏状态 h h h,且解码器只有在开始时刻使用了 h h h。
将 h h h分配给解码器的其他层,能有效提升效果,这种方法称为偷窥(Peeky)。如下所示:
有两个向量同时被输入到了LSTM层和Affine层,这实际上表示两个向量的拼接(concatenate)。
加上了Peeky的seq2seq的结果大幅变好。
略
略