基于Python的宋词生成器

article/2025/9/9 8:05:40

资源下载地址:https://download.csdn.net/download/sheziqiong/85631523

1. 背景

我有两个爱好,一个是传统文化,另一个是高新技术。

传统文化,我喜欢唐诗宋词、笔墨丹青,高新技术我则从事前沿的IT编程,喜欢研究人工智能。

我很想让这两者联系起来,这一老一新,不知道会碰撞出什么火花。

2. 成果

通过试验,利用循环神经网络结合文本生成,我最终练成神功:提供一个开头,他就会自动生成一篇宋词。而且,这篇新词绝对是原创。

开头生成
细雨细雨仙桂春。明月此,梦断在愁何。等闲帘寒,归。正在栖鸦啼来。
清风清风到破向,貌成眠无风。人在梦断杜鹃风韵。门外插人莫造。怯霜晨。
高楼高楼灯火,九街风月。今夜楼外步辇,行时笺散学空。但洗。俯为人间五色。
海风海风落今夜,何处凤楼偏好。奇妙。残月破。将心青山上,落分离。
今夜今夜谁和泪倚阑干。薰风却足轻。似泠愁绪。似清波似玉人。羞见。

对于诗词稍有研究的我,对于上面“高楼”一词生成的文本,比较满意。

高楼灯火,九街风月。今夜楼外步辇,行时笺散学空。但洗。俯为人间五色。

高楼处在高处,后面的文本也体现了“高”的特色,“高楼望街”是一番意境,“高楼望夜”又是另一番意境,最后出了一个“俯看五色”,一个“俯”字,也是体现了居高临下,整篇文本无不围绕“高”的主题。实乃绝妙!

下面就来剖析下,宋词生成是如何实现的。

3. 实现方式

3.1 数据的准备

我找到了一个宋词数据集,是一个csv格式的文件,里面有2万首宋词。

文档的第一列是词牌名,第二列是作者,第三列是正文。其中正文,已经做好了分词处理。

想要了解分词,可以查看NLP知识点:中文分词。

3.2 数据的读入

首先导入整个项目涉及到的包。

import csv
import tensorflow as tf
from tensorflow.keras.preprocessing.text import Tokenizer
from tensorflow.keras.preprocessing.sequence import pad_sequences
import numpy as np
from tensorflow.python.keras.engine.sequential import Sequential
from tensorflow.keras import layers
from tensorflow.keras.optimizers import Adam

下面是加载数据集文件中数据的方法。

def load_data(num = 1000):# 读取csv文件。表头:0 题目| 1 作者| 2 内容csv_reader = csv.reader(open("./ci.csv",encoding="gbk"))# 以一首词为单位存储ci_list = []for row in csv_reader:# 取每一行,找到词内容那一列ci_list.append(row[2])# 超过最大数量退出循环,用多少取多少if len(ci_list) > num:break return ci_list

然后进行数据序列化。

这里要重点说明一下,因为要做文本预测的训练,需要从上面的词语推断出下面的词语,所以这里做了一些加工。

比如“看山 不是 山 , 看山 又是 山”这一句,它给转化成了多句:

看山 不是
看山 不是 山 
看山 不是 山 ,
看山 不是 山 , 看山
看山 不是 山 , 看山 又是
看山 不是 山 , 看山 又是 山

这么做的目的就是告诉神经网络,如果前面是“看山”,后面跟一个词语是“不是”。当前面变成“看山 不是 山 , 看山”时,这时“看山”后面就变成“又是”了。

“看山”后面并不是固定的,而是根据它前面一串词语综合判断而决定的。

将一句话,切成多句话,这是一个特殊处理的地方,就是下面代码做的事情:

for i in range(1, len(token_list)):n_gram_sequence = token_list[:i+1]input_sequences.append(n_gram_sequence)

3.3 构建模型

要训练数据,我们首先得有一个神经网络模型,下面是构建了一个网络模型序列。

def create_model(vocab_size, embedding_dim, max_length):# 构建序列模型model = Sequential()# 添加嵌入层model.add(layers.Embedding(vocab_size, embedding_dim, input_length = max_length))# 添加长短时记忆层model.add(layers.Bidirectional(layers.LSTM(512)))# 添加softmax分类model.add(layers.Dense(vocab_size, activation='softmax'))# adam优化器adam = Adam(lr=0.01)# 配置训练参数model.compile(loss='categorical_crossentropy',optimizer=adam, metrics=['accuracy'])return model

