BiLSTM+CRF实现AI诗人与长短记忆网络

所用程序说明:
main.py: 为主程序, 在命令行运行方式为:python main.py –-mode train 或 python main.py –-mode test或 python main.py –-mode head
makedata.py: 将三万首唐诗制作成若干批训练集。并将此诗集出现的所有汉字制成一个字典。
header.py: 一些全局参数的定义。
model.py: 构建模型。训练模型。测试模型。
本实训旨在通过AI诗人神经网络让学员了解如何用Tensorflow构建反馈网络。完成本实训项目大约需要100分钟。
实验目标:
1、熟悉自然语言处理及文本读取。

2、熟悉如何用向量表征语言。

3、掌握如何用Tensorflow编写反馈网络。
主要步骤:
1、 将三万多首唐诗通过makedata.py输入到模型中
2、 搭建训练模型
3、 构建训练过程
4、 编写写诗过程

step1 makedata.py

步骤一 将三万多首唐诗通过makedata.py输入到模型中。通过命令行一步一步熟悉如此处理文字文件和数据。
具体的过程实现如下图所示:

1-1、1-2将line字符串的前后空格删除,将它以’:'为分割标志,分成title和poem。

poems = []file = open(filename, "r", encoding="gbk")for line in file:  # 每行储存一首诗# 将line开头及结尾处的空格删除,然后分成题目title与诗体peomtitle,poem=line.strip().split(':')## strip()将line开头及结尾处的空格等其它非文字符号删除## split是分割函数,将字符串分割成“字符”,保存在一个列表中

1-3、1-4、1-5去除空格、其他字符,获取题目与诗的内容

 poem = poem.replace(' ','') #去除诗中的空格## replace替换函数。if '_' in poem or '《' in poem or '[' in poem or '(' in poem or '(' in poem:continue## 去除poem的其它字符if len(poem) < 10 or len(poem) > 128:continue## 确保poem长度适当poem = '[' + poem + ']' #add start and end signspoems.append(poem)# 将poem加到列表 poems当中

1-6 动作:将诗集中出现的汉字根据出现频次制作一个字典,储存于变量allWords之中。

allWords = {}# 定义一个空的字典(dictionary)# key:为汉字# 字典的值value:为该汉字出现的频次# 代码仿照写处2for poem in poems: # 枚举诗歌列表中所有诗for word in poem: # 枚举每首诗中所有的字if word not in allWords:allWords[word] = 1  # 假如该汉字还没出现过else:allWords[word] += 1# 删除低频字erase = []for key in allWords: # 枚举字典allwords中的所有字keyif allWords[key] < 2:  #假如其频次小于2,加入待删列表erase.append(key)for key in erase:del allWords[key]

1-7 将每首诗转换成一个向量

wordPairs = sorted(allWords.items(), key = lambda x: -x[1])# 所有出现的汉字按出现频次,由多到少排序。# 函数items,用于取出字典的key和值。# key = lamda表示按key的值进行排序,按x的第1维进行排序words, a= zip(*wordPairs)  # *wordpairs 将wordpairs解压(unzip)# zip()将输入变量变成turplewords += (" ", )           # 将空格加在最后。wordToID = dict(zip(words, range(len(words)))) #word to ID# 把每个汉字赋予一个数。wordTOIDFun = lambda A: wordToID.get(A, len(words))  # 转化成函数,# 输入汉字,输出它对应的数。poemsVector = [([wordTOIDFun(word) for word in poem]) for poem in poems] # poem to vector## 将所有的诗转化成向量,其中一首诗中,数字用turple储存,在外面用列表储存。## 类似这样。[(1 3 2 4), (2 3 4 1), (1 5 6 2)]

1-8制作训练样本

     batchNum  = (len(poemsVector) - 1) // batchSize  # // 除法将余数去掉,如10//3 = 3X = []Y = []#create batchfor i in range(batchNum):batch = poemsVector[i * batchSize: (i + 1) * batchSize]# batch 储存了 batchsize诗的向量maxLength = max([len(vector) for vector in batch])# 得到一个batch其中一首最长的诗的长度temp = np.full((batchSize, maxLength), wordTOIDFun(" "), np.int32)#将temp初始化成batchsize * maxlength的矩阵,其中矩阵元素初始值皆为空格对应的IDfor j in range(batchSize):temp[j, :len(batch[j])] = batch[j]#将temp 储存了一批诗对应的矩阵# 代码粘贴处4X.append(temp)  # 把这个矩阵放入列表X中,temp2 = np.copy(temp)temp2[:, :-1] = temp[:, 1:]#将诗向前挪一个字的位置对应的向量放入Y中。Y.append(temp2)#提示:比如:输入X =“白日依山近…”,输出Y=“日依山近, …”。# 将字往向前移一个字。比如# temp = [(白日依山进),()]->temp2 [(日依山进进), ()]# X -> Y相当于只挪动一个字。return X, Y, len(words) + 1, wordToID, words

