训练Transformer实现英法翻译
立即解锁
发布时间: 2025-09-05 01:43:18 阅读量: 6 订阅数: 25 AIGC 

# 训练 Transformer 实现英法翻译
## 1. 项目概述
我们的目标是训练一个 Transformer 模型,实现从英语到法语的翻译。通过探索将英语句子转换为法语的模型训练过程,我们能深入理解 Transformer 的架构和注意力机制的运作。
### 1.1 主要步骤
- 对英语和法语短语进行子词分词。
- 理解词嵌入和位置编码。
- 从头开始训练 Transformer 进行英法翻译。
- 使用训练好的 Transformer 将英语短语翻译成法语。
### 1.2 数据准备
我们有超过 47,000 对英法翻译数据。具体操作步骤如下:
1. 访问 [https://mng.bz/WVAw](https://mng.bz/WVAw) 下载包含英法翻译的压缩文件。
2. 解压文件,并将 `en2fr.csv` 放在计算机的 `/files/` 文件夹中。
以下是加载数据并打印示例的代码:
```python
import pandas as pd
df = pd.read_csv("files/en2fr.csv")
num_examples = len(df)
print(f"there are {num_examples} examples in the training data")
print(df.iloc[30856]["en"])
print(df.iloc[30856]["fr"])
```
输出结果:
```
there are 47173 examples in the training data
How are you?
Comment êtes-vous?
```
## 2. 子词分词
### 2.1 分词方法选择
分词方法有字符级分词、词级分词和子词分词。我们选择子词分词,它在其他两种方法之间取得了平衡,能将常用词完整保留在词汇表中,将不常见或更复杂的词拆分为子组件。
### 2.2 英法短语分词
#### 2.2.1 安装库
在 Jupyter Notebook 的新单元格中运行以下代码,安装 `transformers` 库:
```python
!pip install transformers
```
#### 2.2.2 使用预训练分词器
我们使用 Hugging Face 的预训练 XLM 模型作为分词器,因为它擅长处理多种语言,包括英语和法语短语。以下是分词示例代码:
```python
from transformers import XLMTokenizer
tokenizer = XLMTokenizer.from_pretrained("xlm-clm-enfr-1024")
tokenized_en = tokenizer.tokenize("I don't speak French.")
print(tokenized_en)
tokenized_fr = tokenizer.tokenize("Je ne parle pas français.")
print(tokenized_fr)
print(tokenizer.tokenize("How are you?"))
print(tokenizer.tokenize("Comment êtes-vous?"))
```
输出结果:
```
['i</w>', 'don</w>', "'t</w>", 'speak</w>', 'fr', 'ench</w>', '.</w>']
['je</w>', 'ne</w>', 'parle</w>', 'pas</w>', 'franc', 'ais</w>', '.</w>']
['how</w>', 'are</w>', 'you</w>', '?</w>']
['comment</w>', 'et', 'es-vous</w>', '?</w>']
```
#### 2.2.3 注意事项
XLM 模型使用 `</w>` 作为词分隔符,但当两个子词属于同一个单词时除外。例如,“French” 被拆分为 “fr” 和 “ench”,模型不会在它们之间插入 `</w>`。
### 2.3 构建词汇表
深度学习模型不能直接处理原始文本,因此我们需要将文本转换为数字表示。具体步骤如下:
#### 2.3.1 构建英语词汇字典
```python
from collections import Counter
en = df["en"].tolist()
en_tokens = [["BOS"] + tokenizer.tokenize(x) + ["EOS"] for x in en]
PAD = 0
UNK = 1
word_count = Counter()
for sentence in en_tokens:
for word in sentence:
word_count[word] += 1
frequency = word_count.most_common(50000)
total_en_words = len(frequency) + 2
en_word_dict = {w[0]: idx + 2 for idx, w in enumerate(frequency)}
en_word_dict["PAD"] = PAD
en_word_dict["UNK"] = UNK
en_idx_dict = {v: k for k, v in en_word_dict.items()}
```
#### 2.3.2 英语句子转换为数字表示
```python
enidx = [en_word_dict.get(i, UNK) for i in tokenized_en]
print(enidx)
```
输出结果:
```
[15, 100, 38, 377, 476, 574, 5]
```
#### 2.3.3 数字表示还原为英语句子
```python
entokens = [en_idx_dict.get(i, "UNK") for i in enidx]
print(entokens)
en_phrase = "".join(entokens)
en_phrase = en_phrase.replace("</w>", " ")
for x in '''?:;.,'("-!&)%''':
en_phrase = en_phrase.replace(f" {x}", f"{x}")
print(en_phrase)
```
输出结果:
```
['i</w>', 'don</w>', "'t</w>", 'speak</w>', 'fr', 'ench</w>', '.</w>']
i don't speak french.
```
#### 2.3.4 练习 1
在前面的示例中,“How are you?” 被拆分为 `['how</w>', 'are</w>', 'you</w>', '?</w>']`。请按照上述步骤完成以下操作:
1. 使用 `en_word_dict` 将这些标记转换为索引。
2. 使用 `en_idx_dict` 将索引转换回标记。
3. 通过将标记连接成字符串,将分隔符 `</w>` 替换为空格,并去除标点符号前的空格,恢复英语句子。
#### 2.3.5 构建法语词汇字典
```python
fr = df["fr"].tolist()
fr_tokens = [["BOS"] + tokenizer.tokenize(x) + ["EOS"] for x in fr]
word_count = Counter()
for sentence in fr_tokens:
for word in sentence:
word_count[word] += 1
frequency = word_count.most_common(50000)
total_fr_words = len(frequency) + 2
fr_word_dict = {w[0]: idx + 2 for idx, w in enumerate(frequency)}
fr_word_dict["PAD"] = PAD
fr_word_dict["UNK"] = UNK
fr_idx_dict = {v: k for k, v in fr_word_dict.items()}
```
#### 2.3.6 法语句子转换为数字表示
```python
fridx = [fr_word_dict.get(i, UNK) for i in tokenized_fr]
print(fridx)
```
输出结果:
```
[28, 40, 231, 32, 726, 370, 4]
```
#### 2.3.7 数字表示还原为法语句子
```python
frtokens = [fr_idx_dict.get(i, "UNK") for i in fridx]
print(frtokens)
fr_phrase = "".join(frtokens)
fr_phrase = fr_phrase.replace("</w>", " ")
for x in '''?:;.,'("-!&)%''':
fr_phrase = fr_phrase.re
```
0
0
复制全文
相关推荐









