0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

PyTorch教程-16.4。自然语言推理和数据集

jf_pJlTbmA9 来源:PyTorch 作者:PyTorch 2023-06-05 15:44 次阅读

在16.1 节中,我们讨论了情感分析的问题。该任务旨在将单个文本序列分类为预定义的类别,例如一组情感极性。然而,当需要决定一个句子是否可以从另一个句子推断出来,或者通过识别语义等同的句子来消除冗余时,知道如何对一个文本序列进行分类是不够的。相反,我们需要能够对成对的文本序列进行推理。

16.4.1。自然语言推理

自然语言推理研究是否可以从前提中推断出假设,其中两者都是文本序列。换句话说,自然语言推理决定了一对文本序列之间的逻辑关系。这种关系通常分为三种类型:

蕴涵:假设可以从前提中推导出来。

矛盾:可以从前提推导出假设的否定。

中性:所有其他情况。

自然语言推理也称为识别文本蕴含任务。例如,下面的一对将被标记为 蕴涵,因为假设中的“示爱”可以从前提中的“互相拥抱”中推导出来。

前提:两个女人互相拥抱。

假设:两个女人正在秀恩爱。

下面是一个矛盾的例子,因为“running the coding example”表示“not sleeping”而不是“sleeping”。

前提:一个人正在运行来自 Dive into Deep Learning 的编码示例。

假设:这个人正在睡觉。

第三个例子显示了一种中立关系,因为“为我们表演”这一事实不能推断出“著名”或“不著名”。

前提:音乐家正在为我们表演。

假设:音乐家很有名。

自然语言推理一直是理解自然语言的中心话题。它享有从信息检索到开放域问答的广泛应用。为了研究这个问题,我们将从调查一个流行的自然语言推理基准数据集开始。

16.4.2。斯坦福自然语言推理 (SNLI) 数据集

斯坦福自然语言推理 (SNLI) 语料库是超过 500000 个带标签的英语句子对的集合 (Bowman等人,2015 年)。我们将提取的 SNLI 数据集下载并存储在路径中../data/snli_1.0。

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')

Downloading ../data/snli_1.0.zip from https://nlp.stanford.edu/projects/snli/snli_1.0.zip...

import os
import re
from mxnet import gluon, np, npx
from d2l import mxnet as d2l

npx.set_np()

#@save
d2l.DATA_HUB['SNLI'] = (
  'https://nlp.stanford.edu/projects/snli/snli_1.0.zip',
  '9fcde07509c7e87ec61c640c1b2753d9041758e4')

data_dir = d2l.download_extract('SNLI')

16.4.2.1。读取数据集

原始 SNLI 数据集包含的信息比我们在实验中真正需要的信息丰富得多。因此,我们定义了一个函数read_snli 来仅提取部分数据集,然后返回前提、假设及其标签的列表。

#@save
def read_snli(data_dir, is_train):
  """Read the SNLI dataset into premises, hypotheses, and labels."""
  def extract_text(s):
    # Remove information that will not be used by us
    s = re.sub('\(', '', s)
    s = re.sub('\)', '', s)
    # Substitute two or more consecutive whitespace with space
    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.txt'
               if 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

#@save
def read_snli(data_dir, is_train):
  """Read the SNLI dataset into premises, hypotheses, and labels."""
  def extract_text(s):
    # Remove information that will not be used by us
    s = re.sub('\(', '', s)
    s = re.sub('\)', '', s)
    # Substitute two or more consecutive whitespace with space
    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.txt'
               if 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

现在让我们打印前 3 对前提和假设,以及它们的标签(“0”、“1”和“2”分别对应“蕴含”、“矛盾”和“中性”)。

train_data = read_snli(data_dir, is_train=True)
for x0, x1, y in zip(train_data[0][:3], train_data[1][:3], train_data[2][:3]):
  print('premise:', x0)
  print('hypothesis:', x1)
  print('label:', y)

premise: A person on a horse jumps over a broken down airplane .
hypothesis: A person is training his horse for a competition .
label: 2
premise: A person on a horse jumps over a broken down airplane .
hypothesis: A person is at a diner , ordering an omelette .
label: 1
premise: A person on a horse jumps over a broken down airplane .
hypothesis: A person is outdoors , on a horse .
label: 0

train_data = read_snli(data_dir, is_train=True)
for x0, x1, y in zip(train_data[0][:3], train_data[1][:3], train_data[2][:3]):
  print('premise:', x0)
  print('hypothesis:', x1)
  print('label:', y)

premise: A person on a horse jumps over a broken down airplane .
hypothesis: A person is training his horse for a competition .
label: 2
premise: A person on a horse jumps over a broken down airplane .
hypothesis: A person is at a diner , ordering an omelette .
label: 1
premise: A person on a horse jumps over a broken down airplane .
hypothesis: A person is outdoors , on a horse .
label: 0

