前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >使用RNN的NLP —您可以成为下一个莎士比亚吗?

使用RNN的NLP —您可以成为下一个莎士比亚吗?

作者头像
代码医生工作室
发布2020-05-07 16:46:22
9580
发布2020-05-07 16:46:22
举报
文章被收录于专栏:相约机器人相约机器人

是否想过智能键盘上的预测键盘之类的工具如何工作?在本文中,探讨了使用先验信息生成文本的想法。具体来说,将使用Google Colab上的递归神经网络(RNN)和自然语言处理(NLP),从16世纪文献中产生文章。这个想法很简单,将尝试为模型提供莎士比亚剧本的样本,以产生所有假零件,同时保持相同的本地语言。虽然预测性键盘会为可能包含多个单词的不完整句子生成最佳的“单个单词”匹配,但通过使用单个单词生成莎士比亚戏剧的一部分,将使此过程更加困难。

了解NLP和RNN

首先刷新用于NLP的RNN的概念。RNN被广泛用于预测。RNN的数据集约束是它应该采用时间序列的形式。NLP是人工智能领域,使机器能够读取,理解和查找文本数据中的模式。

可以将文本中的字母转换为数字,并将其输入RNN模型中,以产生下一个可能的结果(诸如预测之类的声音,对吗?)

RNN的变化

该图表示不同RNN的内部机制

RNN具有循环机制,该循环机制用作允许信息从一个步骤流到下一步骤的路径。此信息是隐藏状态,它表示以前的输入。

RNN有许多不同的变体,最常见的是LSTM(长期记忆)。在本文中,将使用一种鲜为人知的变体,称为门控循环单位(GRU)。简单RNN和GRU之间的主要区别在于,后者支持隐藏状态的门控。如前所述,隐藏状态使能够输入先前时间步长中的信息。因此,RNN和GRU的区别在于传递信息的方式。区别在于专用机制,用于何时应该更新隐藏状态以及何时应该重置隐藏状态。

首先,很难掌握LSTM和GRU。总而言之,GRU与LSTM非常相似。唯一的区别是GRU没有单元状态,而是使用隐藏状态传递信息。实际上,GRU有两个门:更新门和重置门。所述更新门作用类似于一个LSTM的忘记和输入门。它决定丢弃哪些信息以及添加哪些新信息。该复位门是用来决定多少过去的信息忘记另一个门。

现在哪一个有好处?一个简单的RNN,LSTM,GRU?就像生活中的所有事物一样,没有什么是明确的。一切都取决于用例,数据量和性能。因此,决定权取决于每个人!

使用GRU生成莎士比亚戏剧

现在将使用剧本《罗密欧与朱丽叶》中的文字来产生一些模仿16世纪文学作品的“假段落”。为此提取了一定数量的数据。

数据集链接

https://www.gutenberg.org/ebooks/1112

可以从.txt文件中删除该书的初始页面,该文件包含内容和致谢部分。这将有助于产生更好的模型。

将开发一个模型,该模型使用先前的字符序列来预测下一个最高概率的字符。必须谨慎使用多少个字符。一方面,使用很长的序列将需要大量的训练时间,并且很可能过度适合与字符集无关的字符序列。另一方面,太短的序列将不适合我们的模型。因此根据已有数据的长度来建立直觉。根据正常短语的长度,将使用一个单词来预测接下来的180个字符。

是时候行动起来了!请按照以下步骤操作:

注意:下面提供了Google colab链接

步骤1:数据导入和基本功能

代码语言:javascript
复制
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import tensorflow as tf
  • 导入数据集(Google colab示例)
代码语言:javascript
复制
input_text = uploaded[‘romeo_juliet.txt’].decode(“utf-8”)

步骤2:资料预处理

创建一组独特的字符:

代码语言:javascript
复制
letter_corpus = sorted(set(input_text))
letter_corpus[:10]

将字母编码为数字

