Residual, BottleNeck, Inverted Residual, MBConv的解释和Pytorch实现

上篇ConvNext的文章有小伙伴问BottleNeck,Inverted Residual的区别,所以找了这篇文章,详细的解释一些用到的卷积块,当作趁热打铁吧

在介绍上面的这些概念之间,我们先创建一个通用的 conv-norm-act 层,这也是最基本的卷积块。

  1. fromfunctoolsimportpartial
  2. fromtorchimportnn
  3. classConvNormAct(nn.Sequential):
  4. def__init__(
  5. self,
  6. in_features: int,
  7. out_features: int,
  8. kernel_size: int,
  9. norm: nn.Module = nn.BatchNorm2d,
  10. act: nn.Module = nn.ReLU,
  11. **kwargs
  12. ):
  13. super().__init__(
  14. nn.Conv2d(
  15. in_features,
  16. out_features,
  17. kernel_size=kernel_size,
  18. padding=kernel_size//2,
  19. ),
  20. norm(out_features),
  21. act(),
  22. )
  23. Conv1X1BnReLU = partial(ConvNormAct, kernel_size=1)
  24. Conv3X3BnReLU = partial(ConvNormAct, kernel_size=3)
  25. importtorch
  26. x = torch.randn((1, 32, 56, 56))
  27. Conv1X1BnReLU(32, 64)(x).shape
  28. #torch.Size([1, 64, 56, 56])

残差连接

ResNet 中提出并使用了残差连接, 这个想法是将层的输入与层的输出相加,输出 = 层(输入)+ 输入。下图可以帮助您将其可视化。但是,它只使用了一个 + 运算符。残差操作提高了梯度在乘法器层上传播的能力,允许有效地训练超过一百层的网络。

在PyTorch中,我们可以轻松地创建一个ResidualAdd层

  1. fromtorchimportnn
  2. fromtorchimportTensor
  3. classResidualAdd(nn.Module):
  4. def__init__(self, block: nn.Module):
  5. super().__init__()
  6. self.block = block
  7. defforward(self, x: Tensor) ->Tensor:
  8. res = x
  9. x = self.block(x)
  10. x += res
  11. returnx
  12. ResidualAdd(
  13. nn.Conv2d(32, 32, kernel_size=1)
  14. )(x).shape

捷径 Shortcut

有时候残差没有相同的输出维度,所以无法将它们相加。所以就需要使用conv(带+的黑色箭头)来投影输入,以匹配输出的特性

完整文章

https://avoid.overfit.cn/post/af49b27f50bb416ca829b4987e902874

posted @   deephub  阅读(113)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)
点击右上角即可分享
微信分享提示