返回顶部
首页 > 资讯 > 后端开发 > Python >PythonPaddleNLP实现自动生成虎年藏头诗
  • 722
分享到

PythonPaddleNLP实现自动生成虎年藏头诗

2024-04-02 19:04:59 722人浏览 泡泡鱼

Python 官方文档:入门教程 => 点击学习

摘要

目录一、 数据处理1.paddleNLP升级2.提取诗头3.生成词表4.定义dataset二、定义模型并训练1.模型定义2.模型训练3.模型保存三、生成藏头诗总结一、 数据处理 本项

一、 数据处理

项目中利用古诗数据集作为训练集,编码器接收古诗的每个字的开头,解码器利用编码器的信息生成所有的诗句。为了诗句之间的连贯性,编码器同时也在诗头之前加上之前诗句的信息。举例:

“白日依山尽,黄河入海流,欲穷千里目,更上一层楼。” 可以生成两个样本:

样本一:编码器输入,“白”;解码器输入,“白日依山尽,黄河入海流”

样本二:编码器输入,“白日依山尽,黄河入海流。欲”;解码器输入,“欲穷千里目,更上一层楼。”

1.paddlenlp升级

!pip install -U paddlenlp
Looking in indexes: https://pypi.tuna.tsinghua.edu.cn/simple
Collecting paddlenlp
[?25l  Downloading Https://pypi.tuna.tsinghua.edu.cn/packages/17/9b/4535ccf0e96c302a3066bd2e4d0f44b6b1a73487c6793024475b48466c32/paddlenlp-2.2.3-py3-none-any.whl (1.2MB)
     |████████████████████████████████| 1.2MB 11.2MB/s eta 0:00:01
[?25hRequirement already satisfied, skipping upgrade: h5py in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from paddlenlp) (2.9.0)
Requirement already satisfied, skipping upgrade: colorlog in /opt/conda/envs/Python35-paddle120-env/lib/python3.7/site-packages (from paddlenlp) (4.1.0)
Requirement already satisfied, skipping upgrade: colorama in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from paddlenlp) (0.4.4)
Requirement already satisfied, skipping upgrade: seqeval in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from paddlenlp) (1.2.2)
Requirement already satisfied, skipping upgrade: jieba in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from paddlenlp) (0.42.1)
Requirement already satisfied, skipping upgrade: multiprocess in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from paddlenlp) (0.70.11.1)
Requirement already satisfied, skipping upgrade: six in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from h5py->paddlenlp) (1.16.0)
Requirement already satisfied, skipping upgrade: numpy>=1.7 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from h5py->paddlenlp) (1.20.3)
Requirement already satisfied, skipping upgrade: scikit-learn>=0.21.3 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from seqeval->paddlenlp) (0.24.2)
Requirement already satisfied, skipping upgrade: dill>=0.3.3 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from multiprocess->paddlenlp) (0.3.3)
Requirement already satisfied, skipping upgrade: scipy>=0.19.1 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from scikit-learn>=0.21.3->seqeval->paddlenlp) (1.6.3)
Requirement already satisfied, skipping upgrade: threadpoolctl>=2.0.0 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from scikit-learn>=0.21.3->seqeval->paddlenlp) (2.1.0)
Requirement already satisfied, skipping upgrade: joblib>=0.11 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from scikit-learn>=0.21.3->seqeval->paddlenlp) (0.14.1)
Installing collected packages: paddlenlp
  Found existing installation: paddlenlp 2.1.1
    Uninstalling paddlenlp-2.1.1:
      Successfully uninstalled paddlenlp-2.1.1
Successfully installed paddlenlp-2.2.3

2.提取诗头

import re
poems_file = open("./data/data70759/poems_zh.txt", encoding="utf8")
# 对读取的每一行诗句,统计每一句的词头
poems_samples = []
poems_prefix = []
poems_heads = []
for line in poems_file.readlines():
    line_ = re.sub('。', ' ', line)
    line_ = line_.split()
    # 生成训练样本
    for i, p in enumerate(line_):
        poems_heads.append(p[0])
        poems_prefix.append('。'.join(line_[:i]))
        poems_samples.append(p + '。')


# 输出文件信息
for i in range(20):
    print("poems heads:{}, poems_prefix: {}, poems:{}".fORMat(poems_heads[i], poems_prefix[i], poems_samples[i]))
