【pytorch】ResNet中的BasicBlock与bottleneck

https://zhuanlan.zhihu.com/p/349717627

ResNet与残差块

深度卷积网络的瓶颈:
理论上,增加网络层数后,网络可以进行更加复杂的特征模式的提取,所以当模型更深时可以取得更好的结果。但VGG、GoogLeNet等网络单纯增加层数遇到了一些瓶颈:简单增加卷积层,训练误差不但没有降低,反而越来越高。在CIFAR-10、ImageNet等数据集上,单纯叠加3×3卷积,何恺明等[1]人发现,训练和测试误差都变大了。这主要是因为深层网络存在着梯度消失或者爆炸的问题,模型层数越多,越难训练。

残差块:

但是神经网络的ReLU激活函数恰恰不能保证“什么都不学习”。残差网络的初衷就是尽量让模型结构有“什么都不做”的能力,这样就不会因为网络层数的叠加导致梯度消失或爆炸。
在这里插入图片描述现有H(x) = F(x)+x, 只要F(x)=0,那么H(x)=x,H(x)就是恒等映射,也就是有了“什么都不做”的能力。ResNet基于这一思想提出了一种残差网络的结构,其中输入x可以传递到输出,传递的过程被称为ShortCut
同时,下图里有两个权重层,即F(x)部分。假如“什么都不学习”是最优的,或者说H(x)=x是最优的,那么理论上来说,F(x)学习到的目标值为0即可;如果H(x)=x不是最优,那么基于神经网络强大的学习能力,F(x)可以尽可能去拟合我们期望的值。
在这里插入图片描述

BasicBlock

ResNet中使用的一种网络结构,在resnet18和resnet34中使用了BasicBlock:
输入输出通道数均为64,残差基础块中两个3×3卷积层参数量是:
在这里插入图片描述

在这里插入图片描述

BasicBlock类中计算了残差,该类继承了nn.Module。

class BasicBlock(nn.Module):
    expansion = 1

    def __init__(self, inplanes, planes, stride=1, downsample=None):
        super(BasicBlock, self).__init__()
        self.conv1 = conv3x3(inplanes, planes, stride)
        self.bn1 = nn.BatchNorm2d(planes)
        self.relu = nn.ReLU(inplace=True)
        self.conv2 = conv3x3(planes, planes)
        self.bn2 = nn.BatchNorm2d(planes)
        self.downsample = downsample
        self.stride = stride

    def forward(self, x):
        identity = x

        out = self.conv1(x)
        out = self.bn1(out)
        out = self.relu(out)

        out = self.conv2(out)
        out = self.bn2(out)

        if self.downsample is not None:
            identity = self.downsample(x)

        out += identity
        out = self.relu(out)

        return out

bottleNeck

ResNet-34核心部分均使用3×3卷积层,总层数相对没那么多,对于更深的网络,作者们提出了另一种残差基础块。(在resnet50、resnet101、resnet152使用了Bottlenect构造网络.)

Bottleneck Block中使用了1×1卷积层。如输入通道数为256,1×1卷积层会将通道数先降为64,经过3×3卷积层后,再将通道数升为256。1×1卷积层的优势是在更深的网络中,用较小的参数量处理通道数很大的输入。

Bottleneck Block中,输入输出通道数均为256,残差基础块中的参数量是:
在这里插入图片描述
BasicBlock比较,使用1×1卷积层,参数量减少了。当然,使用这样的设计,也是因为更深的网络对显存和算力都有更高的要求,在算力有限的情况下,深层网络中的残差基础块应该减少算力消耗。

在这里插入图片描述
代码:

class Bottleneck(nn.Module):
    expansion = 4

    def __init__(self, inplanes, planes, stride=1, downsample=None):
        super(Bottleneck, self).__init__()
        self.conv1 = conv1x1(inplanes, planes)
        self.bn1 = nn.BatchNorm2d(planes)
        self.conv2 = conv3x3(planes, planes, stride)
        self.bn2 = nn.BatchNorm2d(planes)
        self.conv3 = conv1x1(planes, planes * self.expansion)
        self.bn3 = nn.BatchNorm2d(planes * self.expansion)
        self.relu = nn.ReLU(inplace=True)
        self.downsample = downsample
        self.stride = stride

    def forward(self, x):
        identity = x

        out = self.conv1(x)
        out = self.bn1(out)
        out = self.relu(out)

        out = self.conv2(out)
        out = self.bn2(out)
        out = self.relu(out)

        out = self.conv3(out)
        out = self.bn3(out)

        if self.downsample is not None:
            identity = self.downsample(x)

        out += identity
        out = self.relu(out)

        return out

