🚩🚩🚩Transformer实战-系列教程总目录
有任何问题欢迎在下面留言
本篇文章的代码运行界面均在Pycharm中进行
本篇文章配套的代码资源已经上传
点我下载源码
DETR 算法解读
DETR 源码解读1(项目配置/CocoDetection类/ConvertCocoPolysToMask类)
DETR 源码解读2(DETR类)
DETR 源码解读3(位置编码:Joiner类/PositionEmbeddingSine类)
DETR 源码解读4(BackboneBase类/Backbone类)
DETR 源码解读5(Transformer类)
DETR 源码解读6(编码器:TransformerEncoder类/TransformerEncoderLayer类)
DETR 源码解读7(解码器:TransformerDecoder类/TransformerDecoderLayer类)
DETR 源码解读8(训练函数/损失函数)
9、Transformer类
位置:models/transformer.py/Transformer类
9.1 _reset_parameters()函数
def _reset_parameters(self):
for p in self.parameters():
if p.dim() > 1:
nn.init.xavier_uniform_(p)
这个辅助函数,遍历当前被调用的模型中所有的参数,当这个参数的维度大于1时,会对当前参数使用Xavier均匀初始化方法进行初始化
9.2 构造函数
class Transformer(nn.Module):
def __init__(self, d_model=512, nhead=8, num_encoder_layers=6,
num_decoder_layers=6, dim_feedforward=2048, dropout=0.1,
activation="relu", normalize_before=False,
return_intermediate_dec=False):
super().__init__()
encoder_layer = TransformerEncoderLayer(d_model, nhead, dim_feedforward, dropout, activation, normalize_before)
encoder_norm = nn.LayerNorm(d_model) if normalize_before else None
self.encoder = TransformerEncoder(encoder_layer, num_encoder_layers, encoder_norm)
decoder_layer = TransformerDecoderLayer(d_model, nhead, dim_feedforward, dropout, activation, normalize_before)
decoder_norm = nn.LayerNorm(d_model)
self.decoder = TransformerDecoder(decoder_layer, num_decoder_layers, decoder_norm, return_intermediate=return_intermediate_dec)
self._reset_parameters()
self.d_model = d_model
self.nhead = nhead
- 定义类,继承PyTorch的nn.Module
- 构造函数,传入模型维度、多头注意力的头数、编码器层数、解码器层数、前馈网络的维度、dropout比率、激活函数类型、是否在层之前进行归一化处理、是否返回解码器的中间层输出
- 初始化
- encoder_layer ,使用TransformerEncoderLayer类创建一个编码器层
- encoder_norm ,根据normalize_before的值决定是否创建一个层归一化层
- encoder ,使用TransformerEncoder类调用编码器层、编码器层数、归一化等创建编码器
- decoder_layer ,使用TransformerDecoderLayer类创建一个解码器层
- decoder_norm ,创建一个层归一化层
- decoder ,使用TransformerDecoder类调用解码器层、解码器层数、归一化等创建解码器
- d_model,模型维度
- nhead,多头注意力的头数
9.3 前向传播
def forward(self, src, mask, query_embed, pos_embed):
bs, c, h, w = src.shape
src = src.flatten(2).permute(2, 0, 1)
pos_embed = pos_embed.flatten(2).permute(2, 0, 1)
query_embed = query_embed.unsqueeze(1).repeat(1, bs, 1)
mask = mask.flatten(1)
tgt = torch.zeros_like(query_embed)
memory = self.encoder(src, src_key_padding_mask=mask, pos=pos_embed)
hs = self.decoder(tgt, memory, memory_key_padding_mask=mask,
pos=pos_embed, query_pos=query_embed)
return hs.transpose(1, 2), memory.permute(1, 2, 0).view(bs, c, h, w)
- 前向传播函数,传入数据源、掩码、Q向量、位置编码等
- bs, c, h, w,[2, 256, 24, 24],获取数据源的维度,batch、通道数、长、宽,每次传入的数据的长宽可能不同
- src,torch.Size([576, 2, 256]),维度从[batch_size, channels, height, width]转换为[height*width, batch_size, channels],576表示序列长度,256表示每个序列有256维向量
- pos_embed ,torch.Size([576, 2, 256]),位置编码进行同样操作
- query_embed ,torch.Size([100, 2, 256]),将Q向量扩展并重复,以匹配batch_size
- mask ,torch.Size([2, 576]),展平减少一个维度
- tgt ,torch.Size([100, 2, 256]),初始化目标序列tgt为与Q向量维度相同但全为0的Tensor,这在解码器的自回归预测中用作初始输入
- memory ,torch.Size([576, 2, 256]),调用编码器传入数据源、掩码、位置编码得到输出
- hs ,torch.Size([6, 100, 2, 256]),调用解码器传入初始化目标序列、编码器输出、掩码、位置编码、Q向量等得到输出
- return ,hs:torch.Size([6, 2, 100, 256]),memory:torch.Size([2, 256, 24, 24]),将编码器输出和解码器的输出的维度进行调整后返回
DETR 算法解读
DETR 源码解读1(项目配置/CocoDetection类/ConvertCocoPolysToMask类)
DETR 源码解读2(DETR类)
DETR 源码解读3(位置编码:Joiner类/PositionEmbeddingSine类)
DETR 源码解读4(BackboneBase类/Backbone类)
DETR 源码解读5(Transformer类)
DETR 源码解读6(编码器:TransformerEncoder类/TransformerEncoderLayer类)
DETR 源码解读7(解码器:TransformerDecoder类/TransformerDecoderLayer类)
DETR 源码解读8(训练函数/损失函数)