今天给大家介绍一个超强的算法模型,Transformer
Transformer 模型是一种基于注意力机制的深度学习模型,广泛应用于自然语言处理(NLP)任务,如机器翻译、文本生成和语义理解。
它最初由 Vaswani 等人在2017年的论文《Attention is All You Need》中提出。它突破了传统序列模型(如RNN和LSTM)的局限,能够并行处理序列数据,从而大大提高了训练效率和模型性能。
文末领取本文的 pdf 版本
Transformer 模型的基本结构
Transformer 模型由两个主要部分组成:编码器(Encoder)和 解码器(Decoder)。
编码器将输入序列编码为一个固定长度的上下文向量,解码器则根据这个上下文向量生成输出序列。
编码器和解码器各由多个层(Layer)堆叠而成。
编码器(Encoder)
编码器的主要作用是将输入序列转换为一组上下文向量,供解码器使用。每个子层之后都会使用残差连接(Residual Connection)和层归一化(Layer Normalization),这有助于避免梯度消失问题并加快训练收敛速度。
importtorch
importtorch.nnasnn
importtorch.optimasoptim
importmath
classPositionalEncoding(nn.Module):
def__init__(self,d_model,max_len=5000):
super(PositionalEncoding,self).__init__()
pe=torch.zeros(max_len,d_model)
position=torch.arange(0,max_len,dtype=torch.float).unsqueeze(1)
div_term=torch.exp(torch.arange(0,d_model,2).float()*(-math.log(10000.0)/d_model))
pe[:,0::2]=torch.sin(position*div_term)
pe[:,1::2]=torch.cos(position*div_term)
pe=pe.unsqueeze(0).transpose(0,1)
self.register_buffer('pe',pe)
defforward(self,x):
x=x+self.pe[:x.size(0),:]
returnx
classTransformerModel(nn.Module):
def__init__(self,input_dim,output_dim,d_model=512,nhead=8,num_encoder_layers=6,dim_feedforward=2048,dropout=0.1):
super(TransformerModel,self).__init__()
self.model_type='Transformer'
self.embedding=nn.Embedding(input_dim,d_model)
self.pos_encoder=PositionalEncoding(d_model)
encoder_layers=nn.TransformerEncoderLayer(d_model,nhead,dim_feedforward,dropout)
self.transformer_encoder=nn.TransformerEncoder(encoder_layers,num_encoder_layers)
self.d_model=d_model
self.decoder=nn.Linear(d_model,output_dim)
self.init_weights()
definit_weights(self):
initrange=0.1
self.embedding.weight.data.uniform_(-initrange,initrange)
self.decoder.bias.data.zero_()
self.decoder.weight.data.uniform_(-initrange,initrange)
defforward(self,src,src_mask):
src=self.embedding(src)*math.sqrt(self.d_model)
src=self.pos_encoder(src)
output=self.transformer_encoder(src,src_mask)
output=self.decoder(output)
returnoutput
defgenerate_square_subsequent_mask(sz):
mask=(torch.triu(torch.ones(sz,sz))==1).transpose(0,1)
mask=mask.float().masked_fill(mask==0,float('-inf')).masked_fill(mask==1,float(0.0))
returnmask
#Exampleusage:
input_dim=1000#Vocabularysize
output_dim=1000#Outputsize
seq_length=10#Lengthofthesequence
#Createthemodel
model=TransformerModel(input_dim=input_dim,output_dim=output_dim)
#Exampledata
src=torch.randint(0,input_dim,(seq_length,32))#(sequence_length,batch_size)
src_mask=generate_square_subsequent_mask(seq_length)
#Forwardpass
output=model(src,src_mask)
print(output.shape)#Expectedoutput:[sequence_length,batch_size,output_dim]
#Defineasimplelossandoptimizerfortraining
criterion=nn.CrossEntropyLoss()
optimizer=optim.Adam(model.parameters(),lr=0.001)
#Exampletrainingloop
forepochinrange(10):#Numberofepochs
optimizer.zero_grad()
output=model(src,src_mask)
loss=criterion(output.view(-1,output_dim),src.view(-1))
loss.backward()
optimizer.step()
print(f"Epoch{epoch+1},Loss:{loss.item()}")