Transformer机器翻译模型(代码实现案例)

目标

  • 了解有关机器翻译的知识
  • 了解seq2seq架构
  • 使用Transformer构建机器翻译模型的实现过程

1 Transformer架构

Transformer模型架构分析

  • Transformer模型架构, 大范围内包括两部分分别是encoder(编码器)和decoder(解码器), 编码器和解码器的内部实现都使用了注意力机制实现, 这里它要完成的是一个德文到英文的翻译: Willkommen in peking → welcome to BeiJing. 编码器首先处理中文输入"Willkommen in peking", 通过Transformer内部的注意力机制提取信息之后的输出张量,就是一个中间语义张量c, 接着解码器将使用这个中间语义张量c以及每一个时间步的目标语言的语义张量, 逐个生成对应的翻译语言.

2 案例介绍

2.1 数据集:

  • 使用的是torchtext中自带的数据集Multi30k, 直接可以使用内置的API函数即可下载
# 默认下载的路径为: /root/.torchtext/cache/Multi30k
└── Multi30k
    ├── mmt16_task1_test.tar.gz
    ├── test.de
    ├── test.en
    ├── train.de
    ├── train.en
    ├── training.tar.gz
    ├── val.de
    ├── val.en
    └── validation.tar.gz

2.2 机器翻译过程

  • 第一步: 导入必备的工具包
  • 第二步: 导入Multi30k数据集并做基本处理
  • 第三步: 构建Transformer模型
  • 第四步: 定义mask的函数, 创建对应的不同的mask
  • 第五步: 定义批次数据处理的回调函数
  • 第六步: 构建训练函数和评估函数
  • 第七步: 训练Transformer模型
  • 第八步: 进行解码生成目标语言语句
  • 第九步: 模型的保存和重加载

3 案例实现步骤

1 导入必备的工具包

import torch
import torch.nn as nn
import math

from torchtext.data.utils import get_tokenizer
from torchtext.vocab import build_vocab_from_iterator
from torchtext.datasets import Multi30k
from typing import Iterable, List
from torch import Tensor
from torch.nn import Transformer
from torch.nn.utils.rnn import pad_sequence
from torch.utils.data import DataLoader
from timeit import default_timer as timer

DEVICE = torch.device('cuda' if torch.cuda.is_available() else 'cpu')

2 导入Multi30k数据集并做基本处理

2.1 加载对应的tokenizer
# 源语言是德语
SRC_LANGUAGE = 'de'
# 目标语言是英语
TGT_LANGUAGE = 'en'

# 定义token的字典, 定义vocab字典
token_transform = {}
vocab_transform = {}

# 创建源语言和目标语言的kokenizer, 确保依赖关系已经安装
# pip install -U spacy
# python -m spacy download en_core_web_sm
# python -m spacy download de_core_news_sm
# get_tokenizer是分词函数, 如果没有特殊的则按照英语的空格分割, 如果有这按照对应的分词库返回. 比如spacy, 返回对应的分词库
token_transform[SRC_LANGUAGE] = get_tokenizer('spacy', language='de_core_news_sm')
token_transform[TGT_LANGUAGE] = get_tokenizer('spacy', language='en_core_web_sm')
2.2 构建生成分词的迭代器
def yield_tokens(data_iter: Iterable, language: str) -> List[str]:
    # data_iter: 对象的迭代对象 Multi30k对象
    # language: 对应的翻译语言 {'de': 0, 'en': 1}
    language_index = {SRC_LANGUAGE: 0, TGT_LANGUAGE: 1}
    # 返回对应的数据迭代器对象
    for data_sample in data_iter:
        # data_sample:(德文, 英文)
        # data_sample:('Zwei junge weiße Männer sind im Freien in der Nähe vieler Büsche.\n', 'Two young, White males are outside near many bushes.\n')
        # token_transform['de']()=['Zwei', 'junge', 'weiße', 'Männer', 'sind', 'im', 'Freien', 'in', 'der', 'Nähe', 'vieler', 'Büsche', '.', '\n']
        # or  token_transform['en']分别进行构造对应的字典
        yield token_transform[language](data_sample[language_index[language]])
2.3 定义特殊字符并下载数据设置默认索引
# 定义特殊字符及其对应的索引值
UNK_IDX, PAD_IDX, BOS_IDX, EOS_IDX = 0, 1, 2, 3
# 确保标记按其索引的顺序正确插入到词汇表中
special_symbols = ['<unk>', '<pad>', '<bos>', '<eos>']

for ln in [SRC_LANGUAGE, TGT_LANGUAGE]:
    # 训练数据集的迭代器,
    # 数据集是用英文描述图像的英文语句, 然后人工将其翻译为德文的语句,有两个文件, 一个是train.de 一个是train.en文件,
    # 然后将其构建为(德文, 英文)的形式
    train_iter = Multi30k(split='train', language_pair=(SRC_LANGUAGE, TGT_LANGUAGE))
    # 创建torchtext的vocab对象, 即词汇表
    vocab_transform[ln] = build_vocab_from_iterator(yield_tokens(train_iter, ln), # 用于构建 Vocab 的迭代器。必须产生令牌列表或迭代器
                                                    min_freq=1,#在词汇表中包含一个标记所需的最低频率
                                                    specials=special_symbols, # 用于添加的特殊字符
                                                    special_first=True) # 指示是在开头还是结尾插入符号

# 将 UNK_IDX 设置为默认索引。未找到令牌时返回此索引
# 如果未设置,则在 Vocabulary
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

山山而川_R

谢谢鼓励

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值