Tensorflow RNN官方文档全面解析,附带修改后代码

官方文本解析以及调试

官方RNN链接:https://www.tensorflow.org/tutorials/text/text_generation

数据集来自莎士比亚作品集,资源链接:https://storage.googleapis.com/download.tensorflow.org/data/shakespeare.txt

基本配置环境:
Python3,Tensorflow, Keras。

库文件:

from __future__ import absolute_import, division, print_function, unicode_literals
import tensorflow as tf
import numpy as np
import os
import time

下载数据集并读取:

path_to_file = tf.keras.utils.get_file('shakespeare.txt', 'https://storage.googleapis.com/download.tensorflow.org/data/shakespeare.txt')
# Read, then decode for py2 compat.
text = open(path_to_file, 'rb').read().decode(encoding='utf-8')
# length of text is the number of characters in it
print ('Length of text: {} characters'.format(len(text)))
# Take a look at the first 250 characters in text
print(text[:250])
# The unique characters in the file
vocab = sorted(set(text))
print ('{} unique characters'.format(len(vocab)))

由于数据集下载地址为https协议,官方文档这里会报错,
在这里插入图片描述
修改如下,在库文件添加ssl协议,并选择关闭

from __future__ import absolute_import, division, print_function, unicode_literals
import tensorflow as tf
import ssl
import numpy as np
import os
import time
ssl._create_default_https_context = ssl._create_unverified_context
path_to_file = tf.keras.utils.get_file('shakespeare.txt', 'https://storage.googleapis.com/download.tensorflow.org/data/shakespeare.txt')

下载成功!
在这里插入图片描述
通常对于NLP文本测试来说,会首先删除文本中的特殊字符以及数字等等,
在官方文档中给出了一种不常使用的方法,这种方法可以有效转换特殊字符和文本中的关系,但是不适用于数据量较大的文本处理,并且一般不用。
官方给出的方法首先会创建两个检索表,即把字符映射到数字,把数字映射到字符。
处理过程中以全数字进行处理,,之后再用查找表还原。

#vocab中是已经处理过的数据并排序,其中set是将单词转化为字母表示,sorted是将set中的集合排序。
vocab = sorted(set(text))
#创建了char2idx字符到索引映射以及idx2char索引到字符的映射集
#Creating a mapping from unique characters to indices
char2idx = {u:i for i, u in enumerate(vocab)}
idx2char = np.array(vocab)
text_as_int = np.array([char2idx[c] for c in text])

首先来看看vocab中的东西是什么
在这里插入图片描述
我们可以从输出来看这种处理方法的问题,首先有可能破坏词与词之间的关系,但是语序关系会随之加强。
转化后的char2idx是以数字为表示,而idx2char只是矩阵化了字符形式。
在这里插入图片描述
接着我们来看官方文档中的预测任务。
在官方文本中,首先给出了一个预测任务,即输入一个字符序列后,训练模型以预测输出的每个时间步长后面的字符。
在各个过程中,由于RNN存在一个内部状态,这个状态取决于前置属性,后来的每个输出都需要结合每一个前置输入的属性进行预测。
为了能够实现这个RNN状态,首先需要创建一个训练模型

  1. 这个训练模型首先包含了所有文本,将所有文本都转化为序列,例如上面的索引模型
  2. 每个输入序列都会产生一个向右移动的偏置量,这个偏置的生成字符会作为目标文本对预测结果进行修正和判断。
  3. 例如限定一个长度为4的目标序列,以hallow为输入文本。在第一个阶段首先输入的是hall,与此同时产生一个向右偏移的序列“ello”,再通过RNN训练后产生一个结果,这个结果会与偏移序列比较并修正。在第二个阶段开始后,输入了ello的同时,会产生第二个偏移序列“llow”,并且在第二阶段的学习过程中会提取前面所有阶段的中间信息,可以称之为RNN的中间状态。
    在官方给出的RNN模型我们可以看出,对于输入文本的语序分析来说,普通的RNN模型往往只是能够分析前置的规律,并不能提取出从后往前的特性,对于这一点会在以后的RNN-LSTM以及SEQ2SEQ模型中得到优化,这部分以后有缘再说。

好了,接下来我们来看看RNN如何阅读莎士比亚作品集并写出一段相似的文章。

# The maximum length sentence we want for a single input in characters
seq_length = 100
examples_per_epoch = len(text)//(seq_length+1)

# Create training examples / targets
char_dataset = tf.data.Dataset.from_tensor_slices(text_as_int)

for i in char_dataset.take(5):
  print(idx2char[i.numpy()])
sequences = char_dataset.batch(seq_length+1, drop_remainder=True)

for item in sequences.take(5):
  print(repr(''.join(idx2char[item.numpy()])))


def split_input_target(chunk):
    input_text = chunk[:-1]
    target_text = chunk[1:]
    return input_text, target_text

dataset = sequences.map(split_input_target)

for input_example, target_example in  dataset.take(1):
  print ('Input data: ', repr(''.join(idx2char[input_example.numpy()])))
  print ('Target data:', repr(''.join(idx2char[target_example.numpy()])))


for i, (input_idx, target_idx) in enumerate(zip(input_example[:5], target_example[:5])):
    print("Step {:4d}".format(i))
    print("  input: {} ({:s})".format(input_idx, repr(idx2char[input_idx])))
    print("  expected output: {} ({:s})".format(target_idx, repr(idx2char[target_idx])))
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章