【自然语言处理|Transformer架构-06】:编码部分实现

1 编码器层部分

  • 编码器层是编码器的组成单元(是编码部分的组成单元)
  • 完成一次对输入特征的提取, 即编码过程
    在这里插入图片描述
    在这里插入图片描述
# 编码器层类 EncoderLayer 实现思路分析
# init函数 (self, size, self_attn, feed_forward, dropout):
    # 实例化多头注意力层对象self_attn # 前馈全连接层对象feed_forward  self.size词嵌入维度512
    # clones两个子层连接结构 self.sublayer = clones(SublayerConnection(size,dropout),2)
# forward函数 (self, x, mask)
    # 数据经过子层连接结构1 self.sublayer[0](x, lambda x: self.self_attn(x, x, x, mask))
    # 数据经过子层连接结构2 self.sublayer[1](x, self.feed_forward)
class EncoderLayer(nn.Module):
    def __init__(self, size, self_attn, feed_forward, dropout):
        super(EncoderLayer, self).__init__()

        # 实例化多头注意力层对象self_attn
        self.self_attn = self_attn

        # 前馈全连接层对象feed_forward
        self.feed_forward = feed_forward

        # size词嵌入维度512
        self.size = size

        # clones两个子层连接结构 self.sublayer = clones(SublayerConnection(size,dropout),2)
        self.sublayer = clones(SublayerConnection(size, dropout), 2)

    def forward(self, x, mask):

        # 数据经过第1个 子层连接结构
        x = self.sublayer[0](x, lambda x:self.self_attn(x, x, x, mask))
        # x = self.sublayer[0](x, self.self_attn) # 这样写掉不起来

        # 数据经过第2个 子层连接结构
        x = self.sublayer[1](x, self.feed_forward)
        return x


def dm07_test_EncoderLayer():

    # 1-1 准备数据
    pe_result = torch.randn(2, 4, 512)

    # 1-2 实例化多头注意力机制对象
    mask = Variable(torch.zeros(8, 4, 4))
    my_mha = MultiHeadedAttention(8, 512, 0.1)

    # 1-3 实例化PositionwiseFeedForward
    d_model, d_ff = 512, 1024
    my_positionwisefeedforward = PositionwiseFeedForward(d_model, d_ff)

    # 实例化编码器层
    my_encoderlayer = EncoderLayer(512, my_mha, my_positionwisefeedforward, 0.1)
    print('my_encoderlayer-->', my_encoderlayer)

    el_result =  my_encoderlayer(pe_result, mask)
    print('el_result-->', el_result.shape)

在这里插入图片描述

1.1 深拷贝多头注意力机制和前馈全连接传参

  • 编码器层,在传入多头自注意力机制对象的时候,需要进行深拷贝,保证每个编码器层使用自己独立的my_mha对象,my_positionwisefeedforward对象;也就说每个层拥有自己独立自注意力层权重参数
# 实例化 一个 编码器层
c = copy.deepcopy
my_encoderlayer = EncoderLayer(512, c(my_mha), c(my_positionwisefeedforward), 0.1)

1.2 子层连接结构传参

在这里插入图片描述

2 编码器实现

  • 由N个编码器层堆叠而成
  • 编码器用于对输入进行指定的特征提取过程, 也称为编码

在这里插入图片描述

# 编码器类 Encoder 实现思路分析
# init函数 (self, layer, N)  # 注意layerobj是一个实例化后的对象 super()
    # 实例化多个编码器层对象self.layers=clones(layer, N)
    # 实例化规范化层 self.norm = LayerNorm(layer.size)
# forward函数 (self, x, mask)
    # 数据经过N个层 x = layer(x, mask)
    #  返回规范化后的数据 return self.norm(x)
class Encoder(nn.Module):
    def __init__(self, layer, N):
        # layer 是一个实例化层的对象
        super(Encoder, self).__init__()

        # 实例化多个层
        self.layers = clones(layer, N)

        # 实例化规范化层
        self.norm = LayerNorm(layer.size)

    def forward(self, x, mask):

        # 数据经过N个层 x = layer(x, mask)
        for layer in self.layers:
            x = layer(x, mask)

        #  返回规范化后的数据
        #  使用前置norm策略,在最后一个层输出的数据 需要 添加一个norm处理
        return self.norm(x)


def dm08_test_Encoder():
    c = copy.deepcopy

    # 1-1 准备数据
    pe_result = torch.randn(2, 4, 512)

    # 1-2 实例化多头注意力机制对象
    mask = Variable(torch.zeros(8, 4, 4))
    my_mha = MultiHeadedAttention(8, 512, 0.1)

    # 1-3 实例化PositionwiseFeedForward
    d_model, d_ff = 512, 1024
    my_positionwisefeedforward = PositionwiseFeedForward(d_model, d_ff)

    # 实例化 一个 编码器层
    my_encoderlayer = EncoderLayer(512, c(my_mha), c(my_positionwisefeedforward), 0.1)


    # 实例化编码器部分
    myencoder = Encoder(my_encoderlayer, 6)
    print('myencoder--->', myencoder)

    # 给模型喂数据
    encoder_result = myencoder(pe_result, mask)
    print('encoder_result--->', encoder_result.shape, encoder_result)

在这里插入图片描述

3 解码器层部分

  • 是解码器的组成单元
  • 每个解码器层根据给定的输入向目标方向进行特征提取操作,即解码过程
    在这里插入图片描述
