【Pytorch神经网络实战案例】33 使用BERT模型实现完形填空任务

本文涉及的产品
模型训练 PAI-DLC,100CU*H 3个月
交互式建模 PAI-DSW,每月250计算时 3个月
模型在线服务 PAI-EAS,A10/V100等 500元 1个月
简介: 案例:加载Transformers库中的BERT模型,并用它实现完形填空任务,即预测一个句子中缺失的单词。

61f0238bb78e447c87fb94c83b064969.png


1 案例描述


案例:加载Transformers库中的BERT模型,并用它实现完形填空任务,即预测一个句子中缺失的单词。


b1b4533c1b6b44b19bbb1a18701d52e1.png


2 代码实现:使用BERT模型实现完形填空任务


2.1 代码实现:载入词表,并对输入的文本进行分词转化---BERT_MASK.py(第1部分)


import torch
from transformers import BertTokenizer, BertForMaskedLM
# 1.1 载入词表,并对输入的文本进行分词转化
# 加载预训练模型
tokenizer = BertTokenizer.from_pretrained('bert-base-uncased')
# 输入文本,BERT模型需要特殊词来标定句子:
# [CLS]:标记一个段落的开始。一个段落可以有一个或多个句子,但是只能有一个[CLS]。[CLS]在BERT模型中还会被用作分类任务的输出特征。
# [SEP]:标记一个句子的结束。在一个段落中,可以有多个[SEP]。
text = "[CLS] Who is Li BiGor ? [SEP] Li BiGor is a programmer [SEP]"
tokenized_text = tokenizer.tokenize(text)
# 使用词表对输入文本进行转换。与中文分词有点类似。由于词表中不可能覆盖所有的单词,因此当输入文本中的单词不存在时,系统会使用带有通配符的单间(以“#”开头的单词)将其拆开。
print("词表转化结果:",tokenized_text)
# 词表转化结果:['[CLS]','who','is','li','big','##or','?','[SEP]','li','big','##or','is','a','programmer','[SEP]']


2.2 代码实现:遮蔽单词,并将其转换为索引值---BERT_MASK.py(第2部分)


# 1.2 遮蔽单词,并将其转换为索引值,使用标记字符[MAS]代替输入文本中索引值为8的单词,对“Li”进行遮蔽,并将整个句子中的单词转换为词表中的索引值。
masked_index = 8  # 掩码一个标记,再使用'BertForMaskedLM'预测回来
tokenized_text[masked_index] = '[MASK]' # 标记字符[MASK],是BERT模型中的特殊标识符。在BERT模型的训练过程中,会对输入文本的随机位置用[MASK]字符进行替换,并训练模型预测出[MASK]字符对应的值。
print("句子中的索引:",tokenized_text)
# 句子中的索引:['[CLS]','who','is','li','big','##or','?','[SEP]','[MASK]','big','##or','is','a','programmer','[SEP]']
# 将标记转换为词汇表索引
indexed_tokens = tokenizer.convert_tokens_to_ids(tokenized_text)
# 将输入转换为PyTorch张量
tokens_tensor = torch.tensor([indexed_tokens])
print("句子中的向量:",tokens_tensor)
# 句子中的向量:tensor([[101,2040,2003,5622,2502,2953,1029,102,103,2502,2953,2003,1037,20273,102]])


2.3 代码实现:加载预训练模型,并对遮蔽单词进行预测---BERT_MASK.py(第3部分)


# 1.3 加载预训练模型,并对遮蔽单词进行预测
# 指定设备
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
print(device)
# 加载预训练模型 (weights)
model = BertForMaskedLM.from_pretrained('bert-base-uncased') # 用BertForMaskedLM类加载模型,该类可以对句子中的标记字符[MASK]进行预测。
model.eval()
model.to(device)
# 段标记索引:定义输入的BertForMaskedLM类句子指示参数,用于指示输入文本中的单词是属于第一句还是属于第二句。属于第一句的单词用0来表示(一共8个),属于第二句的单词用1来表示(一共7个)。
segments_ids = [0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1]
segments_tensors = torch.tensor([segments_ids]).to(device)
tokens_tensor = tokens_tensor.to(device)
# 预测所有的tokens
with torch.no_grad():
    # 将文本和句子指示参数输入模型进行预测。
    # 输出结果是一个形状为[1,15,30522]的张量。其中,1代表批次个数,15代表输入句子中的15个单词,30522是词表中单词的个数。
    # 模型的结果表示词表中每个单词在句子中可能出现的概率。
    outputs = model(tokens_tensor, token_type_ids=segments_tensors)