关于模型、层、激活函数的知识点,有专门解释:神经网络模型的序列和层、激活函数。


假设我们得到了训练序列input_sequences是:

[0, 0, 1, 2]
[0, 0, 3, 4]
[0, 3, 4, 5]
[3, 4, 5, 6]


对应文字就是:

[0, 0, 春花, 秋月]
[0, 0, 一江, 春水]
[0, 一江, 春水, 向东]
[一江, 春水, 向东, 流]


对于训练,一般都是成对的。一个输入,一个输出。机器将学习从输入推断出输出的诀窍。在这个例子中,因为是从上一个词推断出下一个词,所以输入和输出都要从上面的语料库中来取。下面这段代码就是从input_sequences取出了输入和输出:
```python
xs = input_sequences[:,:-1] 
labels = input_sequences[:,-1]
输入 xs输出 labels
[0, 0, 春花][秋月]
[0, 0, 一江][春水]
[0, 一江, 春水][向东]
[一江, 春水, 向东][流 ]

因为模型里面激活函数使用了activation='softmax',所以这个输出要通过tf.keras.utils.to_categorical转化成了独热编码。

此时,需要强调几个概念:

  • 文本序列的最大长度max_sequence_len就是[一江, 春水, 向东, 流]的长度,此处值为4。主要作用是定义一个固定的训练长度,长度不足时补0,超出时裁剪。

为什么要这么做,可以点击此处了解。

  • 输入序列的长度input_length就是[0, 一江, 春水]的长度,固定为3,是从max_sequence_len截取出来的,最后一个词不要。主要作用是作为输入。

3.5 进行预测

训练完成之后,我们就可以享受胜利果实,开始进行预测了。

预测需要给一个开头的词语,并且指定后面需要预测多少个词语。

预测B
预测C
预测D
预测后面N个词
开头词语 A
AB
ABC
ABCD

首先,根据开始的词语,通过model.predict_classes(token_list)预测出下一个词语,接着开头词语连同预测词语两方再作为输入,继续预测下一个词语。如此类推,像贪吃蛇一样,从一个开头词语慢慢地引出一个长句子。句子中每个词语是有语义上的前后关系的。

这就是宋词生成器的实现逻辑,希望对你有所帮助。

资源下载地址:https://download.csdn.net/download/sheziqiong/85631523


http://chatgpt.dhexx.cn/article/wVUoOwR3.shtml

相关文章

基于java的古诗词生成管理系统

10161-古诗词生成管理系统 开发工具 eclipse tomact mysql jdk 功能详情: 古诗搜索、古诗问答、机器回复、古诗管理(添加古诗、古诗分类、古诗标签、古诗列表)、用户管理

田字格字帖生成器、孩子取名系列工具

大家好,我是小寻,欢迎关注公众号:工具优选,免费领取优质项目源码和常用工具,还可以加入我的交流群! 这是是一款2013年上线的在线小工具集,包括了 13 款中文学习工具,有田字格字帖、拼音田字格、古诗词字帖…

有趣的深度学习——使用TensorFlow 2.0 + RNN 实现一个古体诗生成器

一、前言 很早之前,我曾经写过一个古体诗生成器(详情可以戳TensorFlow练手项目二:基于循环神经网络(RNN)的古诗生成器),那个时候用的还是Python 2.7和TensorFlow 1.4。 随着框架的迭代,API 的变更&#x…

现在还可以一键自动生成古诗词,你知道吗?

人类在漫长的历史长河中,一直在探索着各种各样的美好,不断地追求着更高的境界。而如今,随着科技的不断发展,人工智能已经成为了我们得力的伙伴之一,为我们带来了更多的便利和可能性。尤其是在艺术和文化领域&#xff0…

古诗词在线起名 - 一刀工具箱

古诗词名字生成器帮助你在线生成古诗词名字,包含:诗经、楚辞、唐诗、宋词、辞赋等古风的名字,这些名字都非常的优美好听,希望你们能够喜欢这款古诗词起名工具。 代码片段 async subName() {let name_arr Object.keys(this.userN…

NLP入门 - 基于Word Embedding + LSTM的古诗生成器

一共实现三个功能: 1. 续写五言诗 2. 续写七言诗 3. 写五言藏头诗 之前用这个做Intro to Computer Science的期末项目折腾太久,不想赘述,内容介绍及实现方法可参考期末presentation的slides: https://docs.google.com/presen…

基于古诗词的名字生成器

数据集 因为数据量庞大,使用本地的 CSV 数据进行测试。 后续改进 CSV 文件保存到 mongodb 数据库,便于聚合查询。 数据分词 我们需要一个分词器将这些数据进行分词,用到的是 Golang 版的 jieba 库如下: "github.com/go-e…

基于LSTM + keras 的古诗生成器

1.语料准备:包含 5.5 万首唐诗、26 万首宋诗、2.1 万首宋词和其他古典文集。诗人包括唐宋两朝近 1.4 万古诗人,和两宋时期 1.5 千古词人。数据来源于互联网。每行一首诗,标题在预处理的时候已经去掉了。2.模型参数配置:预先定义模…

唐诗生成器

使用唐诗语料库,经过去噪预处理、分词、生成搭配、生成主题等过程,生成唐诗。 csdn下载地址:http://download.csdn.net/detail/lijiancheng0614/9840952 github上repository地址:https://github.com/lijiancheng0614/poem_genera…

JQuery中的val()函数

JQuery中的val()函数相当于Javascript中的value属性,可以用来设置和获取元素的值。 下面用一个简单的邮箱登陆界面来举个例子: 在默认情况下邮箱的地址输入框和密码输入框都有相应的提示。 要求:当鼠标聚焦在邮箱地址输入框时,提…

【Python】sklearn中的cross_val_score()函数参数

sklearn 中的cross_val_score函数可以用来进行交叉验证,因此十分常用,这里介绍这个函数的参数含义。 sklearn.cross_validation.cross_val_score(estimator, X, yNone, scoringNone, cvNone, n_jobs1, verbose0, fit_paramsNone, pre_dispatch‘2*n_job…

sklearn交叉验证函数cross_val_score用法及参数解释

文章目录 一 、使用示例二、参数含义三、常见的scoring取值1.分类、回归和聚类scoring参数选择2.f1_micro和f1_macro区别3.负均方误差和均方误差 一 、使用示例 import numpy as np from sklearn.model_selection import train_test_split from sklearn import svm from sklea…

java val_Java中是否有val()函数?

慕尼黑的夜晚无繁华 很少有实际用例能够评估String作为Java代码的一个片段是必要的或可取的。也就是说,询问如何做到这一点实际上是XY问题:你实际上有一个不同的问题,可以用不同的方法来解决。先问问自己,这是怎么回事String你想要…

c语言val函数用法,函数VAL()什么意思怎么用啊?/

满意答案 Dickyshe 2013.03.22 采纳率:50% 等级:12 已帮助:12551人 将一个数据行变量转换成数字长整型变量如 text1.text "10" text2.text "11" text3.text text1.texttext2.text 按道理应该得到10+11(…

mysql中val是什么意思_val是什么函数

val是将由数字符号组成的字符型数据转换成相应的数值型数据的函数,其语法是“Val(S,V,Code)”,若字符串内出现非数字字符,那么只转换非数字字符前面的部分;若字符串的首字符不是数字符号,则返回数值零,但忽…

抽象方法的访问修饰符

抽象方法不能使用private修饰符,也不宜使用默认修饰符(default) (1)如果使用private修饰符 public abstract class SuperClass {/** The abstract method test in type SuperClass can only set a visibility modifi…

Java之访问修饰符

1.访问修饰符 java提供四种访问修饰符,用于控制方法和属性(成员变量)的访问权限 四种分别是 公开级别:public,对外公开 受保护级别:protected,对子类和同一个包的类公开 默认级别&#xff…

Java-访问修饰符

目录 一、private(私有权限) 二、default(默认权限) 三、protected(受保护权限) ​四、public(公共权限) 五、总结 示意图 private(default)protectedpublic本类YesYesYesYes同包的类NoYesYesYes不同包的父子关系NoNoYesYes不同包的非父子关系NoNoNoYes 注意点&#xf…

C# 的访问修饰符

访问修饰符的作用域分为三种: 类的访问修饰符方法的访问修饰符属性的访问修饰符 访问修饰符主要分为: public (公共的)protected (保护的)internal (内部的)private (私有的) 一,类的访问修饰符 默认的是 internal 二,方法的…