# 解码器层类 DecoderLayer 实现思路分析
# init函数 (self, size, self_attn, src_attn, feed_forward, dropout)
    # 词嵌入维度尺寸大小size 自注意力机制层对象self_attn 一般注意力机制层对象src_attn 前馈全连接层对象feed_forward
    # clones3子层连接结构 self.sublayer = clones(SublayerConnection(size,dropout),3)
# forward函数 (self, x, memory, source_mask, target_mask)
    # 数据经过子层连接结构1 self.sublayer[0](x, lambda x:self.self_attn(x, x, x, target_mask))
    # 数据经过子层连接结构2 self.sublayer[1](x, lambda x:self.src_attn(x, m, m, source_mask))
    # 数据经过子层连接结构3 self.sublayer[2](x, self.feed_forward)
class DecoderLayer(nn.Module):

    def __init__(self, size, self_attn, src_attn, feed_forward, dropout):

        super(DecoderLayer, self).__init__()
        # 词嵌入维度尺寸大小size
        self.size = size

        # 自注意力机制层对象 self_attn
        self.self_attn = self_attn

        # 一般注意力机制层对象 src_attn
        self.src_attn = src_attn

        # 前馈全连接层对象 feed_forward
        self.feed_forward = feed_forward

        # clones3子层连接结构 self.sublayer = clones(SublayerConnection(size,dropout),3)
        self.sublayer = clones(SublayerConnection(size, dropout), 3)

    def forward(self, x, memory, source_mask, target_mask):
        m = memory
        # 数据经过子层连接结构1 self.sublayer[0](x, lambda x:self.self_attn(x, x, x, target_mask))
        x = self.sublayer[0](x, lambda x: self.self_attn(x, x, x, target_mask))

        # 数据经过子层连接结构2 self.sublayer[1](x, lambda x:self.src_attn(x, m, m, source_mask))
        x = self.sublayer[1](x, lambda x: self.src_attn(x, m, m, source_mask))

        # 数据经过子层连接结构3 self.sublayer[2](x, self.feed_forward)
        x = self.sublayer[2](x, self.feed_forward)
        return  x


def dm01_test_DecoderLayer():
    # 1-1 准备数据
    pe_result = torch.randn(2, 4, 512)

    # 1-2 实例化多头注意力机制对象
    source_mask = Variable(torch.zeros(8, 4, 4))
    target_mask = Variable(torch.zeros(8, 4, 4))
    self_attn = src_attn = MultiHeadedAttention(8, 512, 0.1)

    # 1-3 实例化PositionwiseFeedForward
    d_model, d_ff = 512, 1024
    ff = PositionwiseFeedForward(d_model, d_ff)

    # 实例化 一个 编码器层
    my_decoderlayer = DecoderLayer(512, self_attn, src_attn, ff, 0.1)
    print('my_decoderlayer--->', my_decoderlayer)

    # 准备编码器部分的最后编码结果 也就是中间语义张量C
    memory = torch.randn(2, 4, 512)

    dl_result = my_decoderlayer(pe_result, memory, source_mask, target_mask)
    print('dl_result--->', dl_result.shape, dl_result)

4 解码器实现

  • 多个解码器层组成解码器(解码器部分)
  • 根据编码器的结果以及上一次预测的结果, 对下一次可能出现的‘值’进行特征表示;
# 解码器类 Decoder 实现思路分析
# init函数 (self, layer, N): #  super()
    # self.layers clones N个解码器层clones(layer, N)
    # self.norm 定义规范化层 LayerNorm(layer.size)
# forward函数 (self, x, memory, source_mask, target_mask)
    # 数据以此经过各个子层  x = layer(x, memory, source_mask, target_mask)
    # 数据最后经过规范化层  return self.norm(x)
    # 返回处理好的数据

class Decoder(nn.Module):

    def __init__(self, layer, N):
        super(Decoder, self).__init__()

        # clone实例化解码器层
        self.layers = clones(layer, N)

        # 实例化规范化层
        self.norm = LayerNorm(layer.size)

    def forward(self, x, memory, source_mask, target_mask):

        # 让数据经过各个解码器层
        for layer in self.layers:
           x = layer(x, memory, source_mask, target_mask)

        return self.norm(x)


def dm02_test_Decoder():

    c = copy.deepcopy

    # 1-1 准备数据
    pe_result = torch.randn(2, 4, 512)

    # 1-2 实例化多头注意力机制对象
    source_mask = Variable(torch.zeros(8, 4, 4))
    target_mask = Variable(torch.zeros(8, 4, 4))
    self_attn = src_attn = MultiHeadedAttention(8, 512, 0.1)

    # 1-3 实例化PositionwiseFeedForward
    d_model, d_ff = 512, 1024
    ff = PositionwiseFeedForward(d_model, d_ff)

    # 实例化 一个 编码器层
    my_decoderlayer = DecoderLayer(512, c(self_attn), c(src_attn), c(ff), 0.1)
    print('my_decoderlayer--->', my_decoderlayer)

    # # 准备编码器部分的最后编码结果 也就是中间语义张量C
    memory = torch.randn(2, 4, 512)

    # 实例化解码器部分
    my_decoder = Decoder(my_decoderlayer, 6)
    print('my_decoder--->', my_decoder)

    # 让数据经过解码器部分
    decoder_result = my_decoder(pe_result, memory, source_mask, target_mask)
    print('decoder_result--->', decoder_result.shape, decoder_result)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值