用LSTM的模型实现自动编写古诗

本文涉及的产品
模型在线服务 PAI-EAS,A10/V100等 500元 1个月
模型训练 PAI-DLC,5000CU*H 3个月
交互式建模 PAI-DSW,5000CU*H 3个月
简介: 用LSTM的模型实现自动编写古诗

简介

训练次数较少的时候生成的诗句:


77c2c8c1803c00fa99478a26e8a89bd3.png


训练结束时生成的诗句:


8e7e3a55737c55f41d3070d325848f9b.png

虽然训练到最后写出的诗句都不怎么看得懂,但是,可以看到模型在学习到越来越多


目前RNN循环神经网络可以说是最强大的神经网络模型之一了,可以处理大量的序列数据,目前已经广泛用于语音识别、文本分类、自然语言处理中了。


现在有很多deep learning的框架能很方便的实现RNN的模型。因为作者比较倾向于Keras,所以本文的 代码都是以Keras框架编写的。


当然,网上也有很多其他框架实现的例子,本文中也借鉴了前人的一些代码。只是在学习的过程中,遇到了一些其他文章中没有讲清楚的问题,在这里记录下来。


模型


b83426e077bf41dfbff727da766c7b64.png


模型很简单,首先是两个LSTM+Dropout层,最后一层为全连接层,激活函数用的softmax。

语料数据


251515396040d1772f62a5c6563edb69.png



语料是从网上下载的,由于下载的时候没有记住来源,所以,默默地感谢前人已经做的准备工作呢。

一共四万多首古诗,每行一首诗,以分隔标题和诗句,让模型学习的是诗句,所以标题在预处理的时候会去掉。


文件预处理


首先,机器并不懂每个中文汉字代表的是什么,所以要将文字转换为机器能理解的形式。这里我们采用one-hot的形式,具体内容请自行查询。简单地说下就是将所有的文字组成一个字典,每个字就能用该字在字典里的序号表示。比如“我爱吃香蕉”,一共五个字,字典就是["我", "爱", "吃", "香", "蕉"],那么,"我"就能用[1,0,0,0,0]表示,所以“香蕉”用这种形式表示出来就是一个维度为(2, 5)的向量。


类似地,处理当前的诗句文件也是将所有的字组成一个字典,这样诗句中的每个字都能用向量来表示。

defpreprocess_file(Config):# 语料文本内容files_content=''withopen(Config.poetry_file,'r',encoding='utf-8')asf:forlineinf:# 每行的末尾加上"]"符号代表一首诗结束files_content+=line.strip()+"]".split(":")[-1]words=sorted(list(files_content))counted_words={}forwordinwords:ifwordincounted_words:counted_words[word]+=1else:counted_words[word]=1# 去掉低频的字erase=[]forkeyincounted_words:ifcounted_words[key]<=2:erase.append(key)forkeyinerase:delcounted_words[key]wordPairs=sorted(counted_words.items(),key=lambdax:-x[1])words,_=zip(*wordPairs)words+=(" ",)# word到id的映射word2num=dict((c,i)fori,cinenumerate(words))num2word=dict((i,c)fori,cinenumerate(words))word2numF=lambdax:word2num.get(x,len(words)-1)returnword2numF,num2word,words,files_content


在每行末尾加上]符号是为了标识这首诗已经结束了。我们给模型学习的方法是,给定前六个字,生成第七个字,所以在后面生成训练数据的时候,会以6的跨度,1的步长截取文字,生成语料。比如“我要吃香蕉”,现在以3的跨度生成训练数据就是("我要吃", “香”),("要吃香", "蕉")。跨度为6的句子中,前后每个字都是有关联的。如果出现了]符号,说明]符号之前的语句和之后的语句是两首诗里面的内容,两首诗之间是没有关联关系的,所以我们后面会舍弃掉包含]符号的训练数据。


生成训练数据


再生成训练数据的时候先看下配置项:

classConfig(object):# 语料文本poetry_file='poetry.txt'# 保存模型的文件名weight_file='poetry_model.h5'# 跨度max_len=6# batch_sizebatch_size=32# learning_rate learning_rate=0.001

配置很简单,主要就是语料文本的路径、保存模型的文件名等。 下面生成训练数据:

defdata_generator(self):'''生成数据'''i=0while1:x=self.files_content[i:i+self.config.max_len]y=self.files_content[i+self.config.max_len]if']'inxor']'iny:i+=1continuey_vec=np.zeros(shape=(1,len(self.words)),dtype=np.bool)y_vec[0,self.word2numF(y)]=1.0x_vec=np.zeros(shape=(1,self.config.max_len,len(self.words)),dtype=np.bool)fort,charinenumerate(x):x_vec[0,t,self.word2numF(char)]=1.0yieldx_vec,y_veci+=1

x表示输入,y表示输出,输入就是前六个字,输出即为第七个字。再将文字转换成向量的形式。 需要注意的是,这边的生成器是一个while 1的无限循环的过程,官网上是这样说的:


a tuple (inputs, targets, sample_weights). This tuple (a single output of the generator) makes a single batch. Therefore, all arrays in this tuple must have the same length (equal to the size of this batch). Different batches may have different sizes. For example, the last batch of the epoch is commonly smaller than the others, if the size of the dataset is not divisible by the batch size. * The generator is expected to loop over its data indefinitely.* An epoch finishes when steps_per_epoch batches have been seen by the model.

但是实际上,在我们的生成器中,当i+max_len > len(file_content)的时候,下标就已经超过语料的长度了。所以我们在后面会限制模型学习的循环次数。


