一、前言
1、图解RNN
二、实战
1、训练数据处理
(1)文字转为向量
def _get_poetry(self):
with open(self.poetry_file, "r", encoding='utf-8') as f:
poetry_list = [line for line in f]
return poetry_list
def _gen_poetry_vectors(self):
words = sorted(set(''.join(self.poetry_list)+' '))
# 每一个字符分配一个索引 为后续诗词向量化做准备
int_to_word = {i: word for i, word in enumerate(words)}
word_to_int = {v: k for k, v in int_to_word.items()}
to_int = lambda word: word_to_int.get(word)
poetry_vectors = [list(map(to_int, poetry)) for poetry in self.poetry_list]
return poetry_vectors, word_to_int, int_to_word
在这里将训练数据中所有的字生成了一个"文字==>数字"的词袋,并将所有的诗词按行分割转化为数字表示。
(2)生成器
def batch(self):
# 生成器
start = 0
end = self.batch_size
for _ in range(self.chunk_size):
batches = self.poetry_vectors[start:end]
# 输入数据 按每块数据中诗句最大长度初始化数组,缺失数据补全
x_batch = np.full((self.batch_size, max(map(len, batches))), self.word_to_int[' '], np.int32)
for row in range(self.batch_size): x_batch[row, :len(batches[row])] = batches[row]
# 标签数据 根据上一个字符预测下一个字符 所以这里y_batch数据应为x_batch数据向后移一位
y_batch = np.copy(x_batch)
y_batch[:, :-1], y_batch[:, -1] = x_batch[:, 1:], x_batch[:, 0]
yield x_batch, y_batch
start += self.batch_size
end += self.batch_size
x_batch作为输入,y_batch为标签。诗词生成模型根据上一个字符生成下一个字符,所以这里的标签数据应该是和输入数据的shape一致,但序列字符后移一位。y_batch的最后一位,理论上来说应该是本行诗词的下一行的第一个字,简单起见,这里用本行的第一个字代替。
2