【深度学习】backbone网络结构ResNet、Inception、DenseNet简单概述

目录

前言

各自的亮点:

一、ResNet

1. Resnet要解决的是什么问题

2. Residual Block的设计

3. ResNet 网络结构

二、Inception

1. Inception系列想要解决的问题

2. Inception V1-2014年

3. Inception V2、Inception-V3 -2015年

4. 总结

三、DenseNet

3.0 DenseNet优点:

3.1 DenseNet与Resnet的区别:

3.2 DenseNet网络结构图


前言

主要讲述ResNet(更深)、Inception(更宽)、DenseNe(更稠密)t这三个backbone网络结构

各自的亮点:

1)ResNet:通过残差模块解决“网络退化”的问题,使得网络能够更深。

2)Inception:通过使用多个尺寸的卷积核,能够获取多尺度大小的感受野信息,使得网络更宽

3)DenseNet:使用更稠密的网络连接方式,达到Resnet的效果,也使得网络更深,且参数量比Resnet少一些(卷积核数量少)。

一、ResNet

1. Resnet要解决的是什么问题

  • 深度神经网络的“退化”问题。

        我们知道,对浅层网络逐渐叠加layers,模型在训练集和测试集上的性能会变好,因为模型复杂度更高了,表达能力更强了,可以对潜在的映射关系拟合得更好。而“退化”指的是,给网络叠加更多的层后,性能却快速下降的情况。

2. Residual Block的设计

        𝐹(𝑥)+𝑥构成的block称之为Residual Block,即残差块,如下图所示:

        一个残差块有2条路径𝐹(𝑥)和𝑥,𝐹(𝑥)路径拟合残差,不妨称之为残差路径,𝑥路径为identity mapping恒等映射,称之为”shortcut”。图中的⊕为element-wise addition,要求参与运算的𝐹(𝑥)和𝑥的尺寸要相同。 

1)残差路径𝐹(𝑥)的两种形式

        一种有bottleneck结构,即下图右中的1×1 卷积层,用于先降维再升维,主要出于降低计算复杂度的现实考虑,称之为“bottleneck block”,另一种没有bottleneck结构,如下图左所示,称之为“basic block”。basic block由2个3×3卷积层构成,bottleneck block由1×1

两种残差路径:右边为了减少计算量,先使用1*1Conv降低维度,后面再升维回去

2)shortcut路径的两种形式

两种shortcut:一种直接传递,另一种经过1*1Conv升维或采样

3. ResNet 网络结构

         ResNet为多个Residual Block的串联,下面直观看一下ResNet-34与34-layer plain net和VGG的对比,以及堆叠不同数量Residual Block得到的不同ResNet。

Resnet与VGG网络的对比
不同block数量的Resnet

参考链接:https://www.cnblogs.com/shine-lee/p/12363488.html

二、Inception

1. Inception系列想要解决的问题

        Google家的Inception系列模型提出的初衷主要为了解决CNN分类模型的两个问题:

  1. 其一是如何使得网络深度增加的同时能使得模型的分类性能随着增加,而非像简单的VGG网络那样达到一定深度后就陷入了性能饱和的困境(Resnet针对的也是此一问题);
  2. 其二则是如何在保证分类网络分类准确率提升或保持不降的同时使得模型的计算开销与内存开销充分地降低。

2. Inception V1-2014年

        Inception V1模块提出可以使网络变宽,在保证模型质量的前提下,减少参数个数,提取高维特征。

        Inception结构,首先通过1x1卷积来降低通道数把信息聚集一下,再进行不同尺度的特征提取以及池化,得到多个尺度的信息,最后将特征进行叠加输出(官方说法:可以将稀疏矩阵聚类为较为密集的子矩阵来提高计算性能)。

不同尺寸的卷积提取多尺度信息

主要过程:

  1. 相应的在3x3卷积和5x5卷积前面、3x3池化后面添加1x1卷积,将信息聚集且可以有效减少参数量(称为瓶颈层);
  2. 下一层block就包含1x1卷积,3x3卷积,5x5卷积,3x3池化(使用这样的尺寸不是必需的,可以根据需要进行调整)。这样,网络中每一层都能学习到“稀疏”(3x3、5x5)或“不稀疏”(1x1)的特征,既增加了网络的宽度,也增加了网络对尺度的适应性
  3. 通过按深度叠加(deep concat)在每个block后合成特征,获得非线性属性。

3. Inception V2、Inception-V3 -2015年

  • 分解卷积核尺寸,包括:改用多个小尺寸卷积核替换大尺寸卷积核(5*5)
  • 加入BN层,尤其是在额外的辅助分类器上添加BN层
  • 使用label smoothing对网络loss进行规则化处理
把V1里的5*5 filter换成了两个3*3(感受野不变,快了2.78倍)

 

4. 总结

        inception是通过增加网络的宽度来提高网络性能,在每个inception模块中,使用了不同大小的卷积核,可以理解成不同的感受野,然后将其concentrate起来,丰富了每层的信息。之后,使用了BN算法(BN使用在conv之后,relu之前),来加速网络的收敛速度。在V3版本中,还使用了卷积因子分解的思想,将大卷积核分解成小卷积,节省了参数,降低了模型大小。在V4版本中,使用了更加统一的inception模块,并结合了resnet的残差思想,能将网络做得更深。


