一文详解 LSTM 诗词生成

本文介绍如何使用LSTM网络生成藏头诗,详细讲解了模型搭建、参数加载及诗词生成过程。采用TensorFlow框架,实现了一个基于LSTM的诗词生成系统。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

LSTM简单介绍

长短时记忆网络(Long Short Term Memory Network, LSTM),是一种改进之后的循环神经网络,可以解决RNN无法处理长距离的依赖的问题,目前比较流行。

长短时记忆网络的思路:

原始 RNN 的隐藏层只有一个状态,即h,它对于短期的输入非常敏感。再增加一个状态,即c,让它来保存长期的状态,称为单元状态(cell state)。

 

正文开始

在本文章节,我们会利用lstm来进行一个诗词,藏头诗的生成系统,推荐安装的各个版本如下:

python>3.6
tensorflow>1.14
numpy

好的,我们现在开始

第一步,载入RNN模型

第一步

TextConverter是文字处理相关的配置文件,请自行在我博客下载

CharRNN为RNN模型读取与载入

import tensorflow as tf
from read_utils import TextConverter
import numpy as np
import os

converter = TextConverter(filename="./model/default/converter.pkl")
num_classes = converter.vocab_size

第二步,重置tf图

tf.reset_default_graph()

第三步,构建RNN输入

with tf.name_scope('inputs'):
    inputs = tf.placeholder(tf.int32, shape=(1,1),name='inputs')
    targets = tf.placeholder(tf.int32, shape=(1,1),name='targets')
    keep_prob = tf.placeholder(tf.float32, name='keep_prob')

    with tf.device("/cpu:0"):
        embedding = tf.get_variable('embedding', [num_classes, 128])
        lstm_inputs = tf.nn.embedding_lookup(embedding, inputs)

第四步,构建LSTM模型

# 创建单个cell并堆叠多层
def lstm_cell(lstm_size, keep_prob):
    lstm = tf.nn.rnn_cell.BasicLSTMCell(lstm_size)
    drop = tf.nn.rnn_cell.DropoutWrapper(lstm, output_keep_prob=keep_prob)
    return drop

with tf.name_scope('lstm'):
    cell = tf.nn.rnn_cell.MultiRNNCell(
        [lstm_cell(128, keep_prob) for _ in range(2)]
    )
    
    initial_state = cell.zero_state(1, tf.float32)
    pred_state = None

    # 通过dynamic_rnn对cell展开时间维度
    lstm_outputs, final_state = tf.nn.dynamic_rnn(cell, 
                                                  lstm_inputs, 
                                                  initial_state=initial_state)

    # 通过lstm_outputs得到概率
    seq_output = tf.concat(lstm_outputs, 1)
    x = tf.reshape(seq_output, [-1, 128])

    with tf.variable_scope('softmax'):
        softmax_w = tf.Variable(tf.truncated_normal([128, num_classes], stddev=0.1))
        softmax_b = tf.Variable(tf.zeros(num_classes))

    logits = tf.matmul(x, softmax_w) + softmax_b
    proba_prediction = tf.nn.softmax(logits, name='predictions')

第五步,回复LSTM网络参数

saver = tf.train.Saver()
checkpoint_path = "./model/default"
checkpoint =tf.train.latest_checkpoint(checkpoint_path)
session = tf.Session()
saver.restore(session, checkpoint)

第六步,定义一些数据处理方法,包括模型预测等

#随机挑选字词
def pick_top_n(preds, vocab_size, top_n=5):
    p = np.squeeze(preds)
    # 将除了top_n个预测值的位置都置为0
    p[np.argsort(p)[:-top_n]] = 0
    # 归一化概率
    p = p / np.sum(p)
    # 随机选取一个字符
    c = np.random.choice(vocab_size, 1, p=p)[0]
    return c

#模型预测函数
def forecast(input_char):
    global num_class
    global pred_state
    global proba_prediction
    global final_state
    global inputs
    global keep_prob
    global initial_state
    global session
    
    x = np.asarray([[input_char]])
    feed = {
            inputs:x,
            keep_prob:1.0,
            initial_state:pred_state
    }

    preds,pred_state = session.run([proba_prediction,final_state],feed_dict = feed)
    return pick_top_n(preds,num_classes)

def init_pred_state():
    global pred_state
    global initial_state
    global session
    pred_state = session.run(initial_state)

第七步,诗词生成逻辑,

转化第一句诗词,生成后续,并初始化lstm状态

start = converter.text_to_arr("青青河边草")
init_pred_state()

 构建藏头诗,逻辑非常简单,就是根据输入的每个词,都连续生成五个字

sample = []
for c in start:
    sample.append(c)
    preds = forecast(c)

    whole = 4
    if(preds == 2 or preds == 1 or preds == 0 or preds == 3500):
        pass
    else:
        whole = 3
        sample.append(preds)

    gen_number = 0
    while gen_number < whole:
        preds = forecast(preds)
        if(preds == 2 or preds == 1 or preds == 0 or preds == 3500):
            continue
        sample.append(preds)
        gen_number += 1
    sample.append(2)
#插入换行符
sample = np.asarray(sample)

 好啦,结果出来啦,我们把它打印出来

然后我们很贴心的为它做了一个web系统,详情请见我的上篇博文以及我的视频号:碳纤维石头君(B占)

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

梅赛德斯巴伐马

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值