网站备案拍照背景图,建设机械网站咨询,免费的企业网站制作,wordpress提交表单插件#x1f468;#x1f393;作者简介#xff1a;一位即将上大四#xff0c;正专攻机器学习的保研er #x1f30c;上期文章#xff1a;机器学习深度学习——NLP实战#xff08;情感分析模型——textCNN实现#xff09; #x1f4da;订阅专栏#xff1a;机器… 作者简介一位即将上大四正专攻机器学习的保研er 上期文章机器学习深度学习——NLP实战情感分析模型——textCNN实现 订阅专栏机器学习深度学习 希望文章对你们有所帮助 NLP实战自然语言推断——数据集 引入自然语言推断斯坦福自然语言推断SNLI数据集读取数据集定义用于加载数据集的类整合代码 小结 引入
之前我们分别使用了RNN和textCNN实现了情感分析模型这个任务的目的是将单个文本序列分类到预定义的类别中例如一组情感极性中如“积极”或“消极”。然而当需要决定一个句子是否可以从另一个句子推断出来或者需要通过识别语义等价的句子来消除句子间冗余时知道如何对一个文本序列进行分类时不够的。相反我们需要能够对成对的文本序列进行推断这就是自然语言推断。
自然语言推断
自然语言推断主要研究假设是否可以从前提中推断出来其中两者都是文本序列。换言之自然语言推断决定了一对文本序列之间的逻辑关系。这类关系通常分为三种类型 1、蕴涵假设可以从前提中推断出来。 2、矛盾假设的否定可以从前提中推断出来。 3、中性所有其他情况。 自然语言推断也被称为识别文本蕴涵任务。例如下面的一个文本对将被贴上“蕴涵”的标签因为假设中的“示爱”可以从前提中的“拥抱”中推断出来 前提两个人拥抱在一起。 假设两个人在示爱。 下面是一个“矛盾”的例子因为“运行编码实例”表示“不睡觉”而不是“睡觉” 前提一名男子正在运行Dive Into Deep Learning的编码实例。 假设该男子正在睡觉。 第三个例子显示了一种“中性”关系因为“正在为我们表演”这一事实无法推断出“出名”或“不出名” 前提音乐家们正在为我们表演。 假设音乐家很有名。 自然语言推断一直是理解自然语言的中心话题。它有着广泛的应用从信息检索到开放领域的问答。为了研究这个问题我们将首先研究一个流行的自然语言推断基准数据集。
斯坦福自然语言推断SNLI数据集
斯坦福自然语言推断语料库SNLI是由500000多个带标签的英语句子对组成的集合。我们进行下载并存储提取的SNLI数据集。
import os
import re
import torch
from torch import nn
from d2l import torch as d2l#save
d2l.DATA_HUB[SNLI] (https://nlp.stanford.edu/projects/snli/snli_1.0.zip,9fcde07509c7e87ec61c640c1b2753d9041758e4)data_dir d2l.download_extract(SNLI)上面的代码下载可能会出现问题因为SNLI数据集的压缩文件snli_1.0.zip里面有两个路径为“snli_1.0\Icon\r”和“’__MACOSX/snli_1.0/._Icon\r’”的文件导致无法解析此路径进而导致整个文件无法解压。 解决方法 手动解压data下的数据集snli_1.0.zip”然后把data_dir赋值为数据集解压后的路径改一下也就是改为
data_dir D:\Python\pytorch\data\snli_1.0\snli_1.0后序用到download_extract方法的地方也都记得把地址改成这样的。
读取数据集
原始的SNLI数据集包含的信息比我们在实验中真正需要的信息丰富得多。因此我们定义函数read_snli以仅提取数据集的一部分然后返回前提、假设及其标签的列表。
#save
def read_snli(data_dir, is_train):将SNLI数据集解析为前提、假设和标签def extract_text(s):# 删除我们不会使用的信息s re.sub(\\(, , s)s re.sub(\\), , s)# 用一个空格替换两个或多个连续的空格s re.sub(\\s{2,}, , s)return s.strip()label_set {entailment: 0, contradiction: 1, neutral: 2}file_name os.path.join(data_dir, snli_1.0_train.txtif is_train else snli_1.0_test.txt)with open(file_name, r) as f:rows [row.split(\t) for row in f.readlines()[1:]]premises [extract_text(row[1]) for row in rows if row[0] in label_set]hypotheses [extract_text(row[2]) for row in rows if row[0] \in label_set]labels [label_set[row[0]] for row in rows if row[0] in label_set]return premises, hypotheses, labels上面代码可以看出“0”对应“蕴涵entailment”“1”代表“矛盾contradiction”“2”代表“中性neutral”。 我们可以打印前面3对的前提和假设以及它们的标签
train_data read_snli(data_dir, is_trainTrue)
for x0, x1, y in zip(train_data[0][:3], train_data[1][:3], train_data[2][:3]):print(前提, x0)print(假设, x1)print(标签, y)运行结果 前提 A person on a horse jumps over a broken down airplane . 假设 A person is training his horse for a competition . 标签 2 前提 A person on a horse jumps over a broken down airplane . 假设 A person is at a diner , ordering an omelette . 标签 1 前提 A person on a horse jumps over a broken down airplane . 假设 A person is outdoors , on a horse . 标签 0 这里的训练集大概有550000对测试集约有10000对。下面显示了训练集和测试集中的三个标签大致是平衡的
test_data read_snli(data_dir, is_trainFalse)
for data in [train_data, test_data]:print([[row for row in data[2]].count(i) for i in range(3)])运行结果 [183416, 183187, 182764] [3368, 3237, 3219] 定义用于加载数据集的类
下面定义一个用于加载SNLI数据集的类。类构造函数中的变量num_steps指定文本序列的长度使得每个小批量序列将具有相同的形状。换句话说在较长序列中的前num_steps个标记之后的标记被截断而特殊标记“pad”将被附加到较短的序列后直到它们的长度变为num_steps。通过实现__getitem__功能我们可以任意访问带有索引idx的前提、假设和标签。
#save
class SNLIDataset(torch.utils.data.Dataset):用于加载SNLI数据集的自定义数据集def __init__(self, dataset, num_steps, vocabNone):self.num_steps num_stepsall_premise_tokens d2l.tokenize(dataset[0])all_hypothesis_tokens d2l.tokenize(dataset[1])if vocab is None:self.vocab d2l.Vocab(all_premise_tokens \all_hypothesis_tokens, min_freq5, reserved_tokens[pad])else:self.vocab vocabself.premises self._pad(all_premise_tokens)self.hypotheses self._pad(all_hypothesis_tokens)self.labels torch.tensor(dataset[2])print(read str(len(self.premises)) examples)def _pad(self, lines):return torch.tensor([d2l.truncate_pad(self.vocab[line], self.num_steps, self.vocab[pad])for line in lines])def __getitem__(self, idx):return (self.premises[idx], self.hypotheses[idx]), self.labels[idx]def __len__(self):return len(self.premises)整合代码
现在我们可以调用read_snli函数和SNLIDataset类来下载SNLI数据集并返回训练集和测试集的DataLoader实例以及训练集的词表。值得注意的是我们必须使用从训练集构造的词表作为测试集的词表。因此在训练集中训练的模型将不知道来自测试集的任何新词元。
#save
def load_data_snli(batch_size, num_steps50):下载SNLI数据集并返回数据迭代器和词表num_workers d2l.get_dataloader_workers()data_dir D:\Python\pytorch\data\snli_1.0\snli_1.0train_data read_snli(data_dir, True)test_data read_snli(data_dir, False)train_set SNLIDataset(train_data, num_steps)test_set SNLIDataset(test_data, num_steps, train_set.vocab)train_iter torch.utils.data.DataLoader(train_set, batch_size,shuffleTrue,num_workersnum_workers)test_iter torch.utils.data.DataLoader(test_set, batch_size,shuffleFalse,num_workersnum_workers)return train_iter, test_iter, train_set.vocab在这里我们将批量大小设置为128序列长度设置为50并调用load_data_snli函数来获取数据迭代器和词表。然后打印词表大小
train_iter, test_iter, vocab load_data_snli(128, 50)
print(len(vocab))运行结果 read 549367 examples read 9824 examples 18678 现在我们打印第一个小批量的形状。与情感分析不同我们有分别代表前提和假设的两个输入X[0]和X[1]
for X, Y in train_iter:print(X[0].shape)print(X[1].shape)print(Y.shape)break输出结果 torch.Size([128, 50]) torch.Size([128, 50]) torch.Size([128]) 小结
1、自然语言推研究“假设”是否可以从“前提”推断出来其中两者都是文本序列。 2、在自然语言推断中前提和假设之间的关系包括蕴涵关系、矛盾关系和中性关系。 3、斯坦福自然语言推断SNLI语料库是一个比较流行的自然语言推断基准数据集。