step2 搭建训练模型 model.py

下图为buildmodel函数的示意图。它的基本思路:先将一批样本gtX[16X122]矩阵(相当于整数表征)通过embedding_lookup,将其转成向量表征inputbatch;然后,搭建动态RNN,这个RNN基本单元basicCell是一个LSTM,由它堆两层形成stackCell,然后再动态形成RNN(其中 t = 1到122)

2-1将输入buildmodel的变量gtX(整数表征),通过内嵌表embedding,转变成向量表征变量inputbatch。

with tf.variable_scope("embedding"): #embeddingembedding = tf.get_variable("embedding", [wordNum, hidden_units], dtype = tf.float32)# embedding 为 n * m维的矩阵,其中n为涉及的汉字的数目,m为隐藏LSTM单元的数目# 将汉字用hidden_units维向量重新表征,训练RNN的其中一个目的就是为了找到embedding这个矩阵## 代码仿写处 1#将输入buildmodel的变量gtX(整数表征),通过内嵌表embedding,转变成向量表征变量inputbatch。inputbatch = tf.nn.embedding_lookup(embedding, gtX)# 将16首诗转化为向量表达。# embedding_lookup(params, ids)其实就是按照ids顺序返回params中的第ids行。比如说,#ids=[1,3,2],就是返回params中第1,3,2行。返回结果为由params的1,3,2行组成的tensor。# gtx: batchsize * hidden_units, embedding (wordnum*hidden)# inputbatch: batchsize * maxLength * hidden

1-2构建LSTM单元

basicCell = tf.contrib.rnn.BasicLSTMCell(hidden_units, state_is_tuple = True)   

2-3 动作:将LSTM单元垒起来。

#将LSTM单元垒起来
stackCell = tf.contrib.rnn.MultiRNNCell([basicCell] * layers)

2-4 动作:构建动态RNN

#构建动态RNN。
initState = stackCell.zero_state(np.shape(gtX)[0], tf.float32)
outputs, finalState = tf.nn.dynamic_rnn(stackCell, inputbatch, initial_state = initState)
outputs = tf.reshape(outputs, [-1, hidden_units])

step3 定义训练过程

计算成本函数。将一个样本gtX,gtY代入buildmodel函数计算出logits, probs之后,就可以计算其成本函数了

loss = tf.contrib.legacy_seq2seq.sequence_loss_by_example([logits], [targets],[tf.ones_like(targets, dtype=tf.float32)], wordNum)
cost = tf.reduce_mean(loss) # 定义损耗函数

计算梯度
相关资料如下,有多种计算梯度的方法

选择优化方法
optimizer = tf.train.AdamOptimizer(learningRate)
构建训练器
trainOP = optimizer.apply_gradients(zip(grads, tvars))

step4、编写写诗过程

(只实训head这个过程。)比如输入"白黄",它返回"白日依山近,黄河入海流。"
理解probtoword函数。训练好的Model最终输入下一个字出现的概率(它依赖于前面几个字的输入)。它储存在一个5667维的数组,即这5667汉字的出现的概率分别是多少。当然可取概率最大的那个,但这将导致每次都出现同一个词。因此,需要将概率较大的几个当中随机选择一个,但同时使得概率原来越大的被选中的概率也越大。
完成probtoword函数。输入一个概率分布weights(5667个小于1的数字),在概率较大的几个中随机选择一个输出汉字。为了达到这个目的,先用cumsum(累加)函数将分布变成累积分布函数,这样只要取0到1的一个随机数,那么可以证明它落入初始概率大的那个格子的概率正比于原来分布中的概率,如下图所示。
完成testhead函数。请仔细阅读testhead函数。它先导入训练好的网络参数,然后构建初始状态。一个个字往后预测出后面的字出现的概率,并概率转变成汉字
打开文件main.py,修改第33行(也可不改),尝试输入不同的四个或多个汉字(每句诗的诗头),然后 在命令行输入。(比如"白黄欲更")看看AI能创造出什么诗来

具体代码见https://github.com/Arfer-ustc/AI_Poem_BiLstm_CRF.git

