|AI框架应用:用PyTorch构建自然语言生成(NLG)系统
在过去的几年中 , 自然语言处理(NLP)有了显著的增长 , 这要归功于深度学习算法的进步和足够的计算能力 。 但是 , 前馈神经网络不被认为是对语言或文本建模的最佳选择 。 这是因为前馈网络未考虑文本中的单词顺序 。
因此 , 为了捕获文本中存在的顺序信息 , 在NLP中使用了递归神经网络 。 在本文中 , 我们将了解如何使用PyTorch生成自然语言 , 使用递归神经网络(LSTM) 。
本文插图
自然语言生成的简要概述
自然语言生成(NLG)是自然语言处理(NLP)的子字段 , 它与计算机自动生成人类可读文本有关 。 NLG可用于各种NLP任务 , 例如机器翻译 , 语音转文本 , 聊天机器人 , 文本自动更正或文本自动完成 。
我们可以借助语言建模为NLG建模 。 让我解释一下语言模型的概念–语言模型学会预测单词序列的概率 。 例如 , 考虑以下句子:
本文插图
我们可以看到 , 第一句话比第二句话更有可能 , 因为我们知道第二句话中的单词顺序是不正确的 。 这是语言建模背后的基本概念 。 语言模型应该能够区分较高可能性的单词(或标记)序列 。
语言模型的类型
以下是两种类型的语言模型:
- 统计语言模型: 这些模型使用传统的统计技术 , 例如N-gram , 隐马尔可夫模型(HMM)和某些语言规则来学习单词的概率分布 。
- 神经语言模型:这些模型的有效性已经超过统计语言模型 。 他们使用不同种类的神经网络对语言进行建模 。
使用统计语言模型生成文本
首先 , 让我们看看如何在统计模型(如N-Gram模型)的帮助下生成文本 。
假设我们必须为下面的句子生成下一个单词:
本文插图
假设我们的N-Gram模型考虑3个前一个词的上下文只是为了预测下一个词 。 因此 , 模型将尝试使概率P(w |“它建立了a”)最大化 , 其中“ w”代表文本数据集中的每个单词 。 将使该概率最大化的单词将作为句子“她在那里建…”的下一个单词生成 。
然而 , 使用这样的统计模型存在某些缺点 , 该统计模型使用直接的前一个单词作为上下文来预测下一个单词 。 让我给您一些额外的背景信息 。
本文插图
现在 , 我们获得了有关正在发生的事情的更多信息 。 “沙堡”一词很可能是下一个词 , 因为它对“海滩”一词有很强的依赖性 , 因为人们在大多数正确的海滩上建造沙堡 。 因此 , 重点是 , “沙堡”并不取决于当前环境(“她建造了”) , 而是取决于“海滩” 。
使用神经语言模型生成文本
为了捕获序列标记之间的这种无限制的依赖性 , 我们可以使用基于RNN / LSTM的语言模型 。 以下是我们将用于NLG的语言模型的简约表示:
本文插图
- x1 , x2和x3分别是时间步1 , 时间步2和时间步3的输入单词嵌入
- ?1 , ?2和?3是训练数据集中所有不同标记的概率分布
- y1 , y2和y3是基本真值
- U , V和W是权重矩阵
- H0 , H1 , H2和H3是隐藏状态
我们将尝试从三个阶段来了解神经语言模型的功能:
- 资料准备
- 模型训练
- 文字产生
假设我们将下面的句子用作训练数据 。
[“好吧 , 完美” ,“听起来不错” ,“差价是多少”]
第一句话有4个记号 , 第二句话有3个记号 , 第三个句子有5个记号 。 因此 , 所有这些句子在记号方面都有不同的长度 。 LSTM模型只接受长度相同的序列作为输入 。 因此 , 我们必须使训练数据中的序列具有相同的长度 。
有多种技术可以使序列长度相等 。
一种技术是填充 。 我们可以在需要时使用填充令牌填充序列 。 但是 , 如果使用此技术 , 则在损失计算和文本生成期间将不得不处理填充令牌 。
因此 , 我们将使用另一种技术 , 该技术涉及在不使用任何填充令牌的情况下将一个序列分成多个等长的序列 。 该技术还增加了训练数据的大小 。 让我将其应用于我们的训练数据 。
假设我们希望序列具有三个标记 。 然后 , 第一个序列将分为以下序列:
['好吧 , 就是'完美']
第二个序列的长度仅为三 , 因此不会被拆分 。 但是 , 训练数据的第三个序列具有五个令牌 , 它将被分解为多个令牌序列:
['什么是' , '价格是' , '价格差']
现在 , 新数据集将如下所示:
['好吧就是' , '就是完美' , '听起来很棒' , '什么是' , '就是价格' , '价格差']
2.模型训练
由于我们要解决下一个单词生成问题 , 因此目标应该是输入单词的下一个单词 。 例如 , 考虑第一个文本序列“正确” 。
本文插图
对于我们训练数据的第一个序列 , 模型的输入为“正确”和“那个” , 相应的目标标记为“那个”和“是” 。 因此 , 在开始训练过程之前 , 我们将必须将数据集中的所有序列拆分为输入和目标 , 如下所示:
本文插图
因此 , “输入”和“目标”下的这些序列对是将传递给模型的训练示例 , 训练示例的损失将是每个时间步的损失平均值 。
本文插图
让我们看看如何将此模型用于文本生成 。
3.文字生成
一旦我们的语言模型得到训练 , 我们便可以将其用于NLG 。 想法是传递一个文本字符串作为输入 , 以及模型要在输入文本字符串之后生成的许多标记 。 例如 , 如果用户传递“ what is”作为输入文本 , 并指定该模型应生成2个令牌 , 则该模型可能会生成“ what’s going”或“ what is your name”或任何其他序列 。
让我借助一些插图展示它是如何发生的:
输入文字=“什么是”n = 2
步骤1 –输入文本的第一个标记(“ what”)传递给训练后的LSTM模型 。 它产生一个输出?1 , 我们将忽略它 , 因为我们已经知道第二个标记(“ is”) 。 该模型还生成隐藏状态H1 , 该状态将传递到下一个时间步 。
本文插图
步骤2 –然后将第二个令牌(“ is”)与H1一起在时间步骤2传递到模型 。 在此时间步长处的输出是概率分布 , 其中令牌“ going”具有最大值 。 因此 , 我们将其视为模型首次生成或预测的令牌 。 现在我们还有一个令牌可以生成 。
本文插图
步骤3 –为了生成下一个令牌 , 我们需要在时间步骤3将输入令牌传递给模型 。 但是 , 我们用完了输入令牌 , “ is”是生成“ going”的最后一个令牌 。 那么 , 接下来我们要传递什么作为输入呢?在这种情况下 , 我们将传递先前生成的令牌作为输入令牌 。
本文插图
该模型的最终输出将是“正在发生什么” 。 这就是我们将用于执行NLG的文本生成策略 。 接下来 , 我们将在电影情节摘要的数据集中训练自己的语言模型 。
使用PyTorch生成自然语言
现在我们知道了神经语言模型是如何工作的以及需要什么样的数据预处理 , 让我们训练一个LSTM语言模型以使用PyTorch执行自然语言生成 。
让我们快速导入必要的库 。
本文插图
1.加载数据集
我们将使用CMU电影摘要语料库的样本 。
本文插图
你可以使用下面的代码打印五份摘要 , 这些摘要是随机抽样的 。
#个样本随机摘要 random.sample(movie_plots , 5)2.数据准备
首先 , 我们将稍微清除文本 。 我们将仅保留字母和撇号标点符号 , 并从文本中删除其余的其他元素 。
#干净的文字 movie_plots = [re.sub(“ [^ az']” , “” , i)for movie_plots中的i]不必执行此步骤 。 只是我希望我的模型仅关注字母 , 而不必担心标点符号或数字或其他符号 。
接下来 , 我们将定义一个函数以从数据集中准备定长序列 。 我已指定序列的长度为五 。 它是一个超参数 , 您可以根据需要更改它 。
本文插图
因此 , 我们会将电影情节摘要传递给此函数 , 并且它将为每个输入返回固定长度序列的列表 。
本文插图
输出: 152644
一旦准备好相同长度的序列 , 就可以将它们进一步分为输入序列和目标序列 。
本文插图
【|AI框架应用:用PyTorch构建自然语言生成(NLG)系统】
现在我们必须将这些序列(x和y)转换为整数序列 , 但是在此之前 , 我们将必须将数据集中的每个不同的单词映射为一个整数值 。 因此 , 我们将为令牌字典创建一个令牌 , 并为令牌字典创建一个整数 。
本文插图
输出:(14271 , 'the')
#设置词汇量 vocab_size = len(int2token) vocab_size输出: 16592
词汇量为16,592 , 即我们的数据集中有超过16,000个不同的标记 。
一旦我们有了令牌到整数的映射 , 就可以将文本序列转换为整数序列 。
本文插图
3.模型制作
我们将批次的输入序列和目标序列传递给模型 , 因为最好是按批次进行训练 , 而不是一次将整个数据传递给模型 。 以下功能将从输入数据创建批次 。
本文插图
现在 , 我们将定义语言模型的体系结构 。
本文插图
本文插图
输入序列将首先通过嵌入层 , 然后通过LSTM层 。 LSTM层将提供一组与序列长度相等的输出 , 并且这些输出中的每一个都将传递到线性(密集)层 , 在该层上将应用softmax 。
本文插图
输出:
WordLSTM((emb_layer):嵌入(16592 , 200)(lstm):LSTM(200 , 256 , num_layers = 4 , batch_first = True , dropout = 0.3)(dropout ):Dropout(p = 0.3 , inplace = False)(fc ):线性(in_features = 256 , out_features = 16592 , bias = True))
现在让我们定义一个用于训练模型的函数 。
本文插图
本文插图
#训练模型 火车(净额 , batch_size = 32 , 历元= 20 , print_every = 256)我已将批次大小指定为32 , 并将训练模型20个时间段 。 训练可能需要一段时间 。
4.文字生成
训练模型后 , 我们可以将其用于文本生成 。 请注意 , 此模型可以一次生成一个单词 , 并带有隐藏状态 。 因此 , 要生成下一个单词 , 我们将必须使用此生成的单词和隐藏状态 。
本文插图
本文插图
函数sample()从用户处输入一个输入文本字符串(“ prime”) , 并指定一个数字(“ size”) , 该数字指定要生成的令牌数量 。 在给定输入单词和隐藏状态的情况下 , sample()使用predict()函数预测下一个单词 。 下面给出了由模型生成的一些文本序列 。
样本(净值 , 15)输出:
“现在由他们拥有新福音的圣殿负责 , 并关押他”
样本(净值15 , 素数=“其中之一”)输出:
``其中一个团队正在等待他的拒绝 , 并把他扔进对sannokai的拒绝中''
样本(净值15 , 素数=“尽快”)输出:
“一旦他被派去做不是他嘴上造成的普通战士”
样本(净值15 , 素数=“他们”)输出:
“他们发现自己以被扔进船的方式被扔进了船上”
最后
自然语言生成是一个快速成熟的领域 , 并且是越来越活跃的研究领域 。 从N-Gram模型到RNN / LSTM模型 , 用于NLG的方法也已走了很长一段路 , 现在基于变压器的模型已成为该领域的最新技术 。
总而言之 , 在本文中 , 涵盖了许多与NLG相关的内容 , 例如数据集准备 , 如何训练神经语言模型以及最终在PyTorch中进行自然语言生成过程 。 我建议大家尝试在更大的数据集上构建语言模型 , 并查看它生成什么样的文本 。
推荐阅读
- 番茄芝士薄底披萨做法
- 不用油不用牛奶,教你做蜂蜜蛋糕,蒸或烤都可以,只需4种食材
- 白色的发糕是用什么粉做的,难做吗?
- 春分,快手艾草青团的用料,没有一点难度,软糯可口,超简单又好吃的艾草青团
- 肺部|长期抽烟的人,点烟前牢记几点,或许不用戒烟,肺部也会舒服点!
- 银河系|不用一万光年,银河系就是一座黑暗森林|近期科技趣评
- 意大利生牛肉沙拉做法
- 想吃点心不用买,教你在家做“驴打滚”,不用烤箱,软糯香甜!
- 家常炖老母鸡,不用炖3小时,教你一妙招,40分钟鸡肉软嫩入味
- 早餐就爱吃菜团子,不用发面,冬天蒸一锅吃的特过瘾,比馒头还香
