迁移学习 - 中文填空案例 - 数据预处理
1 课程概览
本课讲解迁移学习中文填空案例的数据预处理。中文填空是完形填空任务,本质是分类问题。使用相同的数据源(train、test、validation)。词汇表有 21128 个字,所以有 21128 种可能。随机掩码句子中的某些词,然后做预测。
2 核心概念与定义
- 中文填空:完形填空任务,本质是分类问题。
- 随机掩码:随机遮掩句子中的某些词。
- 词汇表大小:21128 个字,有 21128 种可能。
3 模型与算法详解
中文填空概念
完形填空是一个分类问题。
- 填空:往 <tool_call> 位置填字
- 词汇表有 21128 个字
- 有 21128 种可能
- 本质是分类问题
与中文分类的区别
| 任务 | 输出维度 | 说明 |
|---|---|---|
| 中文分类 | 2 | 二分类(好评/差评) |
| 中文填空 | 21128 | 词汇表大小 |
数据源
使用相同的数据源。
| 文件 | 说明 |
|---|---|
| train | 训练集 |
| test | 测试集 |
| validation | 验证集 |
随机掩码
随机遮掩句子中的某些词,然后做预测。
- 设置随机数
- 把句子中的某几个词或某一个词随机掩码
- 然后做预测
模型选择
使用 BERT base chinese 模型。
| 任务 | 模型 |
|---|---|
| 中文填空 | bert-base-chinese |
数据预处理流程
1. 加载数据
2. 随机掩码句子中的某些词
3. 使用 BERT 分词器处理文本
4. 转成模型输入格式
损失函数
使用 AdamW 优化器。
| 任务 | 优化器 |
|---|---|
| 中文填空 | AdamW |
4 数学原理与推导
中文填空
$$P(w_{\text{mask}} | \text{context}) = \text{softmax}(\text{BERT}(\text{context}))$$
其中:
- $w_{\text{mask}}$ 是要预测的词
- $\text{context}$ 是上下文
- 概率有 21128 种可能
随机掩码
$$\text{masked_text} = \text{replace}(\text{text}, w_i, \text{[MASK]})$$
其中:
- $w_i$ 是随机选择的词
- $\text{[MASK]}$ 是掩码
5 代码示例
import torch
import random
from transformers import BertTokenizer
def collate_fn_fill_mask(data, my_tokenizer, device, max_length=300):
"""数据整理函数:中文填空任务"""
# 1. 提取文本
sentences = [item['text'] for item in data]
# 2. 随机掩码句子中的某些词
masked_sentences = []
mask_positions = [] # 记录掩码位置
for sentence in sentences:
# 将句子转成字列表
chars = list(sentence)
# 随机选择一个位置进行掩码
if len(chars) > 0:
mask_pos = random.randint(0, len(chars) - 1)
mask_positions.append(mask_pos)
chars[mask_pos] = my_tokenizer.mask_token # 替换为 [MASK]
masked_sentences.append(''.join(chars))
# 3. 使用 BERT 分词器处理文本
inputs = my_tokenizer.batch_encode_plus(
masked_sentences,
truncation=True,
max_length=max_length,
padding='max_length',
return_tensors='pt'
)
# 4. 转移到设备
inputs = {k: v.to(device) for k, v in inputs.items()}
return inputs, mask_positions
# 测试
if __name__ == "__main__":
print("=== 迁移学习:中文填空案例 - 数据预处理 ===")
model_name = "bert-base-chinese"
my_tokenizer = BertTokenizer.from_pretrained(model_name)
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
# 测试
data = [{'text': '手动扶梯很好用'}, {'text': '超市的东西很便宜'}]
inputs, mask_positions = collate_fn_fill_mask(data, my_tokenizer, device)
print(f"掩码位置: {mask_positions}")
print(f"输入张量: {inputs['input_ids'].shape}")
代码说明
| 代码 | 说明 |
|---|---|
random.randint(0, len(chars) - 1) | 随机选择掩码位置 |
my_tokenizer.mask_token | <tool_call> 占位符 |
batch_encode_plus(...) | 批量编码 |
mask_positions | 记录掩码位置 |
6 重难点与易错提醒
- ❗重点:中文填空本质是分类问题,有 21128 种可能。
- ❗重点:随机掩码句子中的某些词,然后做预测。
- ❗重点:使用相同的数据源。
- ⚠️易错:记录掩码位置,用于后续预测。
- 💡技巧:使用 AdamW 优化器。
7 课堂问答精选
Q1:中文填空本质是什么问题?
A:分类问题。往 <tool_call> 位置填字,词汇表有 21128 个字,有 21128 种可能。
Q2:中文填空和中文分类有什么区别?
A:中文分类是二分类(好评/差评),输出 2 维;中文填空是 21128 分类,输出 21128 维。
Q3:如何进行随机掩码?
A:设置随机数,把句子中的某几个词或某一个词随机掩码,替换为 <tool_call>,然后做预测。
Q4:使用什么数据源?
A:使用相同的数据源(train、test、validation),和中文分类案例一样。
8 本课小结
- 中文填空:完形填空任务,本质是分类问题。
- 词汇表有 21128 个字,有 21128 种可能。
- 随机掩码句子中的某些词,然后做预测。
- 使用相同的数据源。
- 使用 BERT base chinese 模型。
9 延伸思考
- 如何搭建中文填空模型?
- 中文填空模型和中文分类模型有什么区别?