predictions = outputs[0]  # [1, 15, 30522]
# 预测结果:从输出结果中取出[MASK]字符对应的预测索引值。
predicted_index = torch.argmax(predictions[0, masked_index]).item()
# 将预测索引值转换为单词。
predicted_token = tokenizer.convert_ids_to_tokens([predicted_index])[0]
print('预测词为:', predicted_token)
# 预测词为: li


3 代码总览---BERT_MASK.py


import torch
from transformers import BertTokenizer, BertForMaskedLM
# 1.1 载入词表,并对输入的文本进行分词转化
# 加载预训练模型
tokenizer = BertTokenizer.from_pretrained('bert-base-uncased')
# 输入文本,BERT模型需要特殊词来标定句子:
# [CLS]:标记一个段落的开始。一个段落可以有一个或多个句子,但是只能有一个[CLS]。[CLS]在BERT模型中还会被用作分类任务的输出特征。
# [SEP]:标记一个句子的结束。在一个段落中,可以有多个[SEP]。
text = "[CLS] Who is Li BiGor ? [SEP] Li BiGor is a programmer [SEP]"
tokenized_text = tokenizer.tokenize(text)
# 使用词表对输入文本进行转换。与中文分词有点类似。由于词表中不可能覆盖所有的单词,因此当输入文本中的单词不存在时,系统会使用带有通配符的单间(以“#”开头的单词)将其拆开。
print("词表转化结果:",tokenized_text)
# 词表转化结果:['[CLS]','who','is','li','big','##or','?','[SEP]','li','big','##or','is','a','programmer','[SEP]']
# 1.2 遮蔽单词,并将其转换为索引值,使用标记字符[MAS]代替输入文本中索引值为8的单词,对“Li”进行遮蔽,并将整个句子中的单词转换为词表中的索引值。
masked_index = 8  # 掩码一个标记,再使用'BertForMaskedLM'预测回来
tokenized_text[masked_index] = '[MASK]' # 标记字符[MASK],是BERT模型中的特殊标识符。在BERT模型的训练过程中,会对输入文本的随机位置用[MASK]字符进行替换,并训练模型预测出[MASK]字符对应的值。
print("句子中的索引:",tokenized_text)
# 句子中的索引:['[CLS]','who','is','li','big','##or','?','[SEP]','[MASK]','big','##or','is','a','programmer','[SEP]']
# 将标记转换为词汇表索引
indexed_tokens = tokenizer.convert_tokens_to_ids(tokenized_text)
# 将输入转换为PyTorch张量
tokens_tensor = torch.tensor([indexed_tokens])
print("句子中的向量:",tokens_tensor)
# 句子中的向量:tensor([[101,2040,2003,5622,2502,2953,1029,102,103,2502,2953,2003,1037,20273,102]])
# 1.3 加载预训练模型,并对遮蔽单词进行预测
# 指定设备
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
print(device)
# 加载预训练模型 (weights)
model = BertForMaskedLM.from_pretrained('bert-base-uncased') # 用BertForMaskedLM类加载模型,该类可以对句子中的标记字符[MASK]进行预测。
model.eval()
model.to(device)
# 段标记索引:定义输入的BertForMaskedLM类句子指示参数,用于指示输入文本中的单词是属于第一句还是属于第二句。属于第一句的单词用0来表示(一共8个),属于第二句的单词用1来表示(一共7个)。
segments_ids = [0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1]
segments_tensors = torch.tensor([segments_ids]).to(device)
tokens_tensor = tokens_tensor.to(device)
# 预测所有的tokens
with torch.no_grad():
    # 将文本和句子指示参数输入模型进行预测。
    # 输出结果是一个形状为[1,15,30522]的张量。其中,1代表批次个数,15代表输入句子中的15个单词,30522是词表中单词的个数。
    # 模型的结果表示词表中每个单词在句子中可能出现的概率。
    outputs = model(tokens_tensor, token_type_ids=segments_tensors)
predictions = outputs[0]  # [1, 15, 30522]
# 预测结果:从输出结果中取出[MASK]字符对应的预测索引值。
predicted_index = torch.argmax(predictions[0, masked_index]).item()
# 将预测索引值转换为单词。
predicted_token = tokenizer.convert_ids_to_tokens([predicted_index])[0]
print('预测词为:', predicted_token)
# 预测词为: li