训练集约550000对,测试集约10000对。下图表明“蕴含”、“矛盾”、“中性”这三个标签在训练集和测试集上都是均衡的。

test_data = read_snli(data_dir, is_train=False)
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]

test_data = read_snli(data_dir, is_train=False)
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]

16.4.2.2。定义用于加载数据集的类

下面我们继承DatasetGluon中的类定义一个加载SNLI数据集的类。类构造函数中的参数num_steps指定文本序列的长度,以便每个小批量序列具有相同的形状。换句话说,num_steps较长序列中第一个之后的标记被修剪,而特殊标记“”将附加到较短的序列,直到它们的长度变为num_steps. 通过实现该__getitem__ 功能,我们可以任意访问前提、假设和带有索引的标签idx。

#@save
class SNLIDataset(torch.utils.data.Dataset):
  """A customized dataset to load the SNLI dataset."""
  def __init__(self, dataset, num_steps, vocab=None):
    self.num_steps = num_steps
    all_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_freq=5, reserved_tokens=[''])
    else:
      self.vocab = vocab
    self.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[''])
             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)

#@save
class SNLIDataset(gluon.data.Dataset):
  """A customized dataset to load the SNLI dataset."""
  def __init__(self, dataset, num_steps, vocab=None):
    self.num_steps = num_steps
    all_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_freq=5, reserved_tokens=[''])
    else:
      self.vocab = vocab
    self.premises = self._pad(all_premise_tokens)
    self.hypotheses = self._pad(all_hypothesis_tokens)
    self.labels = np.array(dataset[2])
    print('read ' + str(len(self.premises)) + ' examples')

  def _pad(self, lines):
    return np.array([d2l.truncate_pad(
      self.vocab[line], self.num_steps, self.vocab[''])
             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)

16.4.2.3。把它们放在一起

现在我们可以调用read_snli函数和SNLIDataset 类来下载 SNLI 数据集并返回DataLoader训练集和测试集的实例,以及训练集的词汇表。值得注意的是,我们必须使用从训练集中构造的词汇作为测试集的词汇。因此,测试集中的任何新标记对于在训练集上训练的模型都是未知的。

#@save
def load_data_snli(batch_size, num_steps=50):
  """Download the SNLI dataset and return data iterators and vocabulary."""
  num_workers = d2l.get_dataloader_workers()
  data_dir = d2l.download_extract('SNLI')
  train_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,
                       shuffle=True,
                       num_workers=num_workers)
  test_iter = torch.utils.data.DataLoader(test_set, batch_size,
                      shuffle=False,
                      num_workers=num_workers)
  return train_iter, test_iter, train_set.vocab

#@save
def load_data_snli(batch_size, num_steps=50):
  """Download the SNLI dataset and return data iterators and vocabulary."""
  num_workers = d2l.get_dataloader_workers()
  data_dir = d2l.download_extract('SNLI')
  train_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 = gluon.data.DataLoader(train_set, batch_size, shuffle=True,
                    num_workers=num_workers)
  test_iter = gluon.data.DataLoader(test_set, batch_size, shuffle=False,
                   num_workers=num_workers)
  return train_iter, test_iter, train_set.vocab

这里我们将批量大小设置为 128,将序列长度设置为 50,并调用该load_data_snli函数来获取数据迭代器和词汇表。然后我们打印词汇量。

train_iter, test_iter, vocab = load_data_snli(128, 50)
len(vocab)

read 549367 examples
read 9824 examples

18678

train_iter, test_iter, vocab = load_data_snli(128, 50)
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])

for X, Y in train_iter:
  print(X[0].shape)
  print(X[1].shape)
  print(Y.shape)
  break

(128, 50)
(128, 50)
(128,)

16.4.3。概括

自然语言推理研究是否可以从前提中推断出假设,其中两者都是文本序列。

在自然语言推理中,前提和假设之间的关系包括蕴涵、矛盾和中性。

斯坦福自然语言推理 (SNLI) 语料库是一种流行的自然语言推理基准数据集。

16.4.4。练习

长期以来,机器翻译的评估都是基于肤浅的 n- 输出翻译和真值翻译之间的语法匹配。你能设计一个使用自然语言推理来评估机器翻译结果的方法吗?

我们如何改变超参数来减少词汇量?

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 数据集
    +关注

    关注

    4

    文章

    1179

    浏览量

    24356
  • 自然语言
    +关注

    关注

    1

    文章

    270

    浏览量

    13207
  • pytorch
    +关注

    关注

    2

    文章

    762

    浏览量

    12836
