当前位置:   article > 正文

pytorch 实现 Restormer 主要模块(多头通道自注意力机制和门控制结构)_mdta注意力机制

mdta注意力机制

        前面的博文读论文:Restormer: Efficient Transformer for High-Resolution Image Restoration 介绍了 Restormer 网络结构的网络技术特点,本文用 pytorch 实现其中的主要网络结构模块。

1. MDTA(Multi-Dconv Head Transposed Attention:多头注意力机制

  1. ## Multi-DConv Head Transposed Self-Attention (MDTA)
  2. class Attention(nn.Module):
  3. def __init__(self, dim, num_heads, bias):
  4. super(Attention, self).__init__()
  5. self.num_heads = num_heads # 注意力头的个数
  6. self.temperature = nn.Parameter(torch.ones(num_heads, 1, 1)) # 可学习系数
  7. # 1*1 升维
  8. self.qkv = nn.Conv2d(dim, dim*3, kernel_size=1, bias=bias)
  9. # 3*3 分组卷积
  10. self.qkv_dwconv = nn.Conv2d(dim*3, dim*3, kernel_size=3, stride=1, padding=1, groups=dim*3, bias=bias)
  11. # 1*1 卷积
  12. self.project_out = nn.Conv2d(dim, dim, kernel_size=1, bias=bias)
  13. def forward(self, x):
  14. b,c,h,w = x.shape # 输入的结构 batch 数,通道数和高宽
  15. qkv = self.qkv_dwconv(self.qkv(x))
  16. q,k,v = qkv.chunk(3, dim=1) # 第 1 个维度方向切分成 3 块
  17. # 改变 q, k, v 的结构为 b head c (h w),将每个二维 plane 展平
  18. q = rearrange(q, 'b (head c) h w -> b head c (h w)', head=self.num_heads)
  19. k = rearrange(k, 'b (head c) h w -> b head c (h w)', head=self.num_heads)
  20. v = rearrange(v, 'b (head c) h w -> b head c (h w)', head=self.num_heads)
  21. q = torch.nn.functional.normalize(q, dim=-1) # C 维度标准化,这里的 C 与通道维度略有不同
  22. k = torch.nn.functional.normalize(k, dim=-1)
  23. attn = (q @ k.transpose(-2, -1)) * self.temperature # @ 是矩阵乘
  24. attn = attn.softmax(dim=-1)
  25. out = (attn @ v) # 注意力图(严格来说不算图)
  26. # 将展平后的注意力图恢复
  27. out = rearrange(out, 'b head c (h w) -> b (head c) h w', head=self.num_heads, h=h, w=w)
  28. # 真正的注意力图
  29. out = self.project_out(out)
  30. return out

2. GDFN( Gated-Dconv Feed-Forward Network) 

  1. ## Gated-Dconv Feed-Forward Network (GDFN)
  2. class FeedForward(nn.Module):
  3. def __init__(self, dim, ffn_expansion_factor, bias):
  4. super(FeedForward, self).__init__()
  5. # 隐藏层特征维度等于输入维度乘以扩张因子
  6. hidden_features = int(dim*ffn_expansion_factor)
  7. # 1*1 升维
  8. self.project_in = nn.Conv2d(dim, hidden_features*2, kernel_size=1, bias=bias)
  9. # 3*3 分组卷积
  10. self.dwconv = nn.Conv2d(hidden_features*2, hidden_features*2, kernel_size=3, stride=1, padding=1, groups=hidden_features*2, bias=bias)
  11. # 1*1 降维
  12. self.project_out = nn.Conv2d(hidden_features, dim, kernel_size=1, bias=bias)
  13. def forward(self, x):
  14. x = self.project_in(x)
  15. x1, x2 = self.dwconv(x).chunk(2, dim=1) # 第 1 个维度方向切分成 2 块
  16. x = F.gelu(x1) * x2 # gelu 相当于 relu+dropout
  17. x = self.project_out(x)
  18. return x

3. TransformerBlock

  1. ## 就是标准的 Transformer 架构
  2. class TransformerBlock(nn.Module):
  3. def __init__(self, dim, num_heads, ffn_expansion_factor, bias, LayerNorm_type):
  4. super(TransformerBlock, self).__init__()
  5. self.norm1 = LayerNorm(dim, LayerNorm_type) # 层标准化
  6. self.attn = Attention(dim, num_heads, bias) # 自注意力
  7. self.norm2 = LayerNorm(dim, LayerNorm_type) # 层表转化
  8. self.ffn = FeedForward(dim, ffn_expansion_factor, bias) # FFN
  9. def forward(self, x):
  10. x = x + self.attn(self.norm1(x)) # 残差
  11. x = x + self.ffn(self.norm2(x)) # 残差
  12. return x

4. 测试样例

  1. model = Restormer()
  2. print(model) # 打印网络结构
  3. x = torch.randn((1, 3, 512, 512)) #随机生成输入图像
  4. x = model(x) # 送入网络
  5. print(x.shape) # 打印网络输入的图像结构

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Monodyee/article/detail/237504
推荐阅读
相关标签
  

闽ICP备14008679号