RNN的类别:
循环神经网络主要应用于序列数据的处理,因输入与输出数据之间有时间上的关联性,所以在常规神经网络的基础上,加上了时间维度上的关联性,也就是有了循环神经网络。因此对于循环神经网络而言,它能够记录很长时间的历史信息,即使在某一时刻有相同的输入,但由于历史信息不同,也会得到不同的输出,这也是循环神经网络相比于常规网络的不同之处。
根据输入与输出之间的对应关系,可以将循环神经网络分为以下五大类别:
常规网络中的输入与输出大多是向量与向量之间的关联,不考虑时间上的联系,而在循环神经网络中,输入与输出之间大多是序列与序列(Sequence-to-Sequence.)之间的联系,也就产生了多种模式。
- 一对一(one to one):最为简单的反向传播网络
- 一对多(one to many):可用于图像捕捉(image captioning),将图像转换为文字
- 多对一(many to one):常用于情感分析(sentiment analysis),将一句话中归为具体的情感类别。
- 多对多( many to many):常用于输入输出序列长度不确定时,例如机器翻译(machine translate),实质是两个神经网络的叠加。
- 不确定长度的多对多(many to many)(最右方):常用于语音识别(speech recognition)中,输入与输出序列等长。
文本生成原理:
本章节的文本生成(text generation)示例基于char RNN,也就是说循环神经网络的输入为一个字一个字的序列,输出为与输入等长的字序列,属于上述中的等长的多对多的结构。
基于字符集的文本生成原理可以这样简单理解:
(1)将一个长文本序列依次输入到循环神经网络
(2)对于给定前缀序列的序列数据,对序列中将要出现的下一个字符的概率分布建立模型
(3)这样就可以每次产生一个新的字符
如下图所示,我们想要从给定序列‘hell’中生成‘hello’。每次输入到循环神经网络中一个字符,并计算其概率分布。所以每个字符的出现概率分布都是基于前面历史序列得到的,如第二个‘l’的概率是通过历史信息‘hel’得出。在输出层可以通过最大似然或者条件随机场等规则选择结果。
再经过不断的迭代和优化训练出文本生成的模型。
古诗生成:
在本示例中,将会通过3000多首的唐诗,利用LSTM网络训练一个古诗生成的模型。
代码解读:
网络逻辑图如下:
1、数据处理
自然语言处理中,数据预处理的很多过程是共通的,都是要将文本数据进行编码,变为机器可以识别的词向量或者字向量,比如Word2Vec,one-hot编码等方法。
本次数据预处理步骤如下:
(1)读取古诗数据集,在每首诗的末尾加‘]’,并去除古诗名字只取古诗内容,最后得到一个长文本
with open('poetry.txt', 'r') as f:
files_content = ''
lines = [x for x in f]
for line in lines[:10]:
files_content += (line.strip() + "]").split(":")[-1]
(2)统计每个字出现的频率,并去除出现频率较低的字。一般来说如果数据集较小可以不去除。
# 统计每个字符出现的概率
words = sorted(list(files_content))
counted_words = {
}
for word in words:
if word in counted_words:
counted_words[word] += 1
else:
counted_words[word] = 1
# 去除出现概率较小的字符。此处设置为2
word_delet = []
for key in counted_words:
if counted_words[key] <= 2:
word_delet.append(key