poems heads:欲, poems_prefix: , poems:欲出未出光辣达,千山万山如火发。
poems heads:须, poems_prefix: 欲出未出光辣达,千山万山如火发, poems:须臾走向天上来,逐却残星赶却月。
poems heads:未, poems_prefix: , poems:未离海底千山黑,才到天中万国明。
poems heads:满, poems_prefix: , poems:满目江山四望幽,白云高卷嶂烟收。
poems heads:日, poems_prefix: 满目江山四望幽,白云高卷嶂烟收, poems:日回禽影穿疏木,风递猿声入小楼。
poems heads:远, poems_prefix: 满目江山四望幽,白云高卷嶂烟收。日回禽影穿疏木,风递猿声入小楼, poems:远岫似屏横碧落,断帆如叶截中流。
poems heads:片, poems_prefix: , poems:片片飞来静又闲,楼头江上复山前。
poems heads:飘, poems_prefix: 片片飞来静又闲,楼头江上复山前, poems:飘零尽日不归去,帖破清光万里天。
poems heads:因, poems_prefix: , poems:因登巨石知来处,勃勃元生绿藓痕。
poems heads:静, poems_prefix: 因登巨石知来处,勃勃元生绿藓痕, poems:静即等闲藏草木,动时顷刻徧乾坤。
poems heads:横, poems_prefix: 因登巨石知来处,勃勃元生绿藓痕。静即等闲藏草木,动时顷刻徧乾坤, poems:横天未必朋元恶,捧日还曾瑞至尊。
poems heads:不, poems_prefix: 因登巨石知来处,勃勃元生绿藓痕。静即等闲藏草木,动时顷刻徧乾坤。横天未必朋元恶,捧日还曾瑞至尊, poems:不独朝朝在巫峡,楚王何事谩劳魂。
poems heads:若, poems_prefix: , poems:若教作镇居中国,争得泥金在泰山。
poems heads:才, poems_prefix: , poems:才闻暖律先偷眼,既待和风始展眉。
poems heads:嚼, poems_prefix: , poems:嚼处春冰敲齿冷,咽时雪液沃心寒。
poems heads:蒙, poems_prefix: , poems:蒙君知重惠琼实,薄起金刀钉玉深。
poems heads:深, poems_prefix: , poems:深妆玉瓦平无垅,乱拂芦花细有声。
poems heads:片, poems_prefix: , poems:片逐银蟾落醉觥。
poems heads:巧, poems_prefix: , poems:巧剪银花乱,轻飞玉叶狂。
poems heads:寒, poems_prefix: , poems:寒艳芳姿色尽明。

3.生成词表

# 用PaddleNLP生成词表文件,由于诗文的句式较短,我们以单个字作为词单元生成词表
from paddlenlp.data import Vocab

vocab = Vocab.build_vocab(poems_samples, unk_token="<unk>", pad_token="<pad>", bos_token="<", eos_token=">")
vocab_size = len(vocab)

print("vocab size", vocab_size)
print("Word to idx:", vocab.token_to_idx)

4.定义dataset

# 定义数据读取器
from paddle.io import Dataset, BatchSampler, DataLoader
import numpy as np

class PoemDataset(Dataset):
    def __init__(self, poems_data, poems_heads, poems_prefix, vocab, encoder_max_len=128, decoder_max_len=32):
        super(PoemDataset, self).__init__()
        self.poems_data = poems_data
        self.poems_heads = poems_heads
        self.poems_prefix = poems_prefix
        self.vocab = vocab
        self.tokenizer = lambda x: [vocab.token_to_idx[x_] for x_ in x]
        self.encoder_max_len = encoder_max_len
        self.decoder_max_len = decoder_max_len

    def __getitem__(self, idx):
        eos_id = vocab.token_to_idx[vocab.eos_token]
        bos_id = vocab.token_to_idx[vocab.bos_token]
        pad_id = vocab.token_to_idx[vocab.pad_token]
        # 确保encoder和decoder的输出都小于最大长度
        poet = self.poems_data[idx][:self.decoder_max_len - 2]  # -2 包含bos_id和eos_id
        prefix = self.poems_prefix[idx][- (self.encoder_max_len - 3):]  # -3 包含bos_id, eos_id, 和head的编码
        # 对输入输出编码

        sample = [bos_id] + self.tokenizer(poet) + [eos_id]
        prefix = self.tokenizer(prefix) if prefix else []
        heads = prefix + [bos_id] + self.tokenizer(self.poems_heads[idx]) + [eos_id] 
        sample_len = len(sample)
        heads_len = len(heads)
        sample = sample + [pad_id] * (self.decoder_max_len - sample_len)
        heads = heads + [pad_id] * (self.encoder_max_len - heads_len)
        mask = [1] * (sample_len - 1) + [0] * (self.decoder_max_len - sample_len) # -1 to make equal to out[2]
        out = [np.array(d, "int64") for d in [heads, heads_len, sample, sample, mask]]
        out[2] = out[2][:-1]
        out[3] = out[3][1:, np.newaxis]
        return out

    def shape(self):
        return [([None, self.encoder_max_len], 'int64', 'src'),
                ([None, 1], 'int64', 'src_length'),
                ([None, self.decoder_max_len - 1],'int64', 'trg')], \
               [([None, self.decoder_max_len - 1, 1], 'int64', 'label'),
                ([None, self.decoder_max_len - 1], 'int64', 'trg_mask')]


    def __len__(self):
        return len(self.poems_data)

