是否想过智能键盘上的预测键盘之类的工具如何工作?在本文中,探讨了使用先验信息生成文本的想法。具体来说,将使用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:数据导入和基本功能
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import tensorflow as tf
input_text = uploaded[‘romeo_juliet.txt’].decode(“utf-8”)
步骤2:资料预处理
创建一组独特的字符:
letter_corpus = sorted(set(input_text))
letter_corpus[:10]
将字母编码为数字
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,如果捕获三个句子,则该模型应该能够选择模式并学习它们。
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:训练顺序
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
dataset = sequences.map(create_seq_targets)
步骤5:建立批次
batch_size = 1
buffer_size = 10000
dataset = dataset.shuffle(buffer_size).batch(batch_size, drop_remainder=True)
是时候建立网络了
vocab_size = len(letter_corpus)
embed_dim = 64
rnn_neurons = 1026
导入张量流模型,层和损失函数
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import LSTM,Dense,Embedding,Dropout,GRU
from tensorflow.keras.losses import sparse_categorical_crossentropy
定义损失函数
def sparse_cat_loss(y_true,y_pred):
return sparse_categorical_crossentropy(y_true, y_pred,
from_logits=True)
创建模型
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
我们的模型现在看起来像这样:
model.summary()
模型架构
训练时间
将纪元设置为30
epochs = 30
训练模型。请注意,这将需要一些时间。花了大约40分钟的时间来训练数据集
model.fit(dataset,epochs=epochs)
模型评估
在下面的代码中保存模型历史记录并绘制报告指标
losses = pd.DataFrame(model.history.history)
losses[[‘loss’,’accuracy’]].plot()
GRU模型训练结果
注意损失如何减少直到第20个时期,然后急剧上升。在第18个时代获得的最高准确度是86.03%。因此已经将模型训练了18个时期。
生成文字
定义一个函数(不固定种子)以使用1的序列生成文本。如果已经用两个单词训练了模型,那么模型会更强大,但是训练时间会增加。
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))
对于生成,可以使用以下代码,只需指定起始单词和连续单词的数量即可。
print(generate_text(model,”But”,gen_size=1000))
输出量
获得了“flower”一词的以下输出
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”的输出
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