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占)

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

被折叠的 条评论
为什么被折叠?



