### 使用 Transformer 进行机器翻译的实际操作教程
以下是基于 Transformer 的机器翻译实际操作教程,涵盖了从环境搭建到模型训练的全过程。
#### 1. 导入必要的库
为了实现 Transformer 模型,需要导入 PyTorch 和其他辅助库。
```python
import torch
import torch.nn as nn
from torchtext.data.utils import get_tokenizer
from torchtext.vocab import build_vocab_from_iterator
from torch.utils.data import DataLoader
```
这些库提供了构建和训练 Transformer 所需的功能[^1]。
#### 2. 数据集准备
加载并处理数据集是关键一步。假设我们有一个双语文本文件作为数据源。
```python
def yield_tokens(data_iter, tokenizer_src, tokenizer_tgt):
for src_line, tgt_line in data_iter:
yield tokenizer_src(src_line)
yield tokenizer_tgt(tgt_line)
SRC_LANGUAGE = 'ja'
TGT_LANGUAGE = 'zh'
token_transform = {
SRC_LANGUAGE: get_tokenizer('spacy', language='ja'),
TGT_LANGUAGE: get_tokenizer('spacy', language='zh')
}
train_data = [("こんにちは", "你好"), ("ありがとう", "谢谢")] # 示例数据
vocab_transform = {lang: build_vocab_from_iterator(yield_tokens(train_data, token_transform[SRC_LANGUAGE], token_transform[TGT_LANGUAGE]), specials=["<unk>", "<pad>"]) for lang in [SRC_LANGUAGE, TGT_LANGUAGE]}
```
上述代码展示了如何定义标记化函数以及生成词汇表的过程。
#### 3. 构建 Sequence-to-Sequence Transformer 模型
Transformer 结构由编码器和解码器组成。
```python
class Seq2SeqTransformer(nn.Module):
def __init__(self, num_encoder_layers, num_decoder_layers, emb_size, nhead, vocab_size_src, vocab_size_tgt, dim_feedforward=512, dropout=0.1):
super(Seq2SeqTransformer, self).__init__()
self.transformer = nn.Transformer(d_model=emb_size, nhead=nhead, num_encoder_layers=num_encoder_layers,
num_decoder_layers=num_decoder_layers, dim_feedforward=dim_feedforward, dropout=dropout)
self.generator = nn.Linear(emb_size, vocab_size_tgt)
self.src_tok_emb = TokenEmbedding(vocab_size_src, emb_size)
self.tgt_tok_emb = TokenEmbedding(vocab_size_tgt, emb_size)
self.positional_encoding = PositionalEncoding(emb_size, dropout=dropout)
def forward(self, src, trg, src_mask, tgt_mask, src_padding_mask, tgt_padding_mask, memory_key_padding_mask):
src_emb = self.positional_encoding(self.src_tok_emb(src))
tgt_emb = self.positional_encoding(self.tgt_tok_emb(trg))
outs = self.transformer(src_emb, tgt_emb, src_mask, tgt_mask, None, src_padding_mask, tgt_padding_mask, memory_key_padding_mask)
return self.generator(outs)
def encode(self, src, src_mask):
return self.transformer.encoder(self.positional_encoding(self.src_tok_emb(src)), src_mask)
def decode(self, tgt, memory, tgt_mask):
return self.transformer.decoder(self.positional_encoding(self.tgt_tok_emb(tgt)), memory, tgt_mask)
```
此部分描述了完整的 Transformer 模型结构及其初始化参数。
#### 4. 训练模型
通过自定义损失函数优化模型性能。
```python
loss_fn = nn.CrossEntropyLoss(ignore_index=vocab_transform[TGT_LANGUAGE]["<pad>"])
optimizer = torch.optim.Adam(transformer.parameters(), lr=0.0001, betas=(0.9, 0.98), eps=1e-9)
for epoch in range(num_epochs):
transformer.train()
losses = []
for batch in train_dataloader:
src, tgt = batch.src, batch.trg
tgt_input = tgt[:-1, :]
src_mask, tgt_mask, src_padding_mask, tgt_padding_mask = create_masks(src, tgt_input)
logits = transformer(src, tgt_input, src_mask, tgt_mask, src_padding_mask, tgt_padding_mask, src_padding_mask)
optimizer.zero_grad()
tgt_out = tgt[1:, :]
loss = loss_fn(logits.reshape(-1, logits.shape[-1]), tgt_out.reshape(-1))
loss.backward()
optimizer.step()
losses.append(loss.item())
```
该片段说明了如何利用交叉熵损失来调整模型权重。
#### 5. 测试模型
验证模型效果可以通过简单的输入输出对比完成。
```python
input_seq = 'ils regardent .'
translate(encoder, decoder, input_seq, max_seq_len) # 输出应接近“they are watching.”
```
这是对法语句子进行英译的一个例子[^3]。
---
###