通过训练时多分支与推理时单路径的智能解耦,实现精度与速度的完美平衡
相比ResNet-50
相比EfficientNet-B0
训练时多分支提升性能,推理时单路径保证效率
纯VGG式架构,充分利用GPU并行计算能力
单路径结构降低内存访问成本,提升计算密度
RepVGG 的核心创新在于结构重参数化技术,该技术允许模型在训练时采用复杂的多分支结构以提升性能,而在推理时则转换为简单的单路 VGG 式结构以追求极致速度和内存效率。通过将训练时的 3x3 卷积、1x1 卷积和恒等映射分支及其 BatchNorm 层参数等价融合为单一的 3x3 卷积层,RepVGG 在 ImageNet 等基准测试中,相较于 ResNet 和 EfficientNet 等主流模型,展现出更高的精度、更快的实际推理速度以及更优的内存占用,尤其在 GPU 等并行计算硬件上优势显著。
RepVGG 的结构重参数化技术核心在于将模型的训练结构和推理结构进行分离,并通过参数转换实现两者之间的等价变换。这种解耦机制使得模型能够同时利用多分支结构在训练时的优势以及单路极简结构在推理时的优势。
通过消融实验证明,移除 identity 分支或 1x1 卷积分支都会导致模型准确率的显著下降。 在 RepVGG-B0 的实验中,移除这两个分支后,模型准确率从 75.14% 下降到 72.39%, 充分说明了多分支结构对于提升模型性能的重要性。 [102]
RepVGG 的结构重参数化过程主要依赖于卷积运算的线性可加性以及 Batch Normalization 层在推理时的线性特性。整个转换过程可以概括为三个关键步骤。
将每个分支中的卷积层和其后的 BN 层合并为一个带有偏置的卷积层,通过线性变换实现参数融合。
将 1x1 卷积通过零填充扩展为 3x3 卷积,将 Identity 分支转换为等效的 3x3 卷积核。
利用卷积运算的线性可加性,将三个分支的卷积核和偏置进行元素级别相加,得到最终参数。
模型 | Top-1 Acc (%) | 速度 (ex/s) | 参数量 (M) | FLOPs (B) |
---|---|---|---|---|
RepVGG-A0 | 72.41 | 3256 | 8.30 | 1.4 |
ResNet-18 | 71.16 | 2442 | 11.68 | 1.8 |
RepVGG-A2 | 76.48 | 1322 | 25.49 | 5.1 |
ResNet-50 | 76.31 | 719 | 25.53 | 3.9 |
EfficientNet-B0 | 75.11 | 829 | 5.26 | 0.4 |
数据来源:RepVGG 论文 Table 4,在 NVIDIA 1080Ti GPU 上测试,batch size=128。 [158] [251]
超越 ResNet 和 EfficientNet
GPU 优化优势明显
低访存开销
结构简单灵活
RepVGG 的结构重参数化在实现上主要涉及训练时多分支模块的定义和参数转换逻辑。以下是基于 PyTorch 风格的核心实现代码。 [142]
class RepVGGBlock(nn.Module):
def __init__(self, in_channels, out_channels,
stride=1, groups=1, deploy=False):
super().__init__()
self.deploy = deploy
if deploy:
self.rbr_reparam = nn.Conv2d(
in_channels, out_channels,
kernel_size=3, stride=stride,
padding=1, groups=groups, bias=True
)
else:
self.rbr_identity = nn.BatchNorm2d(in_channels)
if out_channels == in_channels and stride == 1 else None
self.rbr_dense = nn.Sequential(
nn.Conv2d(in_channels, out_channels,
kernel_size=3, stride=stride,
padding=1, groups=groups, bias=False),
nn.BatchNorm2d(out_channels)
)
self.rbr_1x1 = nn.Sequential(
nn.Conv2d(in_channels, out_channels,
kernel_size=1, stride=stride,
padding=0, groups=groups, bias=False),
nn.BatchNorm2d(out_channels)
)
def forward(self, inputs):
if self.deploy:
return self.nonlinearity(self.rbr_reparam(inputs))
identity_out = 0 if self.rbr_identity is None else self.rbr_identity(inputs)
return self.nonlinearity(
self.rbr_dense(inputs) + self.rbr_1x1(inputs) + identity_out
)
def get_equivalent_kernel_bias(self):
kernel3x3, bias3x3 = self._fuse_bn_tensor(self.rbr_dense)
kernel1x1, bias1x1 = self._fuse_bn_tensor(self.rbr_1x1)
kernelid, biasid = self._fuse_bn_tensor(self.rbr_identity)
# 1x1 卷积填充为 3x3
kernel1x1_padded = F.pad(kernel1x1, [1, 1, 1, 1])
# 合并所有分支参数
return (kernel3x3 + kernel1x1_padded + kernelid,
bias3x3 + bias1x1 + biasid)
def _fuse_bn_tensor(self, branch):
if branch is None:
return 0, 0
if isinstance(branch, nn.Sequential):
kernel = branch[0].weight
running_mean = branch[1].running_mean
running_var = branch[1].running_var
gamma = branch[1].weight
beta = branch[1].bias
eps = branch[1].eps
else:
# Identity 分支处理
return None, None
std = (running_var + eps).sqrt()
t = (gamma / std).reshape(-1, 1, 1, 1)
return kernel * t, beta - running_mean * gamma / std
使用多分支结构进行训练,获得最佳精度
调用 switch_to_deploy 方法进行重参数化
使用单路径结构进行高效推理
将结构重参数化应用于 Transformer、图神经网络等更多架构
结合神经架构搜索技术自动设计多分支结构和重参数化策略
针对 ASIC、FPGA 等特定硬件优化 RepVGG 结构和实现
与知识蒸馏、量化、剪枝等技术结合,进一步优化模型
在目标检测、语义分割等更多下游任务中验证性能
探索在自然语言处理等其他领域的适用性
RepVGG 作为一种简单、快速、强大且通用的卷积神经网络架构,通过其创新的结构重参数化技术, 成功解决了模型性能与推理效率之间的矛盾。其"训练时复杂,推理时简单"的核心思想, 为深度学习模型的设计和部署提供了宝贵的经验和启示,有望在未来催生出更多创新性的研究成果和实际应用。