CV中常用的骨干网络简述与其量化方式

骨干网络简述

目前工业中常用的cv网络可以分为三种:

  • 基于卷积的网络(CNN)
  • 基于transformer的网络
  • 上述两者的混合

目前在较为复杂的场景,为了提高网络泛化,即便是CNN也会有较深的网络出现,一整个模型可能包含了多个子模型,每个小模型(或module)可能负责特征提取,可能负责多尺度特征融合,可能负责视角变换,可能负责分类。参考YOLO的基本架构,骨干网络即Backbone是网络中的核心部分,负责将输入的少通道(一般为3或4)的彩色、人眼可识别的尺寸较大的图像转化为多频道(可能在数百甚至数千频道)、小尺寸的特征图。同时,即便是网络内包含transformer结构的,可能也会先使用CNN对特征进行提取,随后再输入到transformer内进一步进行特征提取并最后对输出的sequence进行预测。

骨干网络的深度可能并不会特别深,但参数量较大,在智能驾驶领域大量使用的视觉模型,骨干网络的推理耗时占总推理耗时的比率相对而言很高,因此在一个深度网络中选择一个参数量、性能、推理时间都较为合适的骨干网络是很难的。

同时,骨干网络也是优化的主要目标(包括剪枝、稀疏化、量化等方法),由于骨干网络的组成元素相对简单(一般全都是卷积+残差),工业上经验积累较多,优化起来效果比较明显,在实时性要求比较高的场合,骨干网络一般全都需要跑在INT8精度下,这对其本身的结构设计的要求会很高。

常用骨干网络

ResNet Family

首当其冲的是非常经典的ResNet,ResNet的特点是结构分级明显、清晰简单,废话不多说,直接上图
ResNet Family Architecture

首先可以看到Resnet-18/34使用的在后续conv block内使用的残差块均是两个3x3conv,而Resnet-50及更深的网络使用的残差块是两个1x1conv夹了一个3x3conv。再其他的区别就只剩下每个conv block内的残差块数量的区别了。更深的网络有更多的参数,

同时我们可以看一下mmcv库内的resnet家族的源码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
class ResNet(nn.Module):

arch_settings = {
18: (BasicBlock, (2, 2, 2, 2)),
34: (BasicBlock, (3, 4, 6, 3)),
50: (Bottleneck, (3, 4, 6, 3)),
101: (Bottleneck, (3, 4, 23, 3)),
152: (Bottleneck, (3, 8, 36, 3))
}

def __init__(self,
depth: int,
num_stages: int = 4,
strides: Sequence[int] = (1, 2, 2, 2),
dilations: Sequence[int] = (1, 1, 1, 1),
out_indices: Sequence[int] = (0, 1, 2, 3),
style: str = 'pytorch',
frozen_stages: int = -1,
bn_eval: bool = True,
bn_frozen: bool = False,
with_cp: bool = False):
super().__init__()
if depth not in self.arch_settings:
raise KeyError(f'invalid depth {depth} for resnet')
assert num_stages >= 1 and num_stages <= 4
block, stage_blocks = self.arch_settings[depth]
stage_blocks = stage_blocks[:num_stages] # type: ignore
assert len(strides) == len(dilations) == num_stages
assert max(out_indices) < num_stages

self.out_indices = out_indices
self.style = style
self.frozen_stages = frozen_stages
self.bn_eval = bn_eval
self.bn_frozen = bn_frozen
self.with_cp = with_cp

self.inplanes: int = 64
self.conv1 = nn.Conv2d(
3, 64, kernel_size=7, stride=2, padding=3, bias=False)
self.bn1 = nn.BatchNorm2d(64)
self.relu = nn.ReLU(inplace=True)
self.maxpool = nn.MaxPool2d(kernel_size=3, stride=2, padding=1)

self.res_layers = []
for i, num_blocks in enumerate(stage_blocks):
stride = strides[i]
dilation = dilations[i]
planes = 64 * 2**i
res_layer = make_res_layer(
block,
self.inplanes,
planes,
num_blocks,
stride=stride,
dilation=dilation,
style=self.style,
with_cp=with_cp)
self.inplanes = planes * block.expansion # type: ignore
layer_name = f'layer{i + 1}'
self.add_module(layer_name, res_layer)
self.res_layers.append(layer_name)

self.feat_dim = block.expansion * 64 * 2**( # type: ignore
len(stage_blocks) - 1

Darknet Family

VGG、RepVGG Family


CV中常用的骨干网络简述与其量化方式
https://blog.bakeneko-kuro.com/2025/10/14/hpc/cv-backbone/
作者
迷途黑猫
发布于
2025年10月14日
许可协议