目前循环神经网络(RNN)已经广泛用于自然语言处理中,可以处理大量的序列数据,可以说是最强大的神经网络模型之一。人们已经给 RNN 找到了越来越多的事情做,比如画画和写诗,微软的小冰都已经出版了一本诗集了。
而其实训练一个能写诗的神经网络并不难,下面我们就介绍如何简单快捷地建立一个会写诗的网络模型。
![v2-78bcb7510b445d696efe86c44686ad00_b.jpg](https://i-blog.csdnimg.cn/blog_migrate/a9b689b27532d923e251721ba6672c3e.jpeg)
本次开发环境如下:
- Python 3.6
- Keras 环境
- Jupyter Notebook
整个过程分为以下步骤完成:
- 语料准备
- 语料预处理
- 模型参数配置
- 构建模型
- 训练模型
- 模型作诗
- 绘制模型网络结构图
下面一步步来构建和训练一个会写诗的模型。
第一,语料准备。一共四万多首古诗,每行一首诗,标题在预处理的时候已经去掉了。
第二,文件预处理。首先,机器并不懂每个中文汉字代表的是什么,所以要将文字转换为机器能理解的形式,这里我们采用 One-Hot 的形式,这样诗句中的每个字都能用向量来表示,下面定义函数 preprocess_file()
来处理。
puncs = [']', '[', '(', ')', '{', '}', ':', '《', '》']
def preprocess_file(Config):
# 语料文本内容
files_content = ''
with open(Config.poetry_file, 'r', encoding='utf-8') as f:
for line in f:
# 每行的末尾加上"]"符号代表一首诗结束
for char in puncs:
line = line.replace(char, "")
files_content += line.strip() + "]"
words = sorted(list(files_content))
words.remove(']')
counted_words = {}
for word in words:
if word in counted_words:
counted_words[word] += 1
else:
counted_words[word] = 1
# 去掉低频的字
erase = []
for key in counted_words:
if counted_words[key] <= 2:
erase.append(key)
for key in erase:
del counted_words[key]
del counted_words[']']
wordPairs = sorted(counted_words.items(), key=lambda x: -x[1])
words, _ = zip(*wordPairs)
# word到id的映射
word2num = dict((c, i + 1) for i, c in enumerate(words))
num2word = dict((i, c) for i, c in enumerate(words))
word2numF = lambda x: word2num.get(x, 0)
return word2numF, num2word, words, files_content
在每行末尾加上 ] 符号是为了标识这首诗已经结束了。我们给模型学习的方法是,给定前六个字,生成第七个字,所以在后面生成训练数据的时候,会以6的跨度,1的步长截取文字,生成语料。如果出现了 ] 符号,说明 ] 符号之前的语句和之后的语句是两首诗里面的内容,两首诗之间是没有关联关系的,所以我们后面会舍弃掉包含 ] 符号的训练数据。
第三,模型参数配置。预先定义模型参数和加载语料以及模型保存名称,通过类 Config 实现。