文本生成是自然语言处理领域的一项任务,它涉及到自动生成有意义的文本。可以通过自动补全功能来利用文本生成过程。最初,提供一个提示,这是一个用作生成文本基础的文本。模型将基于提示生成文本,预测的文本将被添加到基础提示中,并再次输入模型。通过这种方式,可以使用提示文本生成许多文本。
文本生成也被称为自然语言生成。文本生成可以用于创建聊天机器人和自动补全。文本生成的质量取决于语料库的质量。语料库是用于训练文本生成模型的一组文档。如果数据质量不好,那么模型的质量也不会好(垃圾进,垃圾出)。为了提供高质量的数据,需要预处理数据。要训练文本生成模型,需要按照以下步骤进行:
准备数据并进行预处理。生成n-gram序列。预填充序列。使用填充序列中的最后一个词作为目标。训练模型。用于预测。
将在本文中详细探讨上述步骤。将详细了解文本生成是如何工作的。
需要spaCy进行预处理。按照上的说明安装spaCy。将使用TensorFlow进行建模,所以如果还没有安装TensorFlow,请按照上的说明进行安装。
安装完spaCy后,执行以下命令。它是spaCy的训练管道包。将用它进行预处理。
python -m spacy download en_core_web_sm
将使用爱尔兰歌词Eof数据集进行训练。可以使用以下命令下载数据集。
wget --no-check-certificate https://storage.googleapis.com/laurencemoroney-blog.appspot.com/irish-lyrics-eof.txt -O /home/data/irish-lyrics-eof.txt
执行上述命令后,数据将存储在以下路径:/home/data/irish-lyrics-eof.txt
导入所需的库:
import re
import spacy
import numpy as np
import pandas as pd
import en_core_web_sm
import tensorflow as tf
from nltk.stem import WordNetLemmatizer
from tensorflow.keras.optimizers import Adam
from tensorflow.keras.models import Sequential
from spacy.lang.en.stop_words import STOP_WORDS
from tensorflow.keras.preprocessing.text import Tokenizer
from tensorflow.keras.preprocessing.sequence import pad_sequences
from tensorflow.keras.layers.experimental.preprocessing import TextVectorization
from tensorflow.keras.layers import Embedding, LSTM, Dense, Bidirectional, Dropout
加载数据:
data = open('/home/data/irish-lyrics-eof.txt').read()
nlp = en_core_web_sm.load()
lemmatizer = WordNetLemmatizer()
DISABLE_PIPELINES = ["tok2vec", "parser", "ner", "textcat", "custom", "lemmatizer"]
stopwords = STOP_WORDS
可以加载spaCy的训练管道,使用命令en_core_web_sm.load()。还初始化了用于预处理的词形还原器。
下面是一个文本预处理器类的实现:
class TextPreprocessor:
def __init__(self, filters):
self.filters = filters
def preprocess_text(self, doc):
tokens = [
token
for token in doc
if not token.is_space and
not token.like_email and
not token.like_url and
not token.is_stop and
not token.is_punct and
not token.like_num
]
translation_table = str.maketrans('', '', self.filters)
translated_tokens = [
token.text.lower().translate(translation_table)
for token in tokens
]
lemmatized_tokens = [
lemmatizer.lemmatize(token)
for token in translated_tokens
if len(token) > 1
]
return lemmatized_tokens
文本预处理器类执行以下步骤:去除文本中的空白。去除包含电子邮件的文本。去除包含URL的文本。去除包含停用词的文本,这也去除了缩写。去除文本中的标点符号。去除包含数字的文本。词形还原。
首先,spaCy将所有句子列表分解为文档列表。在spaCy中,文档是一系列标记对象的序列。上述禁用的管道是不打算使用的,通过禁用它们可以加快处理速度。如上所述,每个文档是一系列标记对象,遍历它们并去除空白、电子邮件、URL、停用词、标点符号和数字。
词形还原是找到词的基础的过程。例如,‘running’的词根是‘run’。还有另一种称为词干提取的技术,它与词形还原非常相似,但两者的区别在于词形还原根据词典产生有意义的词,而词干提取则不会产生有意义的词。使用词形还原的目的是减少词汇量。
接下来,将预处理后的文本转换为数字序列。例如,句子[‘I’, ‘am’, ‘happy’]将被转换为[1, 2, 3]。为了训练文本生成模型,需要从一句话中生成n-gram序列。以上面的例子为例,句子[‘I’, ‘am’, ‘happy’]将用于生成以下n-gram序列[‘I’, ‘am’],[‘I’, ‘am’, ‘happy’]。这些n-gram序列将被生成并追加到变量input_sequences中。将文本转换为n-grams后,将填充整个文本。例如,假设语料库中句子的最大长度为5,如果预填充上面例子中使用的文本,它将是[0, 0, 1, 2, 3]。
输入序列如下:
在预填充序列后,将句子中的最后一个词作为目标。现在已经准备了数据集,可以继续训练模型了。将使用双向LSTM(长短期记忆)来训练模型。想知道什么是LSTM吗?请看这个。
模型的第一层是嵌入层。嵌入层用于将文本转换为向量。将文本转换为向量的目的是可以比使用独热编码更好地找到词之间的相似性。例如,单词‘orange’可能被嵌入为[1.5, 4.5, 6.6],这是一个三维向量。需要产生的维度数量是超参数,可以选择任何正值作为嵌入维度。
下一层是150个单元的双向LSTM(长短期记忆)。之后,使用一个密集层,其单元数等于语料库中的单词总数。使用了softmax激活函数,因为它产生多类输出。使用Adam优化器进行损失函数优化。使用的损失函数是分类交叉熵,使用的指标是准确率。损失函数和指标之间的区别在于,损失函数用于优化模型,而指标用于比较,不用于优化。使用了64的批量大小和10个周期。
训练结果如下:
仅用10个周期,模型就达到了80%的准确率。尝试改变周期数量以提高准确率。现在已经训练了模型,让绘制历史记录。
import matplotlib.pyplot as plt
plt.plot(history.history['accuracy'])
plt.title("History")
plt.xlabel("Epochs")
plt.ylabel('accuracy')
plt.show()
通过查看图表,可以说随着周期的增加,准确率也在增加。换句话说,随着周期数量的增加,模型的准确率增加,这是进步的好兆头。现在已经训练了模型,可以用它来预测下一个词并生成文本。
inverted_word_index = {v: k for k, v in tokenizer.word_index.items()}
seed_text = "This is the good day of my life"
processed_text = tp.preprocess_text(nlp(seed_text))
processed_sentence = " ".join(processed_text)
next_words = 100
for _ in range(next_words):
token_list = tokenizer.texts_to_sequences([processed_sentence])[0]
token_list = pad_sequences([token_list], maxlen=max_sequence_len-1, padding='pre')
predicted = model.predict_classes(token_list, verbose=0)
processed_sentence += " " + inverted_word_index[predicted[0]]
print(processed_sentence)
在上面的代码中,提示句子是“This is the good day of my life”。将预处理它,将其转换为序列,并填充句子。之后,将其输入模型,模型预测一个词。将这个词追加到提示句子本身,然后再次执行相同的过程。迭代执行这些操作,直到获得指定数量的词。通过这种方式,可以使用双向LSTM进行文本生成。