news 2026/2/9 2:00:09

九.vocab字典操作

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
九.vocab字典操作

实例代码

#编码的例子 from transformers import BertTokenizer # 1. 加载本地模型和分词器 model_dir = "D:\\本地模型\\google-bert\\bert-base-chinese" tokenizer = BertTokenizer.from_pretrained(model_dir) #打印特殊符号 print(tokenizer) sents = ["酒店太旧了,大堂感觉象三星级的,房间也就是的好点的三星级的条件,在青岛这样的酒店是绝对算不上四星标准,早餐走了两圈也没有" "已经贴完了,又给小区的妈妈买了一套。最值得推荐", "屏幕大,本本薄,自带数字小键盘,比较少见。声音也还过得去。usb接口多,有四个。独显看高清很好。运行速度也还可以,性价比高!", "酒店环境很好 就是有一点点偏 交通不是很便利 去哪都需要达车 关键是不好打 酒店应该想办法解决一下"] #批量编码句子 out = tokenizer.batch_encode_plus( batch_text_or_text_pairs=[sents[0],sents[1]], add_special_tokens=True, #当句子长度大于max_length时,截断 truncation=True, #一律补零到max_length长度 padding="max_length", max_length=30, #可取tf,pt,np,默认为返回list return_tensors=None, #返回attention_mask return_attention_mask=True, #返回token_type_ids #返回offset_mapping 标识每个词的起止位置,这个参数只BertTokenizerFast使用 # return_offsets_mapping=True, #返回length 标识长度 return_length=True, ) #input_ids 就是编码后的词 #token_type_ids 第一个句子和特殊符号的位置是0,第二个句子的位置是1 #special_tokens_mask 特殊符号的位置是1,其他位置是0 #attention_mask pad的位置是0,其他位置是1 #length 返回句子长度 print(out) for k, v in out.items(): print(k,":",v) print(tokenizer.decode(out["input_ids"][0]),tokenizer.decode(out["input_ids"][1]))

输出特殊符号

无法识别的字符,全部定义为unk

实例2 字典操作

# 字典操作中添加新词 from transformers import ( BertTokenizer, ) # 1. 加载本地模型和分词器 model_dir = "D:\\本地模型\\google-bert\\bert-base-chinese" tokenizer = BertTokenizer.from_pretrained(model_dir) #打印特字典 vocab=tokenizer.get_vocab() print(len(vocab)) print("阳" in vocab) print("光" in vocab) #以每一个中文字符为节点划分,所以添加的词不在vocab中 print("阳光" in vocab) #添加新词 tokenizer.add_tokens(new_tokens=["阳光","大地"]) vocab = tokenizer.get_vocab() print("阳光" in vocab) print(tokenizer.tokenize("阳光")) print(len(vocab)) #添加新的特殊符号 tokenizer.add_special_tokens({"eos_token":"[EOS]"}) vocab = tokenizer.get_vocab() print(vocab) print(tokenizer) print("[EOS]" in vocab) out=tokenizer.encode(text="阳光照在大地上[EOS]", text_pair=None, truncation=True, padding="max_length", max_length=10, add_special_tokens=True) print(out) #解码为原来的字符串 print(tokenizer.decode(out))

BERT(Bidirectional Encoder Representations from Transformers)使用的是WordPiece分词算法,该算法将单词分解为更小的子词单元。对于中文文本,BERT分词器通常采用字符级分词,将每个汉字视为独立的token。

词汇表(字典)是分词器的核心组成部分,它决定了模型能够理解和处理哪些词汇。当遇到词汇表中不存在的词汇时,分词器会将其拆分为已知的子词,这可能导致语义信息的丢失。

2.1 原始词汇表的局限性

让我们通过代码示例来观察原始词汇表的局限性:

from transformers import BertTokenizer # 加载本地模型和分词器 model_dir = "D:\\本地模型\\google-bert\\bert-base-chinese" tokenizer = BertTokenizer.from_pretrained(model_dir) # 打印词汇表基本信息 vocab = tokenizer.get_vocab() print(f"原始词汇表大小: {len(vocab)}") # 检查单个字符是否在词汇表中 print("'阳'在词汇表中:", "阳" in vocab) # 输出: True print("'光'在词汇表中:", "光" in vocab) # 输出: True # 检查词语是否在词汇表中 print("'阳光'在词汇表中:", "阳光" in vocab) # 输出: False

从输出结果可以看出,虽然单个汉字"阳"和"光"都存在于词汇表中,但它们的组合"阳光"却不在其中。这是因为BERT-base-chinese模型采用字符级分词,词汇表主要包含单个汉字和少量常见词语。

2.2 词汇缺失的影响

当词汇表中缺少特定词语时,分词器会将其拆分为单个字符。例如:

  • "阳光" → ["阳", "光"]

  • "人工智能" → ["人", "工", "智", "能"]

这种拆分可能导致以下问题:

  1. 语义信息丢失:词语的整体含义被分解

  2. 序列长度增加:影响模型处理效率

  3. 上下文理解不准确:模型难以捕捉词语的整体语义

三、解决方案:动态添加新词

3.1 使用add_tokens方法扩展词汇表

Transformers库提供了便捷的add_tokens方法,允许我们动态地向分词器添加新词:

# 添加新词 tokenizer.add_tokens(new_tokens=["阳光", "大地"]) # 验证添加结果 vocab = tokenizer.get_vocab() print("'阳光'在词汇表中:", "阳光" in vocab) # 输出: True print(f"扩展后词汇表大小: {len(vocab)}") # 增加了2 # 测试分词效果 print("分词结果:", tokenizer.tokenize("阳光")) # 输出: ['阳光']

3.2 方法详解