dataset = PoemDataset(poems_samples, poems_heads, poems_prefix, vocab)
batch_sampler = BatchSampler(dataset, batch_size=2048)
data_loader = DataLoader(dataset, batch_sampler=batch_sampler)

二、定义模型并训练

1.模型定义

from Seq2Seq.models import Seq2SeqModel
from paddlenlp.metrics import Perplexity
from Seq2Seq.loss import CrossEntropyCriterion
import paddle
from paddle.static import InputSpec

# 参数
lr = 1e-6
max_epoch = 20
models_save_path = "./checkpoints"

encoder_attrs = {"vocab_size": vocab_size, "embed_dim": 200, "hidden_size": 128, "num_layers": 4, "dropout": .2,
                    "direction": "bidirectional", "mode": "GRU"}
decoder_attrs = {"vocab_size": vocab_size, "embed_dim": 200, "hidden_size": 128, "num_layers": 4, "direction": "forward",
                    "dropout": .2, "mode": "GRU", "use_attention": True}

# inputs shape and label shape
inputs_shape, labels_shape = dataset.shape()
inputs_list = [InputSpec(input_shape[0], input_shape[1], input_shape[2]) for input_shape in inputs_shape]
labels_list = [InputSpec(label_shape[0], label_shape[1], label_shape[2]) for label_shape in labels_shape]

net = Seq2SeqModel(encoder_attrs, decoder_attrs)
model = paddle.Model(net, inputs_list, labels_list)

model.load("./final_models/model")

opt = paddle.optimizer.Adam(learning_rate=lr, parameters=model.parameters())

model.prepare(opt, CrossEntropyCriterion(), Perplexity())
W0122 21:03:30.616776   166 device_context.cc:447] Please NOTE: device: 0, GPU Compute Capability: 7.0, Driver api Version: 10.1, Runtime API Version: 10.1
W0122 21:03:30.620450   166 device_context.cc:465] device: 0, cuDNN Version: 7.6.

2.模型训练

# 训练,训练时间较长,已提供了训练好的模型(./final_models/model)
model.fit(train_data=data_loader, epochs=max_epoch, eval_freq=1, save_freq=5, save_dir=models_save_path, shuffle=True)

3.模型保存

# 保存
model.save("./final_models/model")

三、生成藏头诗

import warnings

def post_process_seq(seq, bos_idx, eos_idx, output_bos=False, output_eos=False):
    """
    Post-process the decoded sequence.
    """
    eos_pos = len(seq) - 1
    for i, idx in enumerate(seq):
        if idx == eos_idx:
            eos_pos = i
            break
    seq = [idx for idx in seq[:eos_pos + 1]
           if (output_bos or idx != bos_idx) and (output_eos or idx != eos_idx)]
    return seq

# 定义用于生成祝福语的类
from paddlenlp.data.tokenizer import JiebaTokenizer

