正文
with open(os.path.join("dataset", name), "r") as f:
content += f.read() + "\n"
# Convert the string into a list of interger
vocab = set(content)
vocab_to_int = {c: i for i, c in enumerate(vocab)}
int_to_vocab = dict(enumerate(vocab))
encoded = np.array([vocab_to_int[c] for c in content], dtype=np.int32)
这里,需要记住的三个重要变量是:vocab_to_int、int_to_vocab和encoded。前两个变量是让我们能够在字符和整数间随意转换。最后的变量是用编码器的形式来表示所有数据。(均已转换为数字)
第一个批函数
首先创建一个简单的批处理:由两个输入序列构成,每个序列10个数字。这一批处理将作为下文字符处理的一个示例。
batch = {
"x" : [
encoded[:10],
encoded[20:30]
],
"y" : [
encoded[1:11],
encoded[21:31]
]
}
Batch Inputs :
[20 6 58 27 6 27 97 86 56 49]
[ 36 32 32 37 27 12 94 60 89 101]
Batch Targets :
[ 6 58 27 6 27 97 86 56 49 57]
[ 32 32 37 27 12 94 60 89 101 77]
这就是批函数所处理的内容,翻译成字符如下:
['/', '*', '\n', ' ', '*', ' ', 'C', 'o', 'p', 'y']
['2', '0', '0', '4', ' ', 'E', 'v', 'g', 'e', 'n']
现在,我们需要来处理一些数值。我们希望神经网络能够在上一个字符"n"已知的条件下预测出下一个字符。而且,不只是上一个字符。如果我告诉神经网络上一个字符是“e” ,下一个字符的可能性空间会非常大。但如果我能告诉神经网络前几个字符分别是 “w” 、“h”、 “i” 、“l” 和 “e” ,下一个要输入的字符很显然就是“(“。
因此,我们必须构建一个能够考虑字符时间间隔的神经网络。这就是递归神经网络。
递归神经网络?
为说明上述实例,我们用一个典型的分类器(上图左侧)来处理上一个字符;它被传递出蓝色的隐含层后,分类器就能推断出结果。递归神经网络在结构上则不同。每个红色的隐含层“细胞”不仅与输入相连,还与前一个“细胞”(instant t-1)相连。为了解决这里的问题,我们的“细胞”内部使用长短期记忆(LSTM)网络。
请花点时间来理解递归神经网络的原理,这样才能充分理解接下来的代码。
构建模型