代码语言:javascript
复制
char_to_ind = {u:i for i, u in enumerate(letter_corpus)}
ind_to_char = np.array(letter_corpus)
encoded_text = np.array([char_to_ind[c] for c in input_text])

步骤3:检查顺序

每个句子的长度为43,如果捕获三个句子,则该模型应该能够选择模式并学习它们。

代码语言:javascript
复制
part_stanza = “””Chor. Two households, both alike in dignity,
In fair Verona, where we lay our scene,
From ancient grudge break to new mutiny,
Where civil blood makes civil hands unclean”””
len(part_stanza)
#Output - 181

步骤4:训练顺序

代码语言:javascript
复制
seq_len = 180
total_num_seq = len(input_text)//(seq_len+1)
#We obtain 972 sequences
char_dataset = tf.data.Dataset.from_tensor_slices(encoded_text)
sequences = char_dataset.batch(seq_len+1, drop_remainder=True)
#drop_remainder=True ensures that the last batch gets dropped if it #has less number of words
  • 将序列映射到数据集
代码语言:javascript
复制
dataset = sequences.map(create_seq_targets)

步骤5:建立批次

代码语言:javascript
复制
batch_size = 1
buffer_size = 10000
dataset = dataset.shuffle(buffer_size).batch(batch_size, drop_remainder=True)

是时候建立网络了

代码语言:javascript
复制
vocab_size = len(letter_corpus)
embed_dim = 64
rnn_neurons = 1026

导入张量流模型,层和损失函数

代码语言:javascript
复制
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import LSTM,Dense,Embedding,Dropout,GRU
from tensorflow.keras.losses import sparse_categorical_crossentropy

定义损失函数

代码语言:javascript
复制
def sparse_cat_loss(y_true,y_pred):
 return sparse_categorical_crossentropy(y_true, y_pred,   
 from_logits=True)

创建模型

代码语言:javascript
复制
def create_model(vocab_size, embed_dim, rnn_neurons, batch_size):
 model = Sequential()
 model.add(Embedding(vocab_size, embed_dim,batch_input_shape=
 [batch_size, None]))
      model.add(GRU(rnn_neurons,return_sequences=True,stateful=True,recurrent_initializer=’glorot_uniform’))