参考链接:https://blog.csdn.net/weixin_45422462/article/details/108416139

三、DenseNet

        DenseNet是与Resnet不同的另外一种较深的网络,它的精髓是Dense Block的结构不同。

3.0 DenseNet优点:

  • (1) 相比ResNet拥有更少的参数量(由于特征复用,每层卷积核的个数想对可以减少一些).
  • (2) 支路更多,加强了特征的重复使用和传递(某层的特征会通过支路传递给该block中后面的每一层).
  • (3) 网络更易于训练,并具有一定的正则效果.
  • (4) 缓解了梯度消失(gradient vanishing)和模型退化(model degradation)的问题.

3.1 DenseNet与Resnet的区别:

1. Resnet block公式:

        第一个公式是ResNet的。这里的l表示层,xl表示l层的输出,Hl表示一个非线性变换。所以对于ResNet而言,l层的输出是l-1层的输出加上对l-1层输出的非线性变换。

2. Dense block公式:

        第二个公式是DenseNet的。[x0,x1,…,xl-1]表示将0到l-1层的输出feature map做concatenation。concatenation是做通道的合并,就像Inception那样。而前面resnet是做值的相加,通道数是不变的。Hl包括BN,ReLU和3*3的卷积。

主要区别:Dense block中第i层的输入不仅与i-1层的输出相关,还有所有之前层的输出有关。

1.Resnet block结构图

resnet block:一个block块中只有一条连接支路

2. Dense block的结构图

Dense block中第i层输入:前面的 i-1 层都会有一个分支传递过来,一个block共有
i-1个支路线

3.2 DenseNet网络结构图

整个DenseNet由3个Dense Block组成,block中间有下采样等操作

 

不同大小的DenseNet网络结构组成
  • 5
    点赞
  • 38
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
可以使用ResNet的最后一个卷积层的输出作为输入,然后添加Inception多尺度模块,将不同尺度的卷积核并行应用到输入特征上,最后将不同尺度的输出特征拼接在一起。具体步骤如下: 1. 使用ResNet骨干网络提取图像特征,得到最后一个卷积层的输出。 2. 定义Inception多尺度模块,包括不同尺度的卷积核和池化核,并行应用到输入特征上,得到不同尺度的输出特征。 3. 将不同尺度的输出特征拼接在一起,得到最终的特征表示。 4. 将最终的特征表示输入到全连接层进行分类或者回归等任务。 以下是代码示例,假设ResNet的最后一个卷积层输出为`x`,Inception多尺度模块包括3个分支: ```python import torch.nn as nn class InceptionModule(nn.Module): def __init__(self, in_channels, out_channels): super(InceptionModule, self).__init__() # 1x1 convolution branch self.branch1x1 = nn.Conv2d(in_channels, out_channels, kernel_size=1, stride=1) # 3x3 convolution branch self.branch3x3 = nn.Sequential( nn.Conv2d(in_channels, out_channels, kernel_size=1, stride=1), nn.Conv2d(out_channels, out_channels, kernel_size=3, stride=1, padding=1) ) # 5x5 convolution branch self.branch5x5 = nn.Sequential( nn.Conv2d(in_channels, out_channels, kernel_size=1, stride=1), nn.Conv2d(out_channels, out_channels, kernel_size=5, stride=1, padding=2) ) # max pooling branch self.branch_pool = nn.Sequential( nn.MaxPool2d(kernel_size=3, stride=1, padding=1), nn.Conv2d(in_channels, out_channels, kernel_size=1, stride=1) ) def forward(self, x): out1x1 = self.branch1x1(x) out3x3 = self.branch3x3(x) out5x5 = self.branch5x5(x) out_pool = self.branch_pool(x) out = torch.cat([out1x1, out3x3, out5x5, out_pool], dim=1) return out class ResNetInception(nn.Module): def __init__(self, num_classes): super(ResNetInception, self).__init__() self.resnet = models.resnet50(pretrained=True) self.inception1 = InceptionModule(2048, 512) self.inception2 = InceptionModule(2048 + 4 * 512, 1024) self.inception3 = InceptionModule(2048 + 4 * 1024, 2048) self.fc = nn.Linear(2048, num_classes) def forward(self, x): # ResNet backbone x = self.resnet.conv1(x) x = self.resnet.bn1(x) x = self.resnet.relu(x) x = self.resnet.maxpool(x) x = self.resnet.layer1(x) x = self.resnet.layer2(x) x = self.resnet.layer3(x) x = self.resnet.layer4(x) # Inception module 1 out1 = self.inception1(x) # Inception module 2 out2 = torch.cat([x, out1], dim=1) out2 = self.inception2(out2) # Inception module 3 out3 = torch.cat([x, out1, out2], dim=1) out3 = self.inception3(out3) # Global average pooling and fully connected layer out = F.adaptive_avg_pool2d(out3, output_size=1) out = out.view(out.size(0), -1) out = self.fc(out) return out ``` 在上面的代码中,ResNet50骨干网络的输出为`x`,然后分别经过3个Inception多尺度模块,每个模块的输出作为下一个模块的输入。最终的特征表示为第3个模块的输出,经过全局平均池化后输入到全连接层进行分类。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值