lstm神经网络matlab程序_使用 LSTM 智能作诗送新年祝福

使用 LSTM 智能作诗送新年祝福

LSTM 介绍

序列化数据即每个样本和它之前的样本存在关联,前一数据和后一个数据有顺序关系。深度学习中有一个重要的分支是专门用来处理这样的数据的——循环神经网络。循环神经网络广泛应用在自然语言处理领域(NLP),今天我们带你从一个实际的例子出发,介绍循环神经网络一个重要的改进算法模型-LSTM。本文章不对LSTM的原理进行深入,想详细了解LSTM可以参考这篇 [译] 理解 LSTM 网络。本文重点从古诗词自动生成的实例出发,一步一步带你从数据处理到模型搭建,再到训练出古诗词生成模型,最后实现从古诗词自动生成新春祝福诗词。

数据处理

我们使用76748首古诗词作为数据集,数据集下载链接,原始的古诗词的存储形式如下:

95b1964321837321b871841eb0759ec5.png

我们可以看到原始的古诗词是文本符号的形式,无法直接进行机器学习,所以我们第一步需要把文本信息转换为数据形式,这种转换方式就叫词嵌入(word embedding),我们采用一种常用的词嵌套(word embedding)算法-Word2vec对古诗词进行编码。关于Word2Vec这里不详细讲解,感兴趣可以参考 [NLP] 秒懂词向量Word2vec的本质。在词嵌套过程中,为了避免最终的分类数过于庞大,可以选择去掉出现频率较小的字,比如可以去掉只出现过一次的字。Word2vec算法经过训练后会产生一个模型文件,我们就可以利用这个模型文件对古诗词文本进行词嵌套编码。经过第一步的处理已经把古诗词词语转换为可以机器学习建模的数字形式,因为我们采用LSTM算法进行古诗词生成,所以还需要构建输入到输出的映射处理。例如: “[长河落日圆]”作为train_data,而相应的train_label就是“长河落日圆]]”,也就是 “[”->“长”,“长”->“河”,“河”->“落”,“落”->“日”,“日”->“圆”,“圆”->“]”,“]”->“]”,这样子先后顺序一一对相。这也是循环神经网络的一个重要的特征。 这里的“[”和“]”是开始符和结束符,用于生成古诗的开始与结束标记。

总结一下数据处理的步骤:

  • 读取原始的古诗词文本,统计出所有不同的字,使用 Word2Vec 算法进行对应编码;
  • 对于每首诗,将每个字、标点都转换为字典中对应的编号,构成神经网络的输入数据 train_data;
  • 将输入数据左移动构成输出标签 train_label;

经过数据处理后我们得到以下数据文件:

  • poems_edge_split.txt:原始古诗词文件,按行排列,每行为一首诗词;
  • vectors_poem.bin:利用 Word2Vec训练好的词向量模型,以开头,按词频排列,去除低频词;
  • poem_ids.txt:按输入输出关系映射处理之后的语料库文件;
  • rhyme_words.txt: 押韵词存储,用于押韵诗的生成;

在提供的源码中已经提供了以上四个数据文件放在data文件夹下,数据处理代码见 data_loader.py 文件,源码链接

模型构建及训练

这里我们使用2层的LSTM框架,每层有128个隐藏层节点,我们使用tensorflow.nn模块库来定义网络结构层,其中RNNcell是tensorflow中实现RNN的基本单元,是一个抽象类,在实际应用中多用RNNcell的实现子类BasicRNNCell或者BasicLSTMCell,BasicGRUCell;如果需要构建多层的RNN,在TensorFlow中,可以使用tf.nn.rnn_cell.MultiRNNCell函数对RNNCell进行堆叠。模型网络的第一层要对输入数据进行 embedding,可以理解为数据的维度变换,经过两层LSTM后,接着softMax得到一个在全字典上的输出概率。 模型网络结构如下:

76f7000af598d3783d9aedbe2aa4b321.png

定义网络的类的程序代码如下:

class CharRNNLM(object): def __init__(self, is_training, batch_size, vocab_size, w2v_model, hidden_size, max_grad_norm, embedding_size, num_layers, learning_rate, cell_type, dropout=0.0, input_dropout=0.0, infer=False): self.batch_size = batch_size self.hidden_size = hidden_size self.vocab_size = vocab_size self.max_grad_norm = max_grad_norm self.num_layers = num_layers self.embedding_size = embedding_size self.cell_type = cell_type self.dropout = dropout self.input_dropout = input_dropout self.w2v_model = w2v_model if embedding_size <= 0: self.input_size = vocab_size self.input_dropout = 0.0 else: self.input_size = embedding_size # 输入和输入定义 self.input_data = tf.placeholder(tf.int64, [self.batch_size, self.num_unrollings], name='inputs') self.targets = tf.placeholder(tf.int64, [self.batch_size, self.num_unrollings], name='targets') # 根据定义选择不同的循环神经网络内核单元 if self.cell_type == 'rnn': cell_fn = tf.nn.rnn_cell.BasicRNNCell elif self.cell_type == 'lstm': cell_fn = tf.nn.rnn_cell.LSTMCell elif self.cell_type == 'gru': cell_fn = tf.nn.rnn_cell.GRUCell params = dict() if self.cell_type == 'lstm': params['forget_bias'] = 1.0 cell = cell_fn(self.hidden_size, **params) cells = [cell] for i in range(self.num_layers-1): higher_layer_cell = cell_fn(self.hidden_size, **params) cells.append(higher_layer_cell) # 训练时是否进行 Dropout if is_training and self.dropout > 0: cells = [tf.nn.rnn_cell.DropoutWrapper(cell, output_keep_prob=1.0-self.dropout) for cell in cells] # 对lstm层进行堆叠 multi_cell = tf.nn.rnn_cell.MultiRNNCell(cells) # 定义网络模型初始状态 with tf.name_scope('initial_state'): self.zero_state = multi_cell.zero_state(self.batch_size, tf.float32) if self.cell_type == 'rnn' or self.cell_type == 'gru': self.initial_state = tuple( [tf.placeholder(tf.float32, [self.batch_size, multi_cell.state_size[idx]], 'initial_state_'+str(idx+1)) for idx in range(self.num_layers)]) elif self.cell_type == 'lstm': self.initial_state = tuple( [tf.nn.rnn_cell.LSTMStateTuple( tf.placeholder(tf.float32, [self.batch_size, multi_cell.state_size[idx][0]], 'initial_lstm_state_'+str(idx+1)), tf.placeholder(tf.float32, [self.batch_size, multi_cell.state_size[idx][1]], 'initial_lstm_state_'+str(idx+1))) for idx in range(self.num_layers)]) # 定义 embedding 层 with tf.name_scope('embedding_layer'): if embedding_size > 0: # self.embedding = tf.get_variable('embedding', [self.vocab_size, self.embedding_size]) self.embedding = tf.get_variable("word_embeddings
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值