机器翻译实战(英译汉)Transformer代码学习详解 您所在的位置:网站首页 嗨用英文怎么翻译成中文的 机器翻译实战(英译汉)Transformer代码学习详解

机器翻译实战(英译汉)Transformer代码学习详解

#机器翻译实战(英译汉)Transformer代码学习详解| 来源: 网络整理| 查看: 265

任务目标

基于Transformer实现英语翻译汉语。如有疏忽请多指教

数据 Hi. 嗨。 Hi. 你好。 Run. 你用跑的。 Wait! 等等! Hello! 你好。 I try. 让我来。 I won! 我赢了。 Oh no! 不会吧。 Cheers! 乾杯! Got it? 你懂了吗? He ran. 他跑了。 Hop in. 跳进来。 I lost. 我迷失了。 I quit. 我退出。 I'm OK. 我沒事。 Listen. 听着。 No way! 不可能! No way! 没门! Really? 你确定? Try it. 试试吧。 We try. 我们来试试。 Why me? 为什么是我? …… …… 代码&数据来源

Github:transformer-simple 哈弗NLP

Transformer模型结构 Transformer的组成 1. Encoder a. 若干个EncoderLayer(两个子层) i. Feed Forward Neural Network connected layer.子层间使用Add & Normalization 相连 ii. Self-Attention 2. Decoder a. 若干个DecoderLayer(三个子层) i. Feed Forward Neural Network connected layer.子层间使用Add & Normalization 相连 ii. Encoder-Decoder-Attention,常规注意力机制 connected layer.子层间使用Add & Normalization 相连 iii. Self-Attention,自注意力机制

在这里插入图片描述

Batch and Masking Mask策略一

一种就是普通的mask,就是自然语言处理中将某些字符(如标点符号,空格等)进行mask的操作

# 该部分与transformer实现有关 class Batch: """ Batches and Masking "Object for holding a batch of data with mask during training." 在训练期间使用mask处理数据 """ def __init__(self, src, trg=None, pad=0): """ 构造函数 @param src: 源数据 @param trg: 目标数据 @param pad: 需要mask掉的字符,默认为0 一共有两种mask的方式: 一种就是普通的mask,就是自然语言处理中将某些字符(如标点符号,空格等)进行mask的操作 另一种就是对目标数据的mask,其原因是为了不让decoder在训练中看到后续的内容(即,我对于下一个字符的预测,只来源于前面的字符) 对于src的mask就是第一种mask,而对于tgt的mask是第一种加第二种 """ # 将numpy.array转换为张量torch.tensor src = torch.from_numpy(src).to(args.device).long() trg = torch.from_numpy(trg).to(args.device).long() self.src = src # 此处pad=0,src向量均不为0(0表示UNK标识),src!=pad生成bool数组,且数组所有元素均为True # 此处为第一种mask策略 self.src_mask = (src != pad).unsqueeze(-2) # unsqueeze()扩展维度,负数表示扩展的维度在倒数第n个位置 if trg is not None: self.trg = trg[:, :-1] # 截掉trg中每个句子最后一个字符 self.trg_y = trg[:, 1:] # 截掉trg中每个句子第一个字符 self.trg_mask = self.make_std_mask(self.trg, pad) # 对trg掩蔽 self.ntokens = (self.trg_y != pad).data.sum() @staticmethod def make_std_mask(tgt, pad): """ mask 目标数据 "Create a mask to hide padding and future words." 翻译:创造一个mask来屏蔽补全词和字典外的词进行屏蔽 @param tgt: 即构造函数中的trg,目标数据 @param pad: 需要mask的字符,默认为0 @return: 返回mask后的目标数据 """ # 此处为第一种mask策略 tgt_mask = (tgt != pad).unsqueeze(-2) # 由于没有0,此时布尔矩阵全为True # 此处为第二种mask策略,调用utils中的subsequent_mask方法得到上三角布尔矩阵 # Variable()封装tensor,并存储tensor的梯度,与tgt_mask做与运算 tgt_mask = tgt_mask & Variable(subsequent_mask(tgt.size(-1)).type_as(tgt_mask.data)) return tgt_mask Mask策略二

另一种就是对目标数据的mask,其原因是为了不让decoder在训练中看到后续的内容(即,我对于下一个字符的预测,只来源于前面的字符)

def subsequent_mask(size): """ 第二种mask策略 "Mask out subsequent positions." @param size: 句子长度 @return: """ attn_shape = (1, size, size) # np.triu函数生成一个对角线位置上移一位的上三角矩阵(k=1代表按对角线方向上移),矩阵大小为attn_shape subsequent_mask = np.triu(np.ones(attn_shape), k=1).astype('uint8') return torch.from_numpy(subsequent_mask) == 0 # 返回布尔矩阵,subsequent_mask上三角矩阵中0的位置对应True make_model

构造Transformer模型

def make_model(src_vocab, tgt_vocab, N = 6, d_model = 512, d_ff = 2048, h = 8, dropout = 0.1): """ 定义了一个接收超参数并生成完整模型的函数。 @param src_vocab: 源数据字典长度 @param tgt_vocab: 目标数据字典长度 @param N: 层数layer @param d_model: 表征后的维度 @param d_ff: FeedForward输出维度 @param h: attention机制,head多头个数 @param dropout: @return: """ c = copy.deepcopy attn = MultiHeadedAttention(h, d_model).to(args.device) # 多头注意力机制 ff = PositionwiseFeedForward(d_model, d_ff, dropout).to(args.device) position = PositionalEncoding(d_model, dropout).to(args.device) # 位置信息嵌入 # model其实是Transformer的类 model = Transformer( Encoder(EncoderLayer(d_model, c(attn), c(ff), dropout).to(args.device), N).to(args.device), Decoder(


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有