收藏 人收藏

    评论

    相关推荐

    如何开始使用PyTorch进行自然语言处理

    随着人工智能和深度学习程序在未来几年的蓬勃发展,自然语言处理(NLP)将日益普及,而且必要性也与日俱增。PyTorch 自然语言处理是实现这些程序的不错选择。
    的头像 发表于 07-07 10:01 2190次阅读

    PyTorch教程-16.7。自然语言推理:微调 BERT

    实验室在 SageMaker Studio Lab 中打开笔记本 在本章前面的部分中,我们为 SNLI 数据集上的自然语言推理任务(如第 16.4 节所述)设计了一个基于注意力的架
    的头像 发表于 06-05 15:44 1000次阅读
    <b class='flag-5'>PyTorch</b>教程-16.7。<b class='flag-5'>自然语言</b><b class='flag-5'>推理</b>:微调 BERT

    python自然语言

    Toolkit,自然语言工具包,地址:http://www.nltk.org/安装命令:pip install nltk安装完成后测试:import nltk没有报错即表明安装成功。NLTK包含大量的软件、数据
    发表于 05-02 13:50

    【推荐体验】腾讯云自然语言处理

    自然语言处理技术的功劳。可以说,只要有大量文本数据的应用场景,几乎都涉及到NLP技术,也都可以使用相关自然语言处理产品的接口来做智能分析。比如:社交媒体上的用户言论,可以使用腾讯云NLP的情感分析接口,来做
    发表于 10-09 15:28

    自然语言处理的语言模型

    自然语言处理——53 语言模型(数据平滑)
    发表于 04-16 11:11

    自然语言处理的词性标注方法

    自然语言处理——78 词性标注方法
    发表于 04-21 11:38

    自然语言处理笔记

    自然语言处理笔记9-哈工大 关毅
    发表于 06-04 16:34

    自然语言处理——总结、习题

    自然语言处理——79 总结、习题
    发表于 06-19 11:22

    什么是自然语言处理

    什么是自然语言处理?自然语言处理任务有哪些?自然语言处理的方法是什么?
    发表于 09-08 06:51

    自然语言推理数据集“人工痕迹”严重,模型性能被高估

    自然语言推理是NLP领域被广泛研究的领域之一,有了这一技术,许多复杂的语义任务如问题回答和文本总结都能得到解决。而用于自然语言推理的大规模数据
    的头像 发表于 03-14 18:11 4349次阅读
    <b class='flag-5'>自然语言</b><b class='flag-5'>推理</b><b class='flag-5'>数据</b>集“人工痕迹”严重,模型性能被高估

    自然语言入门之ESIM

    ESIM是ACL2017的一篇论文,在当时成为各个NLP比赛的杀器,直到现在仍是入门自然语言推理值得一读的文章。 本文根据ESIM原文以及pytorch代码实现对ESIM模型进行总结
    的头像 发表于 02-22 11:34 685次阅读
    <b class='flag-5'>自然语言</b>入门之ESIM

    PyTorch教程16.4自然语言推理和数据

    电子发烧友网站提供《PyTorch教程16.4自然语言推理和数据集.pdf》资料免费下载
    发表于 06-05 10:57 0次下载
    <b class='flag-5'>PyTorch</b>教程<b class='flag-5'>16.4</b>之<b class='flag-5'>自然语言</b><b class='flag-5'>推理</b><b class='flag-5'>和数据</b>集

    PyTorch教程16.5之自然语言推理:使用注意力

    电子发烧友网站提供《PyTorch教程16.5之自然语言推理:使用注意力.pdf》资料免费下载
    发表于 06-05 10:49 0次下载
    <b class='flag-5'>PyTorch</b>教程16.5之<b class='flag-5'>自然语言</b><b class='flag-5'>推理</b>:使用注意力

    PyTorch教程16.7之自然语言推理:微调BERT

    电子发烧友网站提供《PyTorch教程16.7之自然语言推理:微调BERT.pdf》资料免费下载
    发表于 06-05 10:52 0次下载
    <b class='flag-5'>PyTorch</b>教程16.7之<b class='flag-5'>自然语言</b><b class='flag-5'>推理</b>:微调BERT

    PyTorch教程-16.5。自然语言推理:使用注意力

    实验室在 SageMaker Studio Lab 中打开笔记本 我们在16.4 节介绍了自然语言推理任务和 SNLI 数据集。鉴于许多基于复杂和深层架构的模型, Parikh
    的头像 发表于 06-05 15:44 346次阅读
    <b class='flag-5'>PyTorch</b>教程-16.5。<b class='flag-5'>自然语言</b><b class='flag-5'>推理</b>:使用注意力