### 回答1: bottleneckbasicblock是深度学习常用的两种卷积神经网络结构。 Bottleneck结构是一种优化卷积神经网络的方法,它通过在卷积层前加入1x1的卷积层来减少计算量和参数数量。Bottleneck结构通常用于ResNet等深层网络,可以有效地提高模型的性能和训练速度。 Basicblock结构是一种基本的卷积神经网络结构,它由一个卷积层和一个激活函数组成。Basicblock结构通常用于较浅的网络,如VGG等。虽然Basicblock结构比Bottleneck结构简单,但在一些任务也可以取得不错的效果。 总的来说,Bottleneck结构适用于深层网络,可以提高模型的性能和训练速度;而Basicblock结构适用于较浅的网络,可以在一些任务取得不错的效果。 ### 回答2: 在深度学习,常见的构建模块有bottleneckbasicblock两种,它们都是卷积神经网络(CNN)的基础构建单元,用于实现卷积、BN、激活等操作。本文将对比这两种构建模块。 首先,我们看看basicblockbasicblock是最基本的卷积区域,由两个卷积层和一个ReLU激活函数组成。这些卷积操作可以有效地提取特征。basicblock易于实现和训练,除此之外,basicblock也非常轻便,这意味着它在不同的层级可以非常方便地重复使用,这在堆叠层级较深的网络时非常有用。但basicblock存在的问题是,由于它的卷积层只使用了3x3的卷积核,因此可能会丢失一些细节信息。 与之相对的是bottleneckbottleneck的核心思想是将卷积核大小降到较小的值,通常为1x1,这样既可以加速计算,又可以保留更多的空间信息。bottleneck由三个卷积层组成,下面是1x1卷积层,间是3x3卷积层,上面还是1x1卷积层。最后,我们将三个操作串起来,就可以得到一个完整的bottleneck。这种结构可以有效地减少参数数量,并使得计算速度更快,此外bottleneck还可以减少维度,从而更好地控制模型的大小。 总之,basicblockbottleneck都是卷积神经网络常见的构建块。basicblock是一个轻量级的卷积区域,易于实现和训练,但对更好的特征提取存在一定的限制。bottleneck通过降低卷积核的大小来保留更多的细节信息,从而更加高效,但需要更多的计算资源。 ### 回答3: bottleneckbasicblock都是在神经网络常用的基本模块,主要用于构建深层网络模型。它们的作用类似于模型的砖块,可以用不同的方式组合来构建一个完整的网络。 首先,可以从结构上来比较它们。basicblock通常由两次卷积操作和一个恒等映射组成,其恒等映射是为了保持输入输出维度一致。而bottleneck则包含一个1x1卷积、一个3x3卷积和另一个1x1卷积,同样也有一个恒等映射。可以看到,bottleneck相对于basicblock多了一次卷积,但是这个卷积的通道数较少,因此可以减少参数数量,同时增加网络深度。 其次,可以从复杂度和效率上来比较。由于bottleneck有一个较小的卷积层,因此它的计算复杂度较低,但同时又具有较高的表达能力,能够捕捉到更深层次的特征。因此,对于深层网络的构建来说,bottleneck更适合用于增加层数。而basicblock则相对简单,计算复杂度低,但对于比较浅的网络来说,由于没有较深的层次,它的表达能力并不低。 最后,可以从应用场景上来比较。基于以上分析,bottleneck可以用于构建更深的网络来应对复杂任务,如图像分类、目标检测等。而basicblock适合构建较浅的网络来应对一些相对简单的任务,如场景分类、特征提取等。 因此,可以看到,bottleneckbasicblock都有自己的特点和适用场景,具体应该根据实际任务需求来选择使用。对于复杂任务,可以使用bottleneck来增加网络深度,而对于简单任务,则可以使用basicblock来减少计算复杂度,并保证网络准确性。
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值