add_tokens方法的主要特性:

  1. 支持批量添加:可以一次添加多个新词

  2. 保持分词一致性:新词会被作为一个整体进行分词

  3. 词汇表动态扩展:不会影响原有词汇表的功能

四、实际应用场景

4.1 专业领域术语处理

在医疗、法律、金融等专业领域,存在大量专业术语。例如,在医疗领域可以添加:

medical_terms = ["冠状动脉", "心电图", "核磁共振", "化疗"] tokenizer.add_tokens(new_tokens=medical_terms)

4.2 新兴词汇和网络用语

随着语言的发展,不断涌现出新词汇和网络用语:

new_words = ["元宇宙", "区块链", "内卷", "躺平"] tokenizer.add_tokens(new_tokens=new_words)

4.3 特定应用场景定制

针对具体应用场景,可以添加相关词汇:

# 电商场景 ecommerce_words = ["包邮", "满减", "预售", "秒杀"] tokenizer.add_tokens(new_tokens=ecommerce_words)

五、注意事项与最佳实践

5.1 模型权重调整

添加新词后,模型的embedding层需要相应扩展。如果继续使用原有模型,新添加的词会被随机初始化。建议对新词进行微调:

# 扩展模型embedding层 model.resize_token_embeddings(len(tokenizer)) # 对新添加的词进行微调 # ... 微调代码 ...

5.2 词汇添加策略

  1. 必要性评估:只添加高频且重要的词汇

  2. 避免冗余:不要添加已存在的子词组合

  3. 批量处理:对大量词汇进行批量添加以提高效率

5.3 性能考虑

  1. 词汇表大小:过大的词汇表会影响模型推理速度

  2. 内存占用:增加词汇表会占用更多内存

  3. 训练效率:微调时需要更多计算资源

六、完整示例代码

from transformers import BertTokenizer, BertModel import torch # 1. 加载分词器和模型 model_dir = "D:\\本地模型\\google-bert\\bert-base-chinese" tokenizer = BertTokenizer.from_pretrained(model_dir) model = BertModel.from_pretrained(model_dir) # 2. 原始词汇表分析 original_vocab_size = len(tokenizer) print(f"原始词汇表大小: {original_vocab_size}") # 3. 添加新词 new_tokens = ["阳光", "大地", "人工智能", "机器学习"] tokenizer.add_tokens(new_tokens) print(f"添加{len(new_tokens)}个新词后词汇表大小: {len(tokenizer)}") # 4. 调整模型embedding层 model.resize_token_embeddings(len(tokenizer)) # 5. 测试分词效果 test_text = "今天的阳光很好,适合机器学习实践。" tokens = tokenizer.tokenize(test_text) print(f"分词结果: {tokens}") # 6. 编码测试 inputs = tokenizer(test_text, return_tensors="pt") with torch.no_grad(): outputs = model(**inputs) print(f"编码后张量形状: {outputs.last_hidden_state.shape}")

七、总结

动态扩展BERT分词器的词汇表是一项实用且重要的技术,能够有效解决实际应用中的词汇覆盖问题。通过本文的详细解析,我们了解到:

  1. 问题根源:预训练模型的词汇表难以覆盖所有应用场景

  2. 解决方案:使用add_tokens方法动态添加新词

  3. 应用价值:提升模型对专业术语、新兴词汇的理解能力

  4. 最佳实践:合理选择添加词汇,注意模型权重调整

在实际应用中,建议根据具体需求制定词汇添加策略,平衡模型性能和词汇覆盖范围。通过合理的词汇扩展和模型微调,可以显著提升模型在特定领域的表现。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/2/8 2:12:15

VirtualBox(轻量级虚拟机软件)

VirtualBox是由Oracle公司开发的一款开源的虚拟机软件,可以在一台物理机上运行多个虚拟的操作系统。用户可以 软件功能 支持多种操作系统:VirtualBox支持安装和运行多种操作系统,包括Windows、Linux、Mac OS等。 虚拟硬件支持:Vi…

作者头像 李华
网站建设 2026/2/6 21:30:12

小程序计算机毕设之基于Android二手生活用品交易系统设计基于Android的旧物交易平台的设计与实现(完整前后端代码+说明文档+LW,调试定制等)

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围:&am…

作者头像 李华
网站建设 2026/2/5 15:15:01

参团活动说明

活动说明一、活动说明拼团是各购物平台新增的一种营销活动工具,买家通过自身分享邀请好友组团,成团后享受卖家商品的让利。 拼团的发起者称为“团长”,在发起拼团后,团长会将拼团活动的相关信息发布到社群,社群用户如果…

作者头像 李华
网站建设 2026/2/8 8:37:46

商城系统抽奖功能

一、功能介绍 抽奖活动凭借着以小博大的杠杆效应、低门槛参与、高奖励诱惑的活动机制,无论是线下门店促销,还是线上活动,都被广泛用于拉新、促活、获客等增长环节。 我们采用九宫格/大转盘抽奖的方式,后台可设置8个奖品&#xff…

作者头像 李华
网站建设 2026/2/7 11:24:28

【课程设计/毕业设计】基于微信小程序的医院预约挂号系统基于springboot的医院门诊智能预约平台小程序设计与实现【附源码、数据库、万字文档】

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围:&am…

作者头像 李华
网站建设 2026/2/5 13:14:06

Vue动态组件以及keep-alive的使用

文章目录一、动态组件1Vue的动态组件用法二、keep-alive2.1基础用法概念2.2包含include和排除exclude属性2.3 最大缓存实例数2.4 缓存实例的生命周期一、动态组件 1Vue的动态组件用法 <template><div class"app-container"><h1>App 根组件</h…

作者头像 李华