Tensorflow:基于LSTM生成藏头诗
Tensorflow:基于LSTM生成藏头诗
最近在学习TensorFlow,学习到了RNN这一块,相关的资料不是很多,了解到使用RNN可以生成藏头诗之后,我就决定拿这个下手啦!
本文不介绍RNN以及LSTM的相关基本知识,如要了解,请自行百度。
本文是在学习了 TensorFlow7: 基于RNN生成古诗词
这一篇博客之后继续在其基础上修改的代码,若要了解相关内容可以先去上面的博客去看一下。
【注:本博客所使用的数据、代码、模型文件均已放在百度云上:
链接: https://pan.baidu.com/s/1qY4mt1y 密码: 47y2】
模型生成
首先我们要训练好模型。这里采用的是2层的LSTM框架,每层有128个隐藏层节点,batch_size设为64。训练数据来源于全唐诗(可在上面百度云资源分享当中找到)。特别注意到的一点是这里每训练完一次就对训练数据做shuffle。
源代码如下:
#!/usr/bin/python3
#-*- coding: UTF-8 -*-
import collections
import numpy as np
import tensorflow as tf #-------------------------------数据预处理---------------------------#poetry_file ='poetry.txt' # 诗集
poetrys = []
with open(poetry_file, "r") as f: for line in f: try: line = line.decode('UTF-8')line = line.strip(u'\n')title, content = line.strip(u' ').split(u':') content = content.replace(u' ',u'') if u'_' in content or u'(' in content or u'(' in content or u'《' in content or u'[' in content: continue if len(content) < 5 or len(content) > 79: continue content = u'[' + content + u']' poetrys.append(content) except Exception as e: pass # 按诗的字数排序
poetrys = sorted(poetrys,key=lambda line: len(line))
print('唐诗总数: ', len(poetrys)) # 统计每个字出现次数
all_words = []
for poetry in poetrys: all_words += [word for word in poetry]
counter = collections.Counter(all_words)
count_pairs = sorted(counter.items(), key=lambda x: -x[1])
words, _ = zip(*count_pairs) # 取前多少个常用字
words = words[:len(words)] + (' ',)
# 每个字映射为一个数字ID
word_num_map = dict(zip(words, range(len(words))))
# 把诗转换为向量形式,参考TensorFlow练习1
to_num = lambda word: word_num_map.get(word, len(words))
poetrys_vector = [ list(map(to_num, poetry)) for poetry in poetrys]
#[[314, 3199, 367, 1556, 26, 179, 680, 0, 3199, 41, 506, 40, 151, 4, 98, 1],
#[339, 3, 133, 31, 302, 653, 512, 0, 37, 148, 294, 25, 54, 833, 3, 1, 965, 1315, 377, 1700, 562, 21, 37, 0, 2, 1253, 21, 36, 264, 877, 809, 1]
#....]# 每次取64首诗进行训练
batch_size = 64
n_chunk = len(poetrys_vector) // batch_size class DataSet(object):def __init__(self,data_size):self._data_size = data_sizeself._epochs_completed = 0self._index_in_epoch = 0self._data_index = np.arange(data_size)def next_batch(self,batch_size):start = self._index_in_epochif start + batch_size > self._data_size:np.random.shuffle(self._data_index)self._epochs_completed = self._epochs_completed + 1self._index_in_epoch = batch_sizefull_batch_features ,full_batch_labels = self.data_batch(0,batch_size)return full_batch_features ,full_batch_labels else:self._index_in_epoch += batch_sizeend = self._index_in_epochfull_batch_features ,full_batch_labels = self.data_batch(start,end)if self._index_in_epoch == self._data_size:self._index_in_epoch = 0self._epochs_completed = self._epochs_completed + 1np.random.shuffle(self._data_index)return full_batch_features,full_batch_labelsdef data_batch(self,start,end):batches = []for i in range(start,end):batches.append(poetrys_vector[self._data_index[i]])length = max(map(len,batches))xdata = np.full((end - start,length), word_num_map[' '], np.int32) for row in range(end - start): xdata[row,:len(batches[row])] = batches[row] ydata = np.copy(xdata) ydata[:,:-1] = xdata[:,1:] return xdata,ydata#---------------------------------------RNN--------------------------------------#input_data = tf.placeholder(tf.int32, [batch_size, None])
output_targets = tf.placeholder(tf.int32, [batch_size, None])
# 定义RNN
def neural_network(model='lstm', rnn_size=128, num_layers=2): if model == 'rnn': cell_fun = tf.nn.rnn_cell.BasicRNNCell elif model == 'gru': cell_fun = tf.nn.rnn_cell.GRUCell elif model == 'lstm': cell_fun = tf.nn.rnn_cell.BasicLSTMCell cell = cell_fun(rnn_size, state_is_tuple=True) cell = tf.nn.rnn_cell.MultiRNNCell([cell] * num_layers, state_is_tuple=True) initial_state = cell.zero_state(batch_size, tf.float32) with tf.variable_scope('rnnlm'): softmax_w = tf.get_variable("softmax_w", [rnn_size, len(words)]) softmax_b = tf.get_variable("softmax_b", [len(words)]) with tf.device("/cpu:0"): embedding = tf.get_variable("embedding", [len(words), rnn_size]) inputs = tf.nn.embedding_lookup(embedding, input_data) outputs, last_state = tf.nn.dynamic_rnn(cell, inputs, initial_state=initial_state, scope='rnnlm') output = tf.reshape(outputs,[-1, rnn_size]) logits = tf.matmul(output, softmax_w) + softmax_b probs = tf.nn.softmax(logits) return logits, last_state, probs, cell, initial_state def load_model(sess, saver,ckpt_path):latest_ckpt = tf.train.latest_checkpoint(ckpt_path)if latest_ckpt:print ('resume from', latest_ckpt)saver.restore(sess, latest_ckpt)return int(latest_ckpt[latest_ckpt.rindex('-') + 1:])else:print ('building model from scratch')sess.run(tf.global_variables_initializer())return -1#训练
def train_neural_network(): logits, last_state, _, _, _ = neural_network() targets = tf.reshape(output_targets, [-1]) loss = tf.nn.seq2seq.sequence_loss_by_example([logits], [targets], [tf.ones_like(targets, dtype=tf.float32)], len(words)) cost = tf.reduce_mean(loss) learning_rate = tf.Variable(0.0, trainable=False) tvars = tf.trainable_variables() grads, _ = tf.clip_by_global_norm(tf.gradients(cost, tvars), 5) #optimizer = tf.train.GradientDescentOptimizer(learning_rate)optimizer = tf.train.AdamOptimizer(learning_rate) train_op = optimizer.apply_gradients(zip(grads, tvars)) Session_config = tf.ConfigProto(allow_soft_placement=True)Session_config.gpu_options.allow_growth = True trainds = DataSet(len(poetrys_vector))with tf.Session(config=Session_config) as sess:with tf.device('/gpu:2'): sess.run(tf.initialize_all_variables()) saver = tf.train.Saver(tf.all_variables())last_epoch = load_model(sess, saver,'model/') for epoch in range(last_epoch + 1,100):sess.run(tf.assign(learning_rate, 0.002 * (0.97 ** epoch))) #sess.run(tf.assign(learning_rate, 0.01))all_loss = 0.0 for batche in range(n_chunk): x,y = trainds.next_batch(batch_size)train_loss, _ , _ = sess.run([cost, last_state, train_op], feed_dict={input_data: x, output_targets: y}) all_loss = all_loss + train_loss if batche % 50 == 1:#print(epoch, batche, 0.01,train_loss)print(epoch, batche, 0.002 * (0.97 ** epoch),train_loss) saver.save(sess, 'model/poetry.module', global_step=epoch) print (epoch,' Loss: ', all_loss * 1.0 / n_chunk) train_neural_network()
使用该代码会将训练好的模型参数保存在 “model” 文件夹下。经过100个epoch之后,平均loss会降到2.6左右。训练好的模型也已经放在了上面分享的百度云资源当中。
生成古诗
使用训练好的模型可以轻松生成各种古诗。
下面就是几个例子:
生成藏头诗
上代码:
#!/usr/bin/python3
#-*- coding: UTF-8 -*-
import collections
import numpy as np
import tensorflow as tf
'''
This one will produce a poetry with heads.
'''#-------------------------------数据预处理---------------------------#poetry_file ='poetry.txt' # 诗集
poetrys = []
with open(poetry_file, "r") as f: for line in f: try: line = line.decode('UTF-8')line = line.strip(u'\n')title, content = line.strip(u' ').split(u':') content = content.replace(u' ',u'') if u'_' in content or u'(' in content or u'(' in content or u'《' in content or u'[' in content: continue if len(content) < 5 or len(content) > 79: continue content = u'[' + content + u']' poetrys.append(content) except Exception as e: pass # 按诗的字数排序
poetrys = sorted(poetrys,key=lambda line: len(line))
print('唐诗总数: ', len(poetrys)) # 统计每个字出现次数
all_words = []
for poetry in poetrys: all_words += [word for word in poetry]
counter = collections.Counter(all_words)
count_pairs = sorted(counter.items(), key=lambda x: -x[1])
words, _ = zip(*count_pairs) # 取前多少个常用字
words = words[:len(words)] + (' ',)
# 每个字映射为一个数字ID
word_num_map = dict(zip(words, range(len(words))))
# 把诗转换为向量形式,参考TensorFlow练习1
to_num = lambda word: word_num_map.get(word, len(words))
poetrys_vector = [ list(map(to_num, poetry)) for poetry in poetrys]
#[[314, 3199, 367, 1556, 26, 179, 680, 0, 3199, 41, 506, 40, 151, 4, 98, 1],
#[339, 3, 133, 31, 302, 653, 512, 0, 37, 148, 294, 25, 54, 833, 3, 1, 965, 1315, 377, 1700, 562, 21, 37, 0, 2, 1253, 21, 36, 264, 877, 809, 1]
#....]# 每次取64首诗进行训练
batch_size = 1
n_chunk = len(poetrys_vector) // batch_size class DataSet(object):def __init__(self,data_size):self._data_size = data_sizeself._epochs_completed = 0self._index_in_epoch = 0self._data_index = np.arange(data_size)def next_batch(self,batch_size):start = self._index_in_epochif start + batch_size > self._data_size:np.random.shuffle(self._data_index)self._epochs_completed = self._epochs_completed + 1self._index_in_epoch = batch_sizefull_batch_features ,full_batch_labels = self.data_batch(0,batch_size)return full_batch_features ,full_batch_labels else:self._index_in_epoch += batch_sizeend = self._index_in_epochfull_batch_features ,full_batch_labels = self.data_batch(start,end)if self._index_in_epoch == self._data_size:self._index_in_epoch = 0self._epochs_completed = self._epochs_completed + 1np.random.shuffle(self._data_index)return full_batch_features,full_batch_labelsdef data_batch(self,start,end):batches = []for i in range(start,end):batches.append(poetrys_vector[self._data_index[i]])length = max(map(len,batches))xdata = np.full((end - start,length), word_num_map[' '], np.int32) for row in range(end - start): xdata[row,:len(batches[row])] = batches[row] ydata = np.copy(xdata) ydata[:,:-1] = xdata[:,1:] return xdata,ydata#---------------------------------------RNN--------------------------------------#input_data = tf.placeholder(tf.int32, [batch_size, None])
output_targets = tf.placeholder(tf.int32, [batch_size, None])
# 定义RNN
def neural_network(model='lstm', rnn_size=128, num_layers=2): if model == 'rnn': cell_fun = tf.nn.rnn_cell.BasicRNNCell elif model == 'gru': cell_fun = tf.nn.rnn_cell.GRUCell elif model == 'lstm': cell_fun = tf.nn.rnn_cell.BasicLSTMCell cell = cell_fun(rnn_size, state_is_tuple=True) cell = tf.nn.rnn_cell.MultiRNNCell([cell] * num_layers, state_is_tuple=True) initial_state = cell.zero_state(batch_size, tf.float32) with tf.variable_scope('rnnlm'): softmax_w = tf.get_variable("softmax_w", [rnn_size, len(words)]) softmax_b = tf.get_variable("softmax_b", [len(words)]) with tf.device("/cpu:0"): embedding = tf.get_variable("embedding", [len(words), rnn_size]) inputs = tf.nn.embedding_lookup(embedding, input_data) outputs, last_state = tf.nn.dynamic_rnn(cell, inputs, initial_state=initial_state, scope='rnnlm') output = tf.reshape(outputs,[-1, rnn_size]) logits = tf.matmul(output, softmax_w) + softmax_b probs = tf.nn.softmax(logits) return logits, last_state, probs, cell, initial_state #-------------------------------生成古诗---------------------------------#
# 使用训练完成的模型def gen_head_poetry(heads, type):if type != 5 and type != 7:print 'The second para has to be 5 or 7!'return def to_word(weights): t = np.cumsum(weights) s = np.sum(weights) sample = int(np.searchsorted(t, np.random.rand(1)*s)) return words[sample] _, last_state, probs, cell, initial_state = neural_network()Session_config = tf.ConfigProto(allow_soft_placement = True)Session_config.gpu_options.allow_growth=True with tf.Session(config=Session_config) as sess: with tf.device('/gpu:1'): sess.run(tf.initialize_all_variables()) saver = tf.train.Saver(tf.all_variables()) saver.restore(sess, 'model/poetry.module-99')poem = ''for head in heads:flag = Truewhile flag:state_ = sess.run(cell.zero_state(1, tf.float32)) x = np.array([list(map(word_num_map.get, u'['))]) [probs_, state_] = sess.run([probs, last_state], feed_dict={input_data: x, initial_state: state_}) sentence = headx = np.zeros((1,1)) x[0,0] = word_num_map[sentence] [probs_, state_] = sess.run([probs, last_state], feed_dict={input_data: x, initial_state: state_}) word = to_word(probs_)sentence += word while word != u'。': x = np.zeros((1,1)) x[0,0] = word_num_map[word] [probs_, state_] = sess.run([probs, last_state], feed_dict={input_data: x, initial_state: state_}) word = to_word(probs_)sentence += word if len(sentence) == 2 + 2 * type:sentence += u'\n'poem += sentenceflag = Falsereturn poemprint(gen_head_poetry(u'天下之大',5))
最后从函数接口可以看到,除了可以自己定义诗的头外,还可以定义是五言绝句还是七言绝句。
来看几个五言绝句的例子:
再来看几个七言绝句的例子:
那么是不是可以用它来写情诗呢?
当然可以啦!
参考文献:
[1]. http://blog.csdn.net/u014365862/article/details/53868544
Tensorflow:基于LSTM生成藏头诗相关推荐
- 自然语言处理实战-基于LSTM的藏头诗和古诗自动生成
自然语言处理实战-基于LSTM的藏头诗和古诗自动生成 第一次写也是自己的第一篇博客,分享一下自己做的实验以及遇到的一些问题和上交的结课作业.资源都是开源的,参考文章写的很好,菜鸟的我也能理解.原文链接 ...
- 基于RNN循环神经网络lstm的藏头诗制作
基于RNN循环神经网络lstm的藏头诗制作 简单介绍 在一次偶然中接触到藏头诗,觉得十分有意思.但是好像都是利用古代本就有的诗句重新组合而成.比如输入清风袭来,结果如下图所示. 之后想到不如利用深度学 ...
- 基于 Django 的藏头诗生成
基于 Django 的藏头诗生成 环境 Windows 10 Python 3.7 Django 3.0 PyCharm 2019 具体实现 配置方面的东西在这里就不再赘述,请看之前的一篇文章,连接为 ...
- python输出一首诗_用Python自动生成藏头诗
本文首发于公众号「老肥码码码」 前几天老肥给大家介绍了有意思的藏头诗,今天我们就来自己根据输入语句实现自动生成藏头藏尾诗吧. 整个诗句生成的逻辑是这样的,先根据输入语句爬取符合要求的诗句(来自百度汉语 ...
- python中生成藏头诗
可以使用 Python 库 NLTK(Natural Language Toolkit)来生成藏头诗.具体实现方法如下: 安装 NLTK 库,在命令行中运行 pip install nltk. 引入库 ...
- 一键生成藏头诗小程序源码
简介: 简单的小程序源码,后台须调用天行api的接口 上线步骤: 1.百度注册天行数据,完成邮箱验证 2.找到藏头诗生成api,点击申请即可出现key页面,初期是免费调用额度的,绑定微信增加10000 ...
- 【PyTorch】3 AI诗人RNN实战(LSTM)——完成诗歌剩余部分、生成藏头诗
用RNN写诗 1. 背景 2. 数据描述 3. 数据使用 4. LSTM函数 5. Model 6. Train 7. Test 8. 全部代码 小结 1. 背景 书上的内容可见此,一些关于此的博客1 ...
- Python PaddleNLP实现自动生成虎年藏头诗
这篇文章主要介绍了利用Python PaddleNLP实现自动生成虎年藏头诗功能,文中的示例代码讲解详细,感兴趣的同学可以跟随小编一起试一试.Python编程学习资料点击免费领取 目录 1.paddl ...
- PyTorch入门笔记——RNN写诗(含藏头诗)程序代码学习笔记
目录 注意事项 一.数据介绍 二.opt对象 三.data.py 四.☆model.py 五.utils.py封装可视化操作,略 六.main.py 了解`torch.utils.data.DataL ...
最新文章
- 【数据结构】所有顶点对的最短路径 Floyd算法
- GitHub 博客-- Jekyll--代码高亮,Liquid 转义字符
- LeetCode19删除链表的倒数第N个节点20有效的括号
- JAVA——基于HttpClient的正方教务系统[1999-2020]模拟登录|模拟退出|课程查询|成绩查询|考试查询基本解决方案
- python方差特征选择_使用scikitlearn进行方差分析的特征选择和交叉验证
- java Concurrent包学习笔记(一):ExecutorService
- Fabric中的Transient Data与Private Data
- 对C#开发两个基本原则的深入讨论
- 计算机中那些事儿(二):如何神操作你的电脑
- MediaPlayer对象从停止状态到播放状态调用的方法是prepare()和start()
- SqlConnection调用Dispose方法之后还可以在连接池中复用吗?
- 了解SQL Server SELECT INTO语句
- python max_Python max()
- Delphi2010
- html 简单动画效果,HTML-简单动画
- java解惑--谜题11:最后的笑声
- 流处理和批处理框架的异同
- java记忆翻牌_html5记忆翻牌游戏
- 马虎词汇教程21-25(转载)
- Unix哲学学习笔记
热门文章
- 如何语音翻译?我推荐这三个语音翻译软件,真的好用
- 传统的获客渠道方式对比包获客,你更认可哪一种?
- 天路协同办公管理系统解决方案[1]
- 从cocos看国内自研的游戏引擎
- 联想G510主机编号:CB31947311
- 正元工程资料管理免安装_智能化建筑弱电安装工程管理的研究
- 预览word文件,支持下载(微软提供)
- 堪培拉地理位置经纬度_非洲国家主要城市经纬度
- moment 当前周一到周日_记一次用momentjs获取一年内所有周的起始时间遇到的bug
- 超级计算机cdc6600,超级计算机现状和发发展趋势精选.ppt