【pytorch】ResNet中的BasicBlock与bottleneck

本文介绍了ResNet网络及其残差块的设计思想,旨在解决深度神经网络中梯度消失或爆炸的问题。通过引入短Cut机制和1×1卷积层,使得网络在增加深度的同时保持训练稳定性。BasicBlock和BottleneckBlock是ResNet中的两种关键结构,后者在更深的网络中通过减少计算量来优化性能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

### BasicBlock 结构的定义 BasicBlock 是一种基本控制流单元,在编译器设计中广泛使用。它表示一段连续的指令序列,其中不存在分支跳转语句(除了最后一个可能存在的跳转)。这种结构的特点是从入口到出口只有一个路径执行[^1]。 在深度学习编译器中,BasicBlock 的概念同样适用,尤其是在处理计算图优化时。例如,在 TVM 中,Relay IR 提供了一种高层次抽象来描述程序逻辑,并通过 Pass 进行优化[^3]。此时,BasicBlock 可能会被用来划分不同的计算阶段或节点集合,从而便于进一步分析和转换。 ### BasicBlock 在深度学习中的作用 #### 1. **内存管理** 在深度学习模型中,张量数据通常占据大量显存资源。利用 BasicBlock 划分后的区域可以帮助识别哪些变量仅限于局部范围,进而减少不必要的分配释放操作。 #### 2. **算子融合** 当前许多性能提升技术依赖于将多个简单操作合并成更复杂的单一操作以降低开销。如果能够基于 BasicBlocks 定义清晰界限,则更容易找到适合进行此类变换的目标组群。 ```python def fuse_operations(block): fused_op = [] for op in block.operations: if can_fuse(op, fused_op[-1]): combine(fused_op[-1], op) else: fused_op.append(op) return fused_op ``` 上述伪代码展示了如何在一个给定的基本块内部尝试实施算子融合策略。 #### 3. **CUDA Kernel 并行化** 对应于 GPU 上运行的实际 kernel 函数来说,合理安排线程间协作模式至关重要。借助预先分割好的 basic blocks ,开发者可以更加直观地理解任务分解情况,并据此调整调度机制达到最佳效果[^2]。 ### 总结 综上所述,无论是传统还是现代面向 AI 应用场景下的编译工具链开发过程中,basicblock 都扮演着不可或缺的角色——不仅有助于简化复杂流程建模过程本身;而且还能促进后续各类高级别改进措施的有效落地实践当中去。
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值