本次讨论的主要内容是从纯技术角度来探讨Transformer模型的性质和特点,技术角度即指不做延伸的解释和猜想,只从定义和实验出发来分析。
由多层self-attention层叠加而成的模型,可以搭配全连接层,卷积层。attention机制也可以从多种实现中挑选任意一种。
Transformer远不止一个模型,更提出了相应的训练框架,优化方法。
Transformer主要有两个优势,一是速度快,并行度高,二是可以轻易访问相距很远的节点,解决了CNN和RNN常提到的local,non-local问题。可反观Transformer的设计,其中不乏很多“多余”之举。下面通过几个小例子来看看这些设计会否真的“多余”。
import torch
import torch.nn as nn
import tqdm
import numpy as np
BATCH_SIZE = 16
D_MODEL = 256
N_HEAD = 4
N_LAYER = 6
IN_LEN = 10
IN_DIM = 50
class Trans(nn.Module):
def __init__(self):
super(Trans, self).__init__()
self.trans = nn.TransformerEncoder(nn.TransformerEncoderLayer(D_MODEL, N_HEAD), N_LAYER)
self.in_fc = nn.Linear(IN_DIM*2, D_MODEL)
self.out_fc = nn.Linear(D_MODEL, IN_DIM)
def forward(self, x):
h = self.in_fc(x)
h = self.trans(h)
y = self.out_fc(h)
return y
def run(model, test=False):
model.train()
losses = []
lr = 1e-3
optimizer = torch.optim.Adam(model.parameters(), lr=lr)
with tqdm.trange(1000) as tq:
for i,_ in enumerate(tq):
a = torch.randn((BATCH_SIZE, IN_LEN, IN_DIM)).cuda()
b = torch.randn((BATCH_SIZE, IN_LEN, IN_DIM)).cuda()
tar = (a+1)**2 + b
y = model(torch.cat([a,b], -1))
loss = (0.5*(y-tar)**2).mean()
model.zero_grad()
if not test:
loss.backward()
optimizer.step()
tq.set_postfix({'loss':loss.item()})
losses.append(loss.item())
if test:
print('AVG Loss', np.mean(losses))
if __name__ == '__main__':
model = Trans()
model.cuda()
run(model)
run(model, True)
Setting | MSE |
---|---|
lr=1e-3, no warm-up | 3.37 |
lr=1e-4, no warm-up | 0.56 |
lr=1e-5, no warm-up | 2.31 |
lr=1e-3, 1% warm-up | 0.10 |
Setting | MSE |
---|---|
default | 0.097 |
xavier_uniform | 0.191 |
xavier_normal | 0.189 |
normal 0.02 | 0.66 |
normal 0.002 | 2.95 |
normal 0.1 | 3.50 |
uniform +-0.05 | 3.50 |
uniform +-0.01 | 0.424 |
uniform +-0.001 | 3.44 |
kaiming_uniform | 3.50 |
kaiming_normal | 3.50 |
Setting | MSE |
---|---|
kaiming_normal 2 layer | 0.524 |
kaiming_uniform 2 layer | 0.531 |
xavier_uniform 2 layer | 0.124 |
default 2 layer | 0.092 |
uniform +-0.01 2 layer | 0.117 |
Setting | MSE |
---|---|
lr=1e-3, no warm-up 2 layer | 0.086 |
lr=1e-4, no warm-up 2 layer | 0.614 |
Setting | MSE |
---|---|
lr=1e-3, no warm-up batch_size 64 | 0.037 |
由于Transformer是一个对调参很敏感的模型,在对其改造时,通常需要一些简单的实验来验证正确性,但切不能放大在简单实验中得到的结论,很多规律都是随任务场景,数据集规模发生改变的。
- Multi-Head Attention 怎么写
- Layer Norm 怎么加
- Attention Mask
- FFN 是什么