python输出⼀⾸诗_基于循环神经⽹络(RNN)的古诗⽣成器基于循环神经⽹络(RNN)的古诗⽣成器,具体内容如下
之前在⼿机百度上看到有个“为你写诗”功能,能够随机⽣成古诗,当时感觉很酷炫= =
在学习了深度学习后,了解了⼀下原理,打算⾃⼰做个实现练练⼿,于是,就有了这个项⽬。⽂中如有瑕疵纰漏之处,还请路过的诸位⼤佬不吝赐教,万分感谢!
使⽤循环神经⽹络实现的古诗⽣成器,能够完成古体诗的⾃动⽣成。我简单地训练了⼀下,格式是对上了,⾄于意境么。。。emmm,呵呵
举⼀下模型测试结果例⼦:
1.⽣成古体诗
⽰例1:
树阴飞尽⽔三依,谩⾃为能厚景奇。
莫怪仙⾈欲西望,楚⼈今此惜春风。
⽰例2:
岩外前苗点有泉,紫崖烟霭碧芊芊。
似僧⽉明秋更好,⼀踪颜事欲犹伤?
2.⽣成藏头诗(以“神策”为例)
⽰例1:
神照隆祭测馨尘,策紫珑氲⽻团娟。
⽰例2:
神辇莺满花台潭,策穷渐见仙君地。
下⾯记录项⽬实现过程(由于都是⽂本处理⽅⾯,跟前⼀个项⽬存在很多类似的内容,对于这部分内容,我就只简单提⼀下,不展开了,新的东西再具体说):
1.数据预处理
数据集使⽤四万⾸的唐诗训练集,可以点击这⾥进⾏下载。
数据预处理的过程与前⼀个项⽬TensorFlow练⼿项⽬⼀:使⽤循环神经⽹络(RNN)实现影评情感分类⼤同⼩异,可以参考前⼀个项⽬,这⾥就不多说了,直接上代码。
# -*- coding: utf-8 -*-
# @Time : 18-3-13 上午11:04
# @Author : AaronJny
# @Email : Aaron__7@163
import sys
reload(sys)
sys.setdefaultencoding('utf8')
import collections
ORIGIN_DATA = 'origin_' # 源数据路径
OUTPUT_DATA = 'processed_' # 输出向量路径
VOCAB_DATA = 'vocab/poetry.vocab'
def word_to_id(word, id_dict):
if word in id_dict:
return id_dict[word]
else:
return id_dict['']
variable used in lambdapoetry_list = [] # 存放唐诗的数组
# 从⽂件中读取唐诗
with open(ORIGIN_DATA, 'r') as f:
f_lines = f.readlines()
print '唐诗总数 : {}'.format(len(f_lines))
# 逐⾏进⾏处理
for line in f_lines:
# 去除前后空⽩符,转码
strip_line = line.strip().decode('utf8')
try:
# 将唐诗分为标题和内容
title, content = strip_line.split(':')
except:
# 出现多个':'的将被舍弃
continue
# 去除内容中的空格
content = content.strip().replace(' ', '')
# 舍弃含有⾮法字符的唐诗
if '(' in content or '(' in content or '<' in content or '《' in content or '_' in content or '[' in content: continue
# 舍弃过短或过长的唐诗
lenth = len(content)
if lenth < 20 or lenth > 100:
continue
# 加⼊列表
poetry_list.append('s' + content + 'e')
print '⽤于训练的唐诗数 : {}'.format(len(poetry_list))
poetry_list=sorted(poetry_list,key=lambda x:len(x))
words_list = []
# 获取唐诗中所有的字符
for poetry in poetry_list:
d([word for word in poetry])
# 统计其出现的次数
counter = collections.Counter(words_list)
# 排序
sorted_words = sorted(counter.items(), key=lambda x: x[1], reverse=True)
# 获得出现次数降序排列的字符列表
words_list = [''] + [x[0] for x in sorted_words]
# 这⾥选择保留⾼频词的数⽬,词只有不到七千个,所以我全部保留
words_list = words_list[:len(words_list)]
print '词汇表⼤⼩ : {}'.format(words_list)
with open(VOCAB_DATA, 'w') as f:
for word in words_list:
f.write(word + '\n')
# ⽣成单词到id的映射
word_id_dict = dict(zip(words_list, range(len(words_list))))
# 将poetry_list转换成向量形式
id_list=[]
for poetry in poetry_list:
id_list.append([str(word_to_id(word,word_id_dict)) for word in poetry])
# 将向量写⼊⽂件
with open(OUTPUT_DATA, 'w') as f:
for id_l in id_list:
f.write(' '.join(id_l) + '\n')
2.模型编写
这⾥要编写两个模型,⼀个⽤于训练,⼀个⽤于验证(⽣成古体诗)。两个模型⼤体上⼀致,因为⽤途不同,所以有些细节有出⼊。当进⾏验证时,验证模型读取训练模型的参数进⾏覆盖。
注释⽐较细,就不多说了,看代码。对于两个模型不同的⼀些关键细节,我也⽤注释进⾏了说明。
# -*- coding: utf-8 -*-
# @Time : 18-3-13 下午2:06
# @Author : AaronJny
# @Email : Aaron__7@163
import tensorflow as tf
import functools
import setting
HIDDEN_SIZE = 128 # LSTM隐藏节点个数
NUM_LAYERS = 2 # RNN深度
def doublewrap(function):
@functools.wraps(function)
def decorator(*args, **kwargs):
if len(args) == 1 and len(kwargs) == 0 and callable(args[0]): return function(args[0])
else:
return lambda wrapee: function(wrapee, *args, **kwargs) return decorator
@doublewrap
def define_scope(function, scope=None, *args, **kwargs): attribute = '_cache_' + function.__name__
name = scope or function.__name__
@property
@functools.wraps(function)
def decorator(self):
if not hasattr(self, attribute):
with tf.variable_scope(name, *args, **kwargs):
setattr(self, attribute, function(self))
return getattr(self, attribute)
return decorator
class TrainModel(object):
"""
训练模型
"""
def __init__(self, data, labels, emb_keep, rnn_keep):
self.data = data # 数据
self.labels = labels # 标签
<_keep = rnn_keep # lstm层dropout保留率
self.global_step
self.predict
self.loss
self.optimize
@define_scope
def cell(self):
"""
rnn⽹络结构
:return:
"""
lstm_cell = [
<_cell._cell.BasicLSTMCell(HIDDEN_SIZE), output_keep__keep) for _ in range(NUM_LAYERS)]
cell = _cell.MultiRNNCell(lstm_cell)
return cell
@define_scope
def predict(self):
"""
定义前向传播
:return:
"""
# 创建词嵌⼊矩阵权重
embedding = tf.get_variable('embedding', shape=[setting.VOCAB_SIZE, HIDDEN_SIZE])
# 创建softmax层参数
if setting.SHARE_EMD_WITH_SOFTMAX:
softmax_weights = tf.transpose(embedding)
else:
softmax_weights = tf.get_variable('softmaweights', shape=[HIDDEN_SIZE, setting.VOCAB_SIZE])
softmax_bais = tf.get_variable('softmax_bais', shape=[setting.VOCAB_SIZE])
# 进⾏词嵌⼊
emb = bedding_lookup(embedding, self.data)
# dropout
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论