目录
相关文章
|
2月前
|
监控 安全 Linux
在 Linux 系统中,网络管理是重要任务。本文介绍了常用的网络命令及其适用场景
在 Linux 系统中,网络管理是重要任务。本文介绍了常用的网络命令及其适用场景,包括 ping(测试连通性)、traceroute(跟踪路由路径)、netstat(显示网络连接信息)、nmap(网络扫描)、ifconfig 和 ip(网络接口配置)。掌握这些命令有助于高效诊断和解决网络问题,保障网络稳定运行。
96 2
|
2月前
|
数据采集 存储 JSON
Python网络爬虫:Scrapy框架的实战应用与技巧分享
【10月更文挑战第27天】本文介绍了Python网络爬虫Scrapy框架的实战应用与技巧。首先讲解了如何创建Scrapy项目、定义爬虫、处理JSON响应、设置User-Agent和代理,以及存储爬取的数据。通过具体示例,帮助读者掌握Scrapy的核心功能和使用方法,提升数据采集效率。
127 6
|
18天前
|
人工智能 搜索推荐 决策智能
不靠更复杂的策略,仅凭和大模型训练对齐,零样本零经验单LLM调用,成为网络任务智能体新SOTA
近期研究通过调整网络智能体的观察和动作空间,使其与大型语言模型(LLM)的能力对齐,显著提升了基于LLM的网络智能体性能。AgentOccam智能体在WebArena基准上超越了先前方法,成功率提升26.6个点(+161%)。该研究强调了与LLM训练目标一致的重要性,为网络任务自动化提供了新思路,但也指出其性能受限于LLM能力及任务复杂度。论文链接:https://arxiv.org/abs/2410.13825。
49 12
|
1月前
|
机器学习/深度学习 人工智能 PyTorch
Transformer模型变长序列优化:解析PyTorch上的FlashAttention2与xFormers
本文探讨了Transformer模型中变长输入序列的优化策略,旨在解决深度学习中常见的计算效率问题。文章首先介绍了批处理变长输入的技术挑战,特别是填充方法导致的资源浪费。随后,提出了多种优化技术,包括动态填充、PyTorch NestedTensors、FlashAttention2和XFormers的memory_efficient_attention。这些技术通过减少冗余计算、优化内存管理和改进计算模式,显著提升了模型的性能。实验结果显示,使用FlashAttention2和无填充策略的组合可以将步骤时间减少至323毫秒,相比未优化版本提升了约2.5倍。
61 3
Transformer模型变长序列优化:解析PyTorch上的FlashAttention2与xFormers
|
2月前
|
机器学习/深度学习 自然语言处理 数据可视化
【由浅到深】从神经网络原理、Transformer模型演进、到代码工程实现
阅读这个文章可能的收获:理解AI、看懂模型和代码、能够自己搭建模型用于实际任务。
148 11
|
1月前
|
存储 安全 网络安全
网络安全的盾与剑:漏洞防御与加密技术的实战应用
在数字化浪潮中,网络安全成为保护信息资产的重中之重。本文将深入探讨网络安全的两个关键领域——安全漏洞的防御策略和加密技术的应用,通过具体案例分析常见的安全威胁,并提供实用的防护措施。同时,我们将展示如何利用Python编程语言实现简单的加密算法,增强读者的安全意识和技术能力。文章旨在为非专业读者提供一扇了解网络安全复杂世界的窗口,以及为专业人士提供可立即投入使用的技术参考。
|
1月前
|
存储 缓存 监控
Docker容器性能调优的关键技巧,涵盖CPU、内存、网络及磁盘I/O的优化策略,结合实战案例,旨在帮助读者有效提升Docker容器的性能与稳定性。
本文介绍了Docker容器性能调优的关键技巧,涵盖CPU、内存、网络及磁盘I/O的优化策略,结合实战案例,旨在帮助读者有效提升Docker容器的性能与稳定性。
133 7
|
2月前
|
数据采集 前端开发 中间件
Python网络爬虫:Scrapy框架的实战应用与技巧分享
【10月更文挑战第26天】Python是一种强大的编程语言,在数据抓取和网络爬虫领域应用广泛。Scrapy作为高效灵活的爬虫框架,为开发者提供了强大的工具集。本文通过实战案例,详细解析Scrapy框架的应用与技巧,并附上示例代码。文章介绍了Scrapy的基本概念、创建项目、编写简单爬虫、高级特性和技巧等内容。
105 4
|
2月前
|
网络协议 调度 开发者
Python网络编程:Twisted框架的异步IO处理与实战
【10月更文挑战第27天】本文介绍了Python网络编程中的Twisted框架,重点讲解了其异步IO处理机制。通过反应器模式,Twisted能够在单线程中高效处理多个网络连接。文章提供了两个实战示例:一个简单的Echo服务器和一个HTTP服务器,展示了Twisted的强大功能和灵活性。
54 0
|
7月前
|
机器学习/深度学习 PyTorch 算法框架/工具
【从零开始学习深度学习】28.卷积神经网络之NiN模型介绍及其Pytorch实现【含完整代码】
【从零开始学习深度学习】28.卷积神经网络之NiN模型介绍及其Pytorch实现【含完整代码】

热门文章

最新文章