构建模型


defbuild_model(self):'''建立模型'''# 输入的dimensioninput_tensor=Input(shape=(self.config.max_len,len(


这边没什么难度,因为Keras对各种layer都已经做了非常好的封装,我们只需要填好参数就好了。这边我有个建议是,在构建自己的神经网络的过程中,最好自己先把每层数据的维度计算出来,有益于排除错误。特别是input的维度。这里说个坑,在Keras中,需要区分两种维度的表示方式,channels_last和channels_first,也就是tensorflow和Theao对维度的表示方法。


训练模型


deftrain(self):'''训练模型'''number_of_epoch=len(self.words)//self.config.batch_sizeifnotself.model:self.build_model()self.model.fit_generator(generator=self.data_generator(),verbose=True,steps_per_epoch=self.config.batch_size,epochs=number_of_epoch,callbacks=[keras.callbacks.ModelCheckpoint(self.config.weight_file,save_weights_only=False),LambdaCallback(on_epoch_end=self.generate_sample_result)])


steps_per_epoch表示在一个epoch中调用几次generator生成数据进行训练 number_of_epoch表示要训练多少个epoch 上面所说的,i+max_len的下标不能超过文本总长度,所以,当给定batch_size时,用文本总长度除以batch_size得到number_of_epoch。


callbacks中定义了保存模型的回调函数和每个epoch结束后,随机生成诗句的函数,这样在学习的过程中,可以看到随着训练数据的正常,生成的诗句也越来越正常。


结果


训练次数较少的时候生成的诗句:


77c2c8c1803c00fa99478a26e8a89bd3.png

训练结束时生成的诗句:


8e7e3a55737c55f41d3070d325848f9b.png


虽然训练到最后写出的诗句都不怎么看得懂,但是,可以看到模型在学习到越来越多的数据后,从一开始标点符号都不会标,到最后写出了有一点点模样的诗句,能看到模型变得越来越聪明了。


完整代码:https://download.csdn.net/download/pythonyanyan/87389438

相关文章
|
5月前
|
机器学习/深度学习 自然语言处理 数据处理
大模型开发:描述长短期记忆网络(LSTM)和它们在序列数据上的应用。
LSTM,一种RNN变体,设计用于解决RNN处理长期依赖的难题。其核心在于门控机制(输入、遗忘、输出门)和长期记忆单元(细胞状态),能有效捕捉序列数据的长期依赖,广泛应用于语言模型、机器翻译等领域。然而,LSTM也存在计算复杂度高、解释性差和数据依赖性强等问题,需要通过优化和增强策略来改进。
161 1
|
11月前
LSTM+Transformer混合模型时间序列预测实战教学
LSTM+Transformer混合模型时间序列预测实战教学
602 0
|
2月前
|
机器学习/深度学习 API 异构计算
7.1.3.2、使用飞桨实现基于LSTM的情感分析模型的网络定义
该文章详细介绍了如何使用飞桨框架实现基于LSTM的情感分析模型,包括网络定义、模型训练、评估和预测的完整流程,并提供了相应的代码实现。
|
2月前
|
机器学习/深度学习 自然语言处理 算法
7.1.3、使用飞桨实现基于LSTM的情感分析模型
该文章介绍了如何使用飞桨(PaddlePaddle)实现基于长短时记忆网络(LSTM)的情感分析模型,包括数据处理、网络定义、模型训练、评估和预测的详细步骤。
|
4月前
|
机器学习/深度学习 存储 人工智能
算法金 | LSTM 原作者带队,一个强大的算法模型杀回来了
**摘要:** 本文介绍了LSTM(长短期记忆网络)的发展背景和重要性,以及其创始人Sepp Hochreiter新推出的xLSTM。LSTM是为解决传统RNN长期依赖问题而设计的,广泛应用于NLP和时间序列预测。文章详细阐述了LSTM的基本概念、核心原理、实现方法和实际应用案例,包括文本生成和时间序列预测。此外,还讨论了LSTM与Transformer的竞争格局。最后,鼓励读者深入学习和探索AI领域。
51 7
算法金 | LSTM 原作者带队,一个强大的算法模型杀回来了
|
3月前
|
机器学习/深度学习 数据采集 数据挖掘
Python实现循环神经网络RNN-LSTM回归模型项目实战(股票价格预测)
Python实现循环神经网络RNN-LSTM回归模型项目实战(股票价格预测)
137 0
|
5月前
|
机器学习/深度学习 算法
【MATLAB】基于VMD-SSA-LSTM的回归预测模型
【MATLAB】基于VMD-SSA-LSTM的回归预测模型
155 4
|
4月前
|
机器学习/深度学习 自然语言处理 PyTorch
【自然语言处理NLP】Bert预训练模型、Bert上搭建CNN、LSTM模型的输入、输出详解
【自然语言处理NLP】Bert预训练模型、Bert上搭建CNN、LSTM模型的输入、输出详解
92 0
|
5月前
|
机器学习/深度学习 算法
【MATLAB】基于EMD-PCA-LSTM的回归预测模型
【MATLAB】基于EMD-PCA-LSTM的回归预测模型
74 0
【MATLAB】基于EMD-PCA-LSTM的回归预测模型
|
5月前
|
机器学习/深度学习 数据可视化 TensorFlow
【视频】LSTM模型原理及其进行股票收盘价的时间序列预测讲解|附数据代码1
【视频】LSTM模型原理及其进行股票收盘价的时间序列预测讲解|附数据代码
下一篇
无影云桌面