位置前馈网络 (FFN)

这是 Transformer 中使用的位置前馈网络的 PyTorch 实现。

FFN 由两个全连接层组成。隐藏层中的维度数_%5e_0_%5e_通常设置为标记嵌入维度_%5e_1_%5e_的四倍左右。因此,它有时也被称为扩张-压缩网络。

隐藏层有一个激活函数,通常设置为 ReLU (Rectified Linear Unit) 激活函数,_%5e_2_%5e_

在此基础上, FFN 函数可以写作:_%5e_3_%5e_其中_%5e_4_%5e__%5e_5_%5e__%5e_6_%5e__%5e_7_%5e_是可学习的参数。

有时还会使用 GELU (Gaussian Error Linear Unit) 激活函数来代替 ReLU 。_%5e_8_%5e_其中_%5e_9_%5e_

门控线性单元

这是一个通用实现,支持包括门控线性单元(GLU) 在内的不同变体。我们还对这些进行了实验:

38import torch
39from torch import nn as nn
40
41from labml_helpers.module import Module

FFN 模块

44class FeedForward(Module):
  • d_model 是标记嵌入中的特征数量
  • d_ff 是 FFN 隐藏层中的特征数量
  • dropout 是隐藏层的 Dropout 率
  • is_gated 指定了隐藏层是否为门控层
  • bias1 指定了第一个全连接层是否应该具有可学习的偏置
  • bias2 指定第二个全连接层是否应具有可学习的偏置
  • bias_gate 指定门控的全连接层是否应具有可学习的偏置
49    def __init__(self, d_model: int, d_ff: int,
50                 dropout: float = 0.1,
51                 activation=nn.ReLU(),
52                 is_gated: bool = False,
53                 bias1: bool = True,
54                 bias2: bool = True,
55                 bias_gate: bool = True):
65        super().__init__()

第一层由权重和偏差进行参数化

67        self.layer1 = nn.Linear(d_model, d_ff, bias=bias1)

第一层由权重和偏差进行参数化

69        self.layer2 = nn.Linear(d_ff, d_model, bias=bias2)

隐藏层 Dropout

71        self.dropout = nn.Dropout(dropout)

激活函数

73        self.activation = activation

是否存在门控

75        self.is_gated = is_gated
76        if is_gated:

如果存在门控,则通过线性层将输入值与门相乘,并由权重 和偏置进行参数化

79            self.linear_v = nn.Linear(d_model, d_ff, bias=bias_gate)
81    def forward(self, x: torch.Tensor):

83        g = self.activation(self.layer1(x))

如果进行门控,

85        if self.is_gated:
86            x = g * self.linear_v(x)

否则

88        else:
89            x = g

使用 Dropout

91        x = self.dropout(x)

根据是否进行门控,返回或者

94        return self.layer2(x)