class GenPoems():
    # content (str): the str to generate poems, like "恭喜发财"
    # vocab: the instance of paddlenlp.data.vocab.Vocab
    # model: the Inference Model
    def __init__(self, vocab, model):
        self.bos_id = vocab.token_to_idx[vocab.bos_token]
        self.eos_id = vocab.token_to_idx[vocab.eos_token]
        self.pad_id = vocab.token_to_idx[vocab.pad_token]
        self.tokenizer = lambda x: [vocab.token_to_idx[x_] for x_ in x]
        self.model = model
        self.vocab = vocab

    def gen(self, content, max_len=128):
        # max_len is the encoder_max_len in Seq2Seq Model.
        out = []
        vocab_list = list(vocab.token_to_idx.keys())
        for w in content:
            if w in vocab_list:
                content = re.sub("([。,])", '', content)
                heads = out[- (max_len - 3):] + [self.bos_id] + self.tokenizer(w) + [self.eos_id]
                len_heads = len(heads)
                heads = heads + [self.pad_id] * (max_len - len_heads)
                x = paddle.to_tensor([heads], dtype="int64")
                len_x = paddle.to_tensor([len_heads], dtype='int64')
                pred = self.model.predict_batch(inputs = [x, len_x])[0]
                out += self._get_results(pred)[0]
            else:
                warnings.warn("{} is not in vocab list, so it is skipped.".format(w))
                pass
        out = ''.join([self.vocab.idx_to_token[id] for id in out])
        return out
    
    def _get_results(self, pred):
        pred = pred[:, :, np.newaxis] if len(pred.shape) == 2 else pred
        pred = np.transpose(pred, [0, 2, 1])
        outs = []
        for beam in pred[0]:
            id_list = post_process_seq(beam, self.bos_id, self.eos_id)
            outs.append(id_list)
        return outs
# 载入预测模型
from Seq2Seq.models import Seq2SeqInferModel
import paddle

encoder_attrs = {"vocab_size": vocab_size, "embed_dim": 200, "hidden_size": 128, "num_layers": 4, "dropout": .2,
                    "direction": "bidirectional", "mode": "GRU"}
decoder_attrs = {"vocab_size": vocab_size, "embed_dim": 200, "hidden_size": 128, "num_layers": 4, "direction": "forward",
                    "dropout": .2, "mode": "GRU", "use_attention": True}

infer_model = paddle.Model(Seq2SeqInferModel(encoder_attrs,
                                             decoder_attrs,
                                             bos_id=vocab.token_to_idx[vocab.bos_token],
                                             eos_id=vocab.token_to_idx[vocab.eos_token],
                                             beam_size=10,
                                             max_out_len=256))
infer_model.load("./final_models/model")
# 送新年祝福
# 当然,表白也可以
generator = GenPoems(vocab, infer_model)

content = "生龙活虎"
poet = generator.gen(content)
for line in poet.strip().split('。'):
    try:
        print("{}\t{}。".format(line[0], line))
    except:
        pass

输出结果

生    生涯不可见,何处不相逢。
龙    龙虎不知何处,人间不见人间。
活    活人不是人间事,不觉人间不可识。
虎    虎豹相逢不可寻,不知何处不相识。

总结

这个项目介绍了如何训练一个生成藏头诗的模型,从结果可以看出,模型已经具有一定的生成诗句的能力。但是,限于训练集规模和训练时间,生成的诗句还有很大的改进空间,未来还将进一步优化这个模型,敬请期待。

以上就是Python PaddleNLP实现自动生成虎年藏头诗的详细内容,更多关于PaddleNLP生成藏头诗的资料请关注编程网其它相关文章!

--结束END--

本文标题: PythonPaddleNLP实现自动生成虎年藏头诗

