系列文章目录
理论基础
- Transformer结构主要分为两大部分,一是Encoder层结构,另一个则是Decoder层结构,Encoder 的输入由 Input Embedding 和 Positional Embedding 求和输入Multi-Head-Attention,然后经一个ADD&Norm,再通过Feed Forward进行输出。
- FeedForward 是一个神经网络模块,由全连接层FC与激活ReLu组成,通常用于处理序列数据或者在深度学习模型的前馈过程中。
- 前馈全连接层是在Transformer中前馈全连接层就是具有两层线性层的全连接网络。前馈全连接层的作用:考虑注意力机制可能对复杂过程的拟合程度不够,通过增加两层网络来增强模型的能力。
李沐《动手学习深度学习》中对于FeedForward的实现:
* __init__ 方法: 初始化函数,定义了神经网络的结构。它接受以下参数:
* ffn_num_input:输入特征的维度大小。
* ffn_num_hiddens:隐藏层的维度大小。
* ffn_num_outputs:输出特征的维度大小。
* forward 方法: 前向传播函数,定义了数据在神经网络中的流动。它接受输入 X,并经过线性变换、ReLU 激活函数和另一个线性变换后返回结果。
一、导入相关库
import torch
from torch import nn as nn
from labml_helpers.module import Module
二、实现FeedForward模块
- __init__ 方法: 初始化函数,定义了神经网络的结构。它接受以下参数:
- d_model: token 嵌入中的特征数量
- d_ff:隐藏层的特征维度大小。
- dropout:隐藏层的 dropout 概率。
- activation:激活函数,默认为 ReLU。
- is_gated:是否使用门控机制,默认为 False。
- bias1:是否为第一个全连接层使用可学习的偏置。
- bias2:是否为第二个全连接层使用可学习的偏置。
- bias_gate:是否为门控线性层使用可学习的偏置。
- forward 方法: 前向传播函数,定义了数据在神经网络中的流动。
- 将输入 x 通过第一个全连接层,并应用激活函数 f f f。
- 如果使用门控机制,则将激活后的结果与输入相乘,得到门控后的结果。
- 对结果应用 dropout。
- 将结果通过第二个全连接层,并返回输出。
class FeedForward(Module):
"""
## FFN module
"""
def __init__(self, d_model: int, d_ff: int,
dropout: float = 0.1,
activation=nn.ReLU(),
is_gated: bool = False,
bias1: bool = True,
bias2: bool = True,
bias_gate: bool = True):
super().__init__()
self.layer1 = nn.Linear(d_model, d_ff, bias=bias1)
self.layer2 = nn.Linear(d_ff, d_model, bias=bias2)
self.dropout = nn.Dropout(dropout)
self.activation = activation
self.is_gated = is_gated
if is_gated:
self.linear_v = nn.Linear(d_model, d_ff, bias=bias_gate)
def forward(self, x: torch.Tensor):
g = self.activation(self.layer1(x))
if self.is_gated:
x = g * self.linear_v(x)
else:
x = g
x = self.dropout(x)
return self.layer2(x)
参考:
对Transformer中FeedForward层的理解
https://github.com/labmlai/annotated_deep_learning_paper_implementations/blob/master/labml_nn/transformers/feed_forward.py
Transformer前馈全连接层和规范化层(3)