BiLSTM+CRF实现AI诗人与长短记忆网络相关推荐

  1. LSTM(长短记忆网络)

    LSTM(长短记忆网络) 一:LSTM简介 ​ 传统的循环网络RNN可以通过记忆体实现短期记忆进行连续数据的预测,但是当连续数据的序列变长时,会使时间展开步更长,在反向传播更新参数时,梯度要按时间步连 ...

  2. 基于BERT+BiLSTM+CRF模型与新预处理方法的古籍自动标点

    摘要 古文相较于现代文不仅在用词.语法等方面存在巨大差异,还缺少标点,使人难以理解语义.采用人工方式对古文进行标点既需要有较高的文学水平,还需要对历史文化有一定了解.为提高古文自动标点的准确率,将深层 ...

  3. pytorch BiLSTM+CRF代码详解 重点

    一. BILSTM + CRF介绍 https://www.jianshu.com/p/97cb3b6db573 1.介绍 基于神经网络的方法,在命名实体识别任务中非常流行和普遍. 如果你不知道Bi- ...

  4. 代码实现中文命名实体识别(包括多种模型:HMM,CRF,BiLSTM,BiLSTM+CRF)

    作者 | 忆臻 地址 | https://zhuanlan.zhihu.com/p/100969186 专栏 | 机器学习算法与自然语言处理 代码实现中文命名实体识别(包括多种模型:HMM,CRF,B ...

  5. BiLSTM+CRF医学病例命名实体识别项目

    向AI转型的程序员都关注了这个号???????????? 人工智能大数据与深度学习  公众号:datayx 数据来自CCKS2018的电子病历命名实体识别的评测任务,是对于给定的一组电子病历纯文本文档 ...

  6. NLP工具包(Albert+BiLSTM+CRF)

    向AI转型的程序员都关注了这个号???????????? 机器学习AI算法工程   公众号:datayx 一.简介 Macropodus自然语言处理工具(Albert+BiLSTM+CRF) 中文分词 ...

  7. dann的alpha torch_pytorch BiLSTM+CRF代码详解

    一. BILSTM + CRF介绍 1.介绍 基于神经网络的方法,在命名实体识别任务中非常流行和普遍. 如果你不知道Bi-LSTM和CRF是什么,你只需要记住他们分别是命名实体识别模型中的两个层. 1 ...

  8. 深度学习框架PyTorch入门与实践:第九章 AI诗人:用RNN写诗

    我们先来看一首诗. 深宫有奇物,璞玉冠何有. 度岁忽如何,遐龄复何欲. 学来玉阶上,仰望金闺籍. 习协万壑间,高高万象逼. 这是一首藏头诗,每句诗的第一个字连起来就是"深度学习". ...

  9. 【PyTorch】10 文本篇更多代码——BOW、N-Gram、CBOW、LSTM、BI-LSTM CRF

    示例 1. 基于逻辑回归与词袋模式(BOW)的文本分类器 完整代码 结果 2. 词嵌入:编码形式的词汇语义 2.1 N-Gram语言模型 完整代码 结果 2.2 计算连续词袋模型(CBOW)的词向量 ...

最新文章

  1. 论记笔记的重要性:以三个电影为例
  2. Linux网络技术管理
  3. Spring Boot项目(Maven\Gradle)三种启动方式及后台运行详解
  4. 《MySQL实战45讲》基础理论篇 1-8讲 学习笔记
  5. 去除bootstrap中input输入框的蓝色光
  6. js 读取php文件内容为空,PHP 读取文件内容代码(txt,js等)
  7. 制作 小 linux 教程,用BusyBox制作Linux最小系统
  8. 翻译【ElasticSearch Server】第一章:开始使用ElasticSearch集群(2)
  9. 原linux的字符文件作用,linux特殊字符及其作用大全
  10. 安卓 App 库存系统开发 开发成本估计
  11. GDPR或使全球域名whois信息被隐藏
  12. 23种设计模式之代理模式(Proxy)
  13. swing-组件Collapse折叠面板2
  14. 学习理论-PAC理论
  15. 知识共享许可协议 Creative Commons Licenses
  16. 手机图片分辨率怎么调整?如何将图片修改300DPI?
  17. 视网膜数据集(2)Messidor
  18. docker更换镜像源
  19. 一键修改windows远程桌面3389端口
  20. 删除字符串中数字字符

热门文章

  1. ffmpeg-时间基tbn、tbc、tbr
  2. linux12企业实战 -- 37zabbix企业微信通知配置
  3. 国际青少年计算机技能大赛英语,竞赛:2017中学生英语能力、青少年信息学奥赛!...
  4. System Power Tools Suite
  5. c语言编程题大学,大学C语言程序设计(编程题).pdf
  6. 万年历的Java代码
  7. java字符转转长整型_P104 将数字字符串转换成长整型整数 ★★
  8. Ngrok(内网穿透工具)使用教程详解
  9. 操作系统 - Linux - Ubuntu
  10. 为什么你的工具类APP用户量不少,却难以找到变现模式?