# Final Dense Layer to Predict
model.add(Dense(vocab_size))
model.compile(optimizer=’adam’, loss=sparse_cat_loss, metrics = ['accuracy'])
return model
model = create_model( vocab_size = vocab_size, embed_dim=embed_dim, rnn_neurons=rnn_neuron

我们的模型现在看起来像这样:

代码语言:javascript
复制
model.summary()

模型架构

训练时间

将纪元设置为30

代码语言:javascript
复制
epochs = 30

训练模型。请注意,这将需要一些时间。花了大约40分钟的时间来训练数据集

代码语言:javascript
复制
model.fit(dataset,epochs=epochs)

模型评估

在下面的代码中保存模型历史记录并绘制报告指标

代码语言:javascript
复制
losses = pd.DataFrame(model.history.history)
 
losses[[‘loss’,’accuracy’]].plot()

GRU模型训练结果

注意损失如何减少直到第20个时期,然后急剧上升。在第18个时代获得的最高准确度是86.03%。因此已经将模型训练了18个时期。

生成文字

定义一个函数(不固定种子)以使用1的序列生成文本。如果已经用两个单词训练了模型,那么模型会更强大,但是训练时间会增加。

代码语言:javascript
复制
def generate_text(model, start_seed,gen_size=100,temp=1.0):
num_generate = gen_size
input_eval = [char_to_ind[s] for s in start_seed]
input_eval = tf.expand_dims(input_eval, 0)
text_generated = []
temperature = temp
model.reset_states()
for i in range(num_generate):
 # Generate Predictions
 predictions = model(input_eval)
 # Remove the batch shape dimension
 predictions = tf.squeeze(predictions, 0)
 # Use a cateogircal disitribution to select the next character
 predictions = predictions / temperature
 predicted_id = tf.random.categorical(predictions, num_samples=1)[-1,0].numpy()
 # Pass the predicted charracter for the next input
 input_eval = tf.expand_dims([predicted_id], 0)
 # Transform back to character letter
 text_generated.append(ind_to_char[predicted_id])
return (start_seed + ‘’.join(text_generated))

对于生成,可以使用以下代码,只需指定起始单词和连续单词的数量即可。

代码语言:javascript
复制
print(generate_text(model,”But”,gen_size=1000))

输出量

获得了“flower”一词的以下输出

代码语言:javascript
复制
flowers, with power,
thitiest ince to speak.
Enter Lady, packed turnare didomaid,
 O hands the fair creastrim! bystalt me this sare!
 Out you? O, pies, peach, ar, and outsides.
Enter Julie.
Cep.’ Hath you, Caup with such scater, ose must reports! colal, with so smally,
 ‘Year ‘ads-noods withal.
Cap. Ay thou hast thou been shopy sender hase.
Ey’ WAtch make close curtain, with the humour times.
 O, good night, s oppriwite up, in displayd-by so night raught
 Shall back that hous shalt confurers to away in this?
Jul. He case us borny, my chall, is fould wish permission.
 Give me thy shrew, so bir, sighs all,
 Apphrel thee but but my lips?
Jul. Ay, noinot makes, I cave me not doth she country.
Man. The sorisim! O O, Capulet,
 Mush fairence the murte-baggage of Montaghous.
 Where viewild you but ny yo,
 Her simps to the-
Ben.

注意模型如何初始化Juliet和Ben的名称。此外它在句子以标点符号结尾时采用模式,并模仿16世纪散文,例如Ey,thee,thou等。

单词“But”的输出

代码语言:javascript
复制
But,
 Who say wethith is the day purg’d which your bight!
 Are providunity nurse, that mark much soul-
D.ASCup on phforight or verfain, is doth compirications comes and curnais,
 How?
 Allotions back,
 Where I sear and kindroud.
 A plaguage of gracksten, creptain!
 Show her plamangled us, now, sir?
Wife. Spaker, you, sir.
Cap. What [and] Buy Halth will’dinging, non, and pular our soul
 And lovely dreamerly eress murkdeds
 Whose she beshes eyes will be in thy brace!
Enter Appraide his banished.
Ben. I can you like whose’s keaus.
Speak. ’Tis answer ‘I’ shall up, corpudin!
 She [and by] Well, sight as as a know this may be the hight comes Refuchis works corns.
Par. So am I conduct and Montague, Commend.
Extut may cell till me comes she wret?
 Marry, the maid shrifid- grovimeo,
 Whoce arm Louren lover’d right.
 Th

这种模式太好了!

结论

看到模型模仿了《罗密欧与朱丽叶》剧本的创作方式。注意提到字符的句子的开头。此外整个白话被复制。

除了使用Romeo和Juliet训练模型外,还希望对Pride and Prejudice等其他文本以及Edmunds的汽车评论采取类似的方法。虽然前者的模型训练显示出希望,但后者没有达到期望。具体来说,对于评论,该模型无法最佳执行,因为它找不到模式。这很可能与撰写评论的方式有关。大多数人的写作风格不同,这使得模型很难模仿散文。

将来,在查看推文时探索这种方法以及如何使用假推文实现这种模型将很有趣。但是为什么只发推文呢?理想情况下,还可以查看虚假的在线文章,甚至虚假的WhatsApp新闻(尤其是在选举期间)。

可以找到以下代码的链接:

https://github.com/chandravenky/Generating-Text-using-RNN

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-04-22,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 相约机器人 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
NLP 服务
NLP 服务(Natural Language Process,NLP)深度整合了腾讯内部的 NLP 技术,提供多项智能文本处理和文本生成能力,包括词法分析、相似词召回、词相似度、句子相似度、文本润色、句子纠错、文本补全、句子生成等。满足各行业的文本智能需求。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档