×

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

消耗积分:0 | 格式:pdf | 大小:0.13 MB | 2023-06-05

吴湛

分享资料个

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

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

评论(0)
发评论

下载排行榜

全部0条评论

快来发表一下你的评论吧 !

'+ '

'+ '

'+ ''+ '
'+ ''+ ''+ '
'+ ''+ '' ); $.get('/article/vipdownload/aid/'+webid,function(data){ if(data.code ==5){ $(pop_this).attr('href',"/login/index.html"); return false } if(data.code == 2){ //跳转到VIP升级页面 window.location.href="//m.obk20.com/vip/index?aid=" + webid return false } //是会员 if (data.code > 0) { $('body').append(htmlSetNormalDownload); var getWidth=$("#poplayer").width(); $("#poplayer").css("margin-left","-"+getWidth/2+"px"); $('#tips').html(data.msg) $('.download_confirm').click(function(){ $('#dialog').remove(); }) } else { var down_url = $('#vipdownload').attr('data-url'); isBindAnalysisForm(pop_this, down_url, 1) } }); }); //是否开通VIP $.get('/article/vipdownload/aid/'+webid,function(data){ if(data.code == 2 || data.code ==5){ //跳转到VIP升级页面 $('#vipdownload>span').text("开通VIP 免费下载") return false }else{ // 待续费 if(data.code == 3) { vipExpiredInfo.ifVipExpired = true vipExpiredInfo.vipExpiredDate = data.data.endoftime } $('#vipdownload .icon-vip-tips').remove() $('#vipdownload>span').text("VIP免积分下载") } }); }).on("click",".download_cancel",function(){ $('#dialog').remove(); }) var setWeixinShare={};//定义默认的微信分享信息,页面如果要自定义分享,直接更改此变量即可 if(window.navigator.userAgent.toLowerCase().match(/MicroMessenger/i) == 'micromessenger'){ var d={ title:'PyTorch教程16.4之自然语言推理和数据集',//标题 desc:$('[name=description]').attr("content"), //描述 imgUrl:'https://'+location.host+'/static/images/ele-logo.png',// 分享图标,默认是logo link:'',//链接 type:'',// 分享类型,music、video或link,不填默认为link dataUrl:'',//如果type是music或video,则要提供数据链接,默认为空 success:'', // 用户确认分享后执行的回调函数 cancel:''// 用户取消分享后执行的回调函数 } setWeixinShare=$.extend(d,setWeixinShare); $.ajax({ url:"//www.obk20.com/app/wechat/index.php?s=Home/ShareConfig/index", data:"share_url="+encodeURIComponent(location.href)+"&format=jsonp&domain=m", type:'get', dataType:'jsonp', success:function(res){ if(res.status!="successed"){ return false; } $.getScript('https://res.wx.qq.com/open/js/jweixin-1.0.0.js',function(result,status){ if(status!="success"){ return false; } var getWxCfg=res.data; wx.config({ //debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。 appId:getWxCfg.appId, // 必填,公众号的唯一标识 timestamp:getWxCfg.timestamp, // 必填,生成签名的时间戳 nonceStr:getWxCfg.nonceStr, // 必填,生成签名的随机串 signature:getWxCfg.signature,// 必填,签名,见附录1 jsApiList:['onMenuShareTimeline','onMenuShareAppMessage','onMenuShareQQ','onMenuShareWeibo','onMenuShareQZone'] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2 }); wx.ready(function(){ //获取“分享到朋友圈”按钮点击状态及自定义分享内容接口 wx.onMenuShareTimeline({ title: setWeixinShare.title, // 分享标题 link: setWeixinShare.link, // 分享链接 imgUrl: setWeixinShare.imgUrl, // 分享图标 success: function () { setWeixinShare.success; // 用户确认分享后执行的回调函数 }, cancel: function () { setWeixinShare.cancel; // 用户取消分享后执行的回调函数 } }); //获取“分享给朋友”按钮点击状态及自定义分享内容接口 wx.onMenuShareAppMessage({ title: setWeixinShare.title, // 分享标题 desc: setWeixinShare.desc, // 分享描述 link: setWeixinShare.link, // 分享链接 imgUrl: setWeixinShare.imgUrl, // 分享图标 type: setWeixinShare.type, // 分享类型,music、video或link,不填默认为link dataUrl: setWeixinShare.dataUrl, // 如果type是music或video,则要提供数据链接,默认为空 success: function () { setWeixinShare.success; // 用户确认分享后执行的回调函数 }, cancel: function () { setWeixinShare.cancel; // 用户取消分享后执行的回调函数 } }); //获取“分享到QQ”按钮点击状态及自定义分享内容接口 wx.onMenuShareQQ({ title: setWeixinShare.title, // 分享标题 desc: setWeixinShare.desc, // 分享描述 link: setWeixinShare.link, // 分享链接 imgUrl: setWeixinShare.imgUrl, // 分享图标 success: function () { setWeixinShare.success; // 用户确认分享后执行的回调函数 }, cancel: function () { setWeixinShare.cancel; // 用户取消分享后执行的回调函数 } }); //获取“分享到腾讯微博”按钮点击状态及自定义分享内容接口 wx.onMenuShareWeibo({ title: setWeixinShare.title, // 分享标题 desc: setWeixinShare.desc, // 分享描述 link: setWeixinShare.link, // 分享链接 imgUrl: setWeixinShare.imgUrl, // 分享图标 success: function () { setWeixinShare.success; // 用户确认分享后执行的回调函数 }, cancel: function () { setWeixinShare.cancel; // 用户取消分享后执行的回调函数 } }); //获取“分享到QQ空间”按钮点击状态及自定义分享内容接口 wx.onMenuShareQZone({ title: setWeixinShare.title, // 分享标题 desc: setWeixinShare.desc, // 分享描述 link: setWeixinShare.link, // 分享链接 imgUrl: setWeixinShare.imgUrl, // 分享图标 success: function () { setWeixinShare.success; // 用户确认分享后执行的回调函数 }, cancel: function () { setWeixinShare.cancel; // 用户取消分享后执行的回调函数 } }); }); }); } }); } function openX_ad(posterid, htmlid, width, height) { if ($(htmlid).length > 0) { var randomnumber = Math.random(); var now_url = encodeURIComponent(window.location.href); var ga = document.createElement('iframe'); ga.src = 'https://www1.elecfans.com/www/delivery/myafr.php?target=_blank&cb=' + randomnumber + '&zoneid=' + posterid+'&prefer='+now_url; ga.width = width; ga.height = height; ga.frameBorder = 0; ga.scrolling = 'no'; var s = $(htmlid).append(ga); } } openX_ad(828, '#berry-300', 300, 250);