本文链接: https://www.lsjlt.com/news/163432.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • PythonPaddleNLP实现自动生成虎年藏头诗
    目录一、 数据处理1.paddlenlp升级2.提取诗头3.生成词表4.定义dataset二、定义模型并训练1.模型定义2.模型训练3.模型保存三、生成藏头诗总结一、 数据处理 本项...
    99+
    2024-04-02
  • java怎么实现api自动生成
    Java中可以使用反射和动态代理来实现API的自动生成。 使用反射:通过反射可以在运行时获取类的信息和方法的信息,可以利用这些信...
    99+
    2023-10-23
    java
  • Python实现自动生成请假条
    目录需求描述逻辑分析代码实现哈喽兄弟们,今天咱们来实现用Python来批量生成请假条,这回既学了东西又做了事情,两不误~ 本文就将基于一个真实的办公案例进行讲解如何提取Excel内容...
    99+
    2022-12-27
    Python自动生成请假条 Python生成请假条 Python 请假条
  • python实现自动生成C++代码的代码生成器
    遇到的问题 工作中遇到这么一个事,需要写很多C++的底层数据库类,但这些类大同小异,无非是增删改查,如果人工来写代码,既费力又容易出错;而借用python的代码自动生成,可以轻松搞定...
    99+
    2024-04-02
  • idea自动生成实体类怎么实现
    实现自动生成实体类的一个方法是使用反射机制和注解来实现。 首先,在需要自动生成实体类的项目中定义一个注解,例如 @Entity 注解...
    99+
    2023-10-24
    idea
  • oracle自动生成uuid的实现方法
    目录oracle自动生成uuid方法1.创建一个表2.生成uuid的语句3.添加几条数据,查询就可以看到效果oracle获取UUID乱码oracle自动生成uuid方法 1.创建一个表 create table t_us...
    99+
    2024-04-02
  • Java实现自动生成缩略图片
    本文实例为大家分享了Java实现自动生成缩略图片的具体代码,供大家参考,具体内容如下 一、自动生成缩略图方法: package writeimg;   import java.awt...
    99+
    2024-04-02
  • Python自动生成列表怎么实现
    Python可以使用for循环和列表推导式来自动生成列表。以下是两种常见的方法:1. 使用for循环生成列表:```pythonmy...
    99+
    2023-10-11
    Python
  • C#实现自动生成电子印章
    网络办公正逐渐成为常态,无纸化办公也是一个潮流,这二者需要电子签章,最简单的方法就是在纸上盖一个章然后扫描成电子图片文件,最后在你的系统加载这个签章电子图片文件。但这样就会些不理想的...
    99+
    2024-04-02
  • Vue怎么实现自定义组件自动生成
    本文小编为大家详细介绍“Vue怎么实现自定义组件自动生成”,内容详细,步骤清晰,细节处理妥当,希望这篇“Vue怎么实现自定义组件自动生成”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。就目前三大前端主流数据驱动框架...
    99+
    2023-07-04
  • php如何实现自动生成验证码
    本文操作环境:windows10系统、php 7、thinkpad t480电脑。现在验证码在表单中的应用越来越多了,但是如果用js来实现总觉得不太方便,因此使用php来实现下,在此记录下。当然,我们也可以封装成一个函数,以后使用的时候也是...
    99+
    2019-06-04
    php 验证码
  • iOS实现九宫格自动生成视图
    在移动开发里有相当多的时候需要使控件呈现九宫格格式的分布,最常见的如 图案解锁界面: 相册管理界面: 单独创建一个这样界面的步骤相当繁琐,要创建父视图用于控制每一个单独的控件,而...
    99+
    2022-05-28
    iOS 九宫格 视图
  • jpa自动生成数据表怎么实现
    JPA(Java Persistence API)是JavaEE的一个规范,用于简化Java应用程序与数据库之间的交互。JPA提供了...
    99+
    2023-10-20
    jpa
  • Babel自动生成Attribute文档实现详解
    目录1. 前言2. 开发自动生成属性文档插件2.1 生成Babel插件模板:2.2 转换思路详解:2.3 单元测试用例:2.4 AST分析详解:2.5 插件开发过程:2.5.1 定义...
    99+
    2022-11-13
    Babel生成Attribute文档 Babel Attribute
  • Babel怎么实现自动生成Attribute文档
    本篇内容主要讲解“Babel怎么实现自动生成Attribute文档”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Babel怎么实现自动生成Attribute文档”吧!1. 前言利用Babel自动...
    99+
    2023-07-04
  • 利用Python实现自动生成小学生计算题
    目录生成计算题写入Word中过年期间发现小外甥已经上小学了,我姐说老师今天给他们布置了寒假作业:每天坚持做乘法和加减法混合运算。 这我必须帮帮忙,用Python写了一段自动生成小学生...
    99+
    2023-02-07
    Python生成计算题 Python计算题
  • python怎么实现自动生成C++代码的代码生成器
    这篇文章主要讲解了“python怎么实现自动生成C++代码的代码生成器”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“python怎么实现自动生成C++代码的代码生成器”吧!遇到的问题工作中遇...
    99+
    2023-07-02
  • 利用Python实现自动生成数据日报
    目录前言需求详解数据处理前言 人生苦短,快学Python! 日报,是大部分打工人绕不过的难题。 对于管理者来说,日报是事前管理的最好抓手,可以了解团队的氛围和状态。可对于员工来说,那...
    99+
    2024-04-02
  • Java怎么实现自动生成缩略图片
    这篇文章主要介绍“Java怎么实现自动生成缩略图片”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“Java怎么实现自动生成缩略图片”文章能帮助大家解决问题。一、自动生成缩略图方法:package&nb...
    99+
    2023-06-30
  • idea单元测试自动生成怎么实现
    实现自动生成单元测试的方法可以分为以下几个步骤: 静态代码分析:通过静态代码分析工具(如静态代码分析器、AST解析器等),对待测...
    99+
    2023-10-22
    idea
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作