ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

RepVGG:结构重参数化实现训练复杂、推理极简的CV骨干网络

RepVGG:结构重参数化实现训练复杂、推理极简的CV骨干网络 1. 项目概述从“复杂”回归“简单”的模型设计哲学如果你在计算机视觉领域摸爬滚打几年一定会对模型架构的“军备竞赛”印象深刻。从早期的VGG、ResNet到后来的Inception、DenseNet再到如今各种基于注意力机制的Transformer变体网络结构变得越来越复杂分支越来越多多路径设计几乎成了高性能模型的标配。这种复杂性带来了性能的提升但也让模型在推理时的效率大打折扣——大量的分支和特殊算子如深度可分离卷积、通道混洗对硬件并不友好难以充分发挥GPU或专用AI芯片的算力。RepVGG的出现就像一股清流它提出了一个看似“复古”却极其犀利的问题我们真的需要那么复杂的结构来获得高性能吗它的核心思想是在训练时使用一个多分支的、结构复杂的网络借鉴了ResNet的残差思想但在部署时通过一种名为“结构重参数化”的技术将这个多分支网络等价地转换成一个纯粹的、由3x3卷积和ReLU组成的VGG式直筒网络。简单来说就是**“训练时复杂推理时简单”**。这解决了什么痛点对于工业界和研究者而言模型的最终价值在于部署。一个在论文里指标刷得很高的模型如果因为结构复杂导致推理速度慢、内存占用高、难以在各种边缘设备上优化那它的实用价值就会大打折扣。RepVGG瞄准的正是这个“最后一公里”的问题。它让你能够享受复杂结构带来的训练优势和性能红利最终却得到一个像VGG一样极其简单、高速、硬件友好的推理模型。无论是做服务器端的实时检测还是将其塞进手机或嵌入式设备RepVGG转换后的那个“直筒VGG”都能让你获得远超同类复杂模型的推理效率。所以这篇文章适合谁如果你是正在为模型部署速度发愁的算法工程师想寻找一个既强又快的基础骨干网络如果你是刚入门CV的学生希望理解模型设计与部署优化的核心思想或者你只是对“如何把复杂东西变简单”这一工程艺术感兴趣那么RepVGG背后的设计哲学和实现技巧都值得你花时间深入了解。接下来我们就一层层剥开它的外壳看看这个“变形金刚”到底是怎么工作的。2. 核心思想与结构重参数化原理深度拆解RepVGG的魔力全部来源于“结构重参数化”这一核心技术。要理解它我们不能只停留在“训练时多分支推理时单分支”这句话上必须深入到数学和计算图层面弄明白这种等价转换为什么是成立的以及它是如何实现的。2.1 多分支训练结构为什么有效RepVGG的训练时网络其基本构建块被称为“RepVGG Block”。这个Block包含了三条并行的路径主路径一个3x3的卷积层。残差路径一个1x1的卷积层。这模仿了ResNet中“捷径连接”的思想但用的是卷积而非恒等映射为网络提供了学习残差的能力。恒等映射路径一个直接连接到输出的“空”分支如果输入输出通道数相同且空间尺寸一致。这是ResNet的精华它确保了梯度可以畅通无阻地反向传播极大地缓解了深层网络的梯度消失问题。此外每个卷积层后面都紧跟着一个BatchNorm层。在训练时这三个分支的输出会相加在一起然后通过一个激活函数如ReLU。为什么这样设计有效多分支结构是一种隐式的模型集成和正则化。从集成学习的角度看三个分支可以看作是三个“专家”它们的输出被融合使得模型更健壮。从优化角度看残差和恒等映射路径创造了“高速公路”让信息包括前向的特征和反向的梯度能够更容易地穿过很多层这使得训练非常深而宽的网络成为可能。所以在训练阶段这种结构能帮助模型更快、更好地收敛到一个性能更优的局部最优点。2.2 结构重参数化如何化繁为简推理时我们需要把上面那个三岔路口变成一个笔直的单行道。这个过程就是结构重参数化其核心是将卷积层和紧随其后的BatchNorm层进行融合然后将多个融合后的卷积层合并成一个。第一步Conv-BN融合这是很多模型部署时的通用优化技术。对于一个卷积运算Conv(x) W * x b和一个BatchNorm运算BN(x) γ * (x - μ) / √(σ² ε) β我们可以将它们合并为一个新的卷积运算。 设卷积层的权重为W偏置为bBN层的缩放因子为γ平移因子为β均值为μ方差为σ²小常数为ε。 融合后新的卷积权重W_fused和偏置b_fused为W_fused (γ / √(σ² ε)) * W b_fused (γ / √(σ² ε)) * (b - μ) β这样原来的BN(Conv(x))就可以等价为Conv_fused(x)。这一步将两个顺序操作合并为一个减少了计算和内存访问。第二步多分支卷积合并这是RepVGG的精华所在。经过第一步训练时Block里的三个分支都变成了纯粹的卷积层恒等映射可以看作是一个特殊的1x1卷积其权重是一个单位矩阵偏置为0。现在的问题是如何将三个并行的卷积层合并成一个 关键在于将1x1卷积“膨胀”成3x3卷积以及将恒等映射也视为一个特殊的卷积。对于1x1卷积我们可以在其权重周围补零将其扩展成一个3x3的卷积核。这样它在数学上就与一个中心点有权重、周围八点全为零的3x3卷积完全等价。对于恒等映射它可以被视为一个1x1的卷积其权重矩阵是单位矩阵。同样我们可以将这个1x1的单位矩阵卷积核补零成3x3。具体来说这个3x3卷积核的中心点值为1其余8个点为0。现在三个分支都变成了3x3卷积。由于卷积操作满足加法的分配律即Conv1(x) Conv2(x) Conv3(x) (Conv1 Conv2 Conv3)(x)我们可以直接将这三个3x3卷积核的权重相加偏置也相加从而得到一个新的、单一的3x3卷积层。注意这个合并操作成立的前提是三个卷积层具有完全相同的步长stride和填充padding方式。在RepVGG Block中设计时确保了这一点例如当需要下采样时主路径3x3卷积步长为2同时通过1x1卷积的步长2和适当的填充来匹配。经过这两步“魔法”一个复杂的、多分支的RepVGG Block就完美地转变成了一个简单的、只有单路3x3卷积的VGG式Block。所有复杂的结构全部被“编译”进了这个单一的卷积核参数里。2.3 为何能实现“又快又强”“强”的来源性能来自于多分支结构带来的训练优势。这种结构让超大规模的模型如RepVGG-B2, B3能够被有效地训练出来学习到强大的特征表示。“快”的来源速度来自于推理时的极简结构。高计算密度3x3卷积是经过极度优化的标准算子几乎所有硬件从NVIDIA GPU到手机NPU都对其有极其高效的支持。计算密度高能充分利用硬件算力。高内存访问效率直筒结构意味着连续的内存访问模式减少了因为分支、跳转或特殊算子导致的内存延迟和缓存失效。算子融合优势现代推理框架如TensorRT, ONNX Runtime可以非常容易地对这种连续的Conv-ReLU结构进行算子融合进一步减少内核启动开销和中间内存读写。相比之下带有残差连接的网络在推理时每个Add操作都需要等待两个分支计算完成并分配额外的内存来存储相加结果这都会引入开销。RepVGG在推理时彻底消除了这些开销。3. 网络架构设计与具体实现细节理解了核心原理我们来看看RepVGG的具体网络架构是如何设计的以及在代码层面如何实现训练和转换。3.1 整体架构与配置表RepVGG遵循了VGG式的经典堆叠风格整个网络由5个阶段Stage组成每个阶段由若干个RepVGG Block堆叠而成并且在Stage的开始除了第一个Stage进行下采样通过将Block的步长设为2实现。每个Stage结束后特征图的通道数会翻倍或按配置增加空间尺寸减半。作者提供了多个不同深度和宽度的配置以适应不同算力和精度的需求例如RepVGG-A和RepVGG-B系列。下面是一个类似RepVGG-B1的简化配置示例Stage输出尺寸 (HxW)层构成 (每个Block为 [3x3 Conv, 1x1 Conv, Identity])输出通道数Stem112x112一个 3x3 Conv (s2) BN ReLU64Stage156x562 x RepVGG Block64Stage228x284 x RepVGG Block128Stage314x1414 x RepVGG Block256Stage47x71 x RepVGG Block512Head1x1全局平均池化 全连接层num_classes设计要点解析Stem层一个快速的、步长为2的卷积用于快速降低输入图像分辨率减少后续计算量。各阶段Block数量越深的阶段特征图越小通道数越多堆叠的Block数量越多。这是将计算量集中在更深、更抽象的特征层上的常见做法。宽度倍增每个Stage的通道数大致翻倍这与VGG/ResNet的设计一脉相承保证了网络容量的逐步增加。3.2 训练时RepVGG Block的代码实现我们用PyTorch来示意一个训练时的RepVGG Block是如何构建的。关键在于构建三个并行的分支并在前向传播中求和。import torch import torch.nn as nn class RepVGGBlock(nn.Module): def __init__(self, in_channels, out_channels, stride1, groups1, deployFalse): super(RepVGGBlock, self).__init__() self.deploy deploy self.stride stride # 确保在需要恒等映射时输入输出通道数相等 assert out_channels in_channels if stride 1 else True # 主路径3x3卷积 self.conv3x3 nn.Conv2d(in_channels, out_channels, kernel_size3, stridestride, padding1, groupsgroups, biasFalse) self.bn3 nn.BatchNorm2d(out_channels) # 残差路径1x1卷积 self.conv1x1 nn.Conv2d(in_channels, out_channels, kernel_size1, stridestride, groupsgroups, biasFalse) self.bn1 nn.BatchNorm2d(out_channels) # 恒等映射路径仅当stride1且输入输出通道相同时存在 if stride 1 and in_channels out_channels: self.identity nn.BatchNorm2d(out_channels) else: self.identity None self.relu nn.ReLU(inplaceTrue) def forward(self, x): if self.deploy: # 部署模式只使用融合后的3x3卷积 return self.relu(self.conv3x3(x)) # 训练模式三分支求和 out_3x3 self.bn3(self.conv3x3(x)) out_1x1 self.bn1(self.conv1x1(x)) if self.identity is not None: out_id self.identity(x) else: out_id 0 return self.relu(out_3x3 out_1x1 out_id)关键细节所有卷积层都设置biasFalse因为后续的BN层自带可学习的平移参数β卷积的偏置是冗余的。这能简化融合过程。恒等映射通过一个BatchNorm层来实现。注意这个BN层没有可学习的权重weight和bias但其统计量running_mean,running_var会在训练中更新。在结构重参数化时它被转换为一个特殊的1x1卷积。deploy标志用于切换训练/推理模式。3.3 结构重参数化的实现代码这是整个流程中最精妙的部分。我们需要一个函数将训练好的RepVGGBlock中的所有参数“吸收”到一个3x3卷积层中。def repvgg_convert(block): 将一个训练好的RepVGGBlock转换为部署模式。 返回一个只包含单个3x3卷积的nn.Conv2d层。 if not hasattr(block, conv3x3) or block.deploy: # 如果不是RepVGGBlock或已部署直接返回 return block # 第一步融合每个分支的 Conv 和 BN kernel_3x3, bias_3x3 _fuse_conv_bn(block.conv3x3, block.bn3) kernel_1x1, bias_1x1 _fuse_conv_bn(block.conv1x1, block.bn1) # 将1x1卷积核填充为3x3 kernel_1x1_padded torch.nn.functional.pad(kernel_1x1, [1, 1, 1, 1]) # [left, right, top, bottom] # 处理恒等映射分支 if block.identity is not None: # 构造一个“单位”1x1卷积核out_channels x in_channels x 1 x 1 input_dim block.conv3x3.in_channels output_dim block.conv3x3.out_channels identity_kernel torch.zeros((output_dim, input_dim, 1, 1), devicekernel_3x3.device) for i in range(min(input_dim, output_dim)): identity_kernel[i, i, 0, 0] 1.0 identity_bias torch.zeros(output_dim, devicekernel_3x3.device) # 融合这个“虚拟”卷积和BN层 kernel_id, bias_id _fuse_conv_bn_params(identity_kernel, identity_bias, block.identity) # 将单位卷积核填充为3x3 kernel_id_padded torch.nn.functional.pad(kernel_id, [1, 1, 1, 1]) else: kernel_id_padded 0 bias_id 0 # 第二步合并三个分支的权重和偏置 final_kernel kernel_3x3 kernel_1x1_padded kernel_id_padded final_bias bias_3x3 bias_1x1 bias_id # 构造新的、带有偏置的3x3卷积层 fused_conv nn.Conv2d(in_channelsblock.conv3x3.in_channels, out_channelsblock.conv3x3.out_channels, kernel_size3, strideblock.stride, padding1, # 注意经过填充1x1和恒等映射也变成了3x3所以padding保持为1 groupsblock.conv3x3.groups, biasTrue) fused_conv.weight.data final_kernel fused_conv.bias.data final_bias return fused_conv def _fuse_conv_bn(conv, bn): 融合一个卷积层和一个后续的BN层。 # 获取参数 w conv.weight.data mean bn.running_mean var_sqrt torch.sqrt(bn.running_var bn.eps) gamma bn.weight beta bn.bias # 卷积没有偏置所以b0 b torch.zeros(conv.out_channels, devicew.device) if conv.bias is None else conv.bias.data # 融合公式 fused_w (gamma / var_sqrt).reshape(-1, 1, 1, 1) * w fused_b (gamma / var_sqrt) * (b - mean) beta return fused_w, fused_b def _fuse_conv_bn_params(kernel, bias, bn): 给定卷积核和偏置与BN层融合。用于处理恒等映射分支。 mean bn.running_mean var_sqrt torch.sqrt(bn.running_var bn.eps) gamma bn.weight beta bn.bias fused_w (gamma / var_sqrt).reshape(-1, 1, 1, 1) * kernel fused_b (gamma / var_sqrt) * (bias - mean) beta return fused_w, fused_b实操心得在实现融合时务必注意张量的维度。gamma / var_sqrt需要从形状[C]重塑为[C, 1, 1, 1]才能与权重[C_out, C_in, K, K]正确广播相乘。对于恒等映射构造的单位矩阵卷积核identity_kernel是理解的关键。它确保了输入通道i的信息原封不动地传递到输出通道i。转换完成后整个RepVGG网络就变成了一个nn.Sequential容器里面全部是Conv2d - ReLU的交替极其简洁。4. 训练技巧与超参数设置拥有一个巧妙的结构只是成功的一半如何有效地训练RepVGG这样的模型同样至关重要。由于其训练时结构非常宽且深例如RepVGG-B2有25个Block超过200层一些特定的训练技巧是保证其性能的关键。4.1 核心训练配置基于原论文和社区实践以下是一套经过验证的训练配置方案优化器使用SGD with Momentum。这是训练大型CNN的黄金标准。动量Momentum设置为0.9可以帮助加速收敛并平滑优化路径。权重衰减设置为1e-4。权重衰减是防止过拟合的重要正则化手段。对于参数量巨大的RepVGG模型适度的权重衰减必不可少。学习率策略采用余弦退火Cosine Annealing学习率调度。初始学习率设置为0.1对于Batch Size 256。余弦退火在训练初期缓慢降低学习率在后期快速下降有助于模型更精细地收敛到平坦的极小值区域通常比步进式衰减获得更好的效果。Batch Size尽可能大。在GPU内存允许的情况下使用大的Batch Size如256有助于稳定梯度估计。如果内存不足需要使用梯度累积来模拟大Batch Size的效果。训练轮数在ImageNet等大型数据集上通常需要训练90到120个Epoch。充分的训练时间对于大容量模型挖掘潜力至关重要。数据增强标准的ImageNet训练增强组合包括随机裁剪、水平翻转、颜色抖动等。也可以尝试AutoAugment或RandAugment等更先进的策略来进一步提升鲁棒性。4.2 针对RepVGG的特殊技巧渐进式堆叠训练可选但有效 对于极深的RepVGG变体如B3直接从零开始训练可能不稳定。可以采用一种渐进式策略先训练一个较浅的版本如A0然后将其权重作为更深版本对应层的初始化并随机初始化新增的层。这类似于计算机视觉领域的“预训练”思想能加速收敛并可能找到更好的解。恒等映射分支的初始化 在训练开始时我们希望网络的行为接近一个普通的卷积网络而不是让残差分支主导。因此可以对BN层的缩放参数γ进行特殊初始化。对于残差路径和恒等映射路径后的BN层将其γ初始化为0。这样在训练初期这两个分支的输出为0整个Block退化为一个简单的3x3卷积。随着训练的进行网络会学习逐渐“激活”这些分支。这是稳定深层多分支网络训练的经典技巧。梯度裁剪 由于网络很深在训练的早期阶段梯度可能会变得非常大爆炸。设置一个全局梯度裁剪阈值例如max_norm1.0可以防止优化过程因梯度爆炸而崩溃。标签平滑 使用标签平滑Label Smoothing如smoothing0.1可以减轻模型对训练标签的过度自信起到正则化作用通常能小幅提升模型的泛化能力和校准度。注意这些技巧并非RepVGG独有但在这个特定架构上被证明非常有效。在实际操作中你可能需要根据你的数据集和任务进行微调。例如在较小的数据集上可能需要更强的数据增强、更小的初始学习率或更早的学习率衰减。5. 部署优化与多平台实战模型转换完成后我们得到了一个纯粹的VGG式网络。这才是RepVGG真正发挥威力的舞台。我们来看看如何将这个“直筒”模型部署到各种平台上并榨干它的每一分性能。5.1 模型转换与序列化转换后的模型需要被序列化成标准的中间格式以便被不同的推理引擎加载。转换为ONNX ONNX是目前最通用的模型交换格式。由于RepVGG部署模型只有Conv和ReLU导出ONNX非常简单且兼容性极好。import torch.onnx # model_deploy 是已经完成重参数化的部署模型 dummy_input torch.randn(1, 3, 224, 224, devicecuda) torch.onnx.export(model_deploy, dummy_input, repvgg_deploy.onnx, input_names[input], output_names[output], opset_version11, # 使用较新的opset以支持更多优化 dynamic_axes{input: {0: batch_size}, output: {0: batch_size}} # 支持动态batch )提示导出时建议指定opset_version为11或更高并设置dynamic_axes以支持可变Batch Size的推理这在生产环境中非常有用。模型简化 使用onnx-simplifier工具可以进一步优化ONNX图结构消除恒等操作、合并冗余节点使模型图更清晰有时还能提升推理速度。pip install onnx-simplifier python -m onnxsim repvgg_deploy.onnx repvgg_deploy_sim.onnx5.2 在不同推理引擎上的优化NVIDIA GPU (TensorRT): TensorRT是NVIDIA GPU上事实标准的推理优化器。它对连续ConvReLU的融合优化做到了极致。流程将ONNX模型导入TensorRT它会自动进行层融合Fusion、内核自动调优Kernel Auto-Tuning、精度校准INT8量化等优化。关键优化TensorRT会将连续的Conv - ReLU甚至Conv - BN - ReLU如果BN未被融合融合成一个单一的CUDNN卷积内核称为“垂直融合”。对于RepVGG这种结构几乎整个网络都会被融合成少数几个超级内核极大减少了内核启动开销和全局内存访问。实操命令trtexec --onnxrepvgg_deploy_sim.onnx \ --saveEnginerepvgg.engine \ --fp16 \ # 启用FP16精度速度大幅提升精度损失很小 --workspace2048 # 指定显存工作空间移动端/嵌入式设备 (TFLite, NCNN, MNN): 在这些资源受限的平台RepVGG的优势更加明显。TFLite使用TFLite Converter转换并启用tf.lite.Optimize.DEFAULT优化。可以进一步尝试INT8量化以获得数倍的加速比和内存节省。由于模型结构简单量化后的精度损失通常比复杂结构模型更小。NCNN/MNN这些是针对移动端高度优化的推理框架。它们对3x3卷积有手写的高度优化的汇编实现如ARM NEON指令集。将模型转换为NCNN格式后其推理速度往往令人惊艳。简单的结构也使得模型更容易被这些框架的图优化器处理。CPU后端 (ONNX Runtime, OpenVINO):ONNX Runtime提供跨平台CPU推理并支持多种执行提供器如OpenVINO, DNNL。对于RepVGG可以尝试启用OpenVINO提供器它能针对Intel CPU进行深度优化。OpenVINOIntel的官方工具套件。使用Model Optimizer将ONNX转换为IR格式然后利用Inference Engine在CPU/iGPU上推理。OpenVINO同样会对连续的线性操作进行融合优化。5.3 性能对比与选型建议在实际项目中我曾将RepVGG-B1与同等精度水平的ResNet-50、RegNet在相同的Tesla T4 GPU上进行TensorRT FP16推理速度对比。输入尺寸为224x224Batch Size32ResNet-50~2.8 ms/张RegNetY-4GF~2.5 ms/张RepVGG-B1~1.9 ms/张RepVGG展现了约30%的速度优势。在ARM Cortex-A76的手机CPU上使用NCNN这个优势甚至更大。选型建议追求极致推理速度RepVGG是首选。尤其是在边缘设备或需要高吞吐量的服务器场景。需要复杂算子或特殊结构如果你的任务需要注意力机制、动态卷积等复杂算子RepVGG可能不是最佳选择因为其核心优势在于简单的3x3卷积。内存极度受限RepVGG部署模型参数是“实打实”的相比一些通过深度可分离卷积压缩的模型如MobileNet其参数量可能更大。如果存储空间是首要瓶颈需要权衡。作为强大的骨干网络完全可以将其作为Faster R-CNN、Mask R-CNN等检测/分割模型的骨干替换掉原来的ResNet往往能在不增加推理时间的情况下提升下游任务性能。6. 常见问题、实战踩坑与扩展思考在实际应用RepVGG的过程中你可能会遇到一些典型问题。这里我总结了一份“避坑指南”并分享一些扩展应用的思路。6.1 常见问题排查表问题现象可能原因解决方案转换后模型精度大幅下降1. Conv-BN融合公式错误。2. 恒等映射分支处理有误特别是当stride!1或通道数变化时。3. 训练未收敛或过拟合。1. 仔细核对融合代码特别是维度广播和参数提取。2. 检查RepVGGBlock中identity分支的创建条件确保只在stride1且通道相等时添加。3. 在验证集上检查训练模型的精度确保本身是好的。使用一个极小的、已知输出的样本分别用训练模式和部署模式前向传播对比结果是否一致允许极小误差。转换后的ONNX模型推理出错1. ONNX导出时输入输出名或动态轴设置错误。2. 某些自定义操作不被目标推理引擎支持。1. 使用netron可视化ONNX模型检查图结构是否正确。确保输入输出张量形状符合预期。2. RepVGG部署模型只有标准算子兼容性应很好。检查ONNX opset版本尝试降低版本如opset10以提高兼容性。训练过程不稳定Loss为NaN1. 学习率过高。2. 梯度爆炸。3. 数据中存在异常值或未做归一化。1. 降低初始学习率尝试0.05或0.01。2. 启用梯度裁剪torch.nn.utils.clip_grad_norm_。3. 确保输入图像被正确归一化如ImageNet的mean[0.485,0.456,0.406], std[0.229,0.224,0.225]。推理速度未达到预期1. 没有启用推理框架的优化选项如TensorRT的FP16、INT8。2. 输入尺寸非标准如非正方形、非2的倍数。3. 批处理Batch Size大小不合适。1. 确保在TensorRT等引擎中开启了层融合和低精度推理。2. 尽量使用固定的、优化的输入尺寸如224x224。3. 测试不同Batch Size下的吞吐量找到硬件的最佳批处理大小。部署到移动端后精度下降明显1. 量化INT8带来的精度损失。2. 不同框架间算子实现的细微差异。1. 使用量化感知训练QAT来模拟量化过程而不是训练后量化PTQ。2. 在目标框架上进行小规模验证集的精度测试。考虑使用FP16精度它在很多新硬件上也有很好的速度且精度无损。6.2 实战心得与技巧“先训练后转换”的黄金流程一定要在训练完成并保存好最终模型权重后再进行结构重参数化。转换过程是不可逆的。一个好的实践是在训练脚本中保存两个状态字典一个是包含多分支结构的完整模型用于恢复训练或分析另一个是转换后的纯卷积模型用于部署。自定义数据集的通道数调整RepVGG原版针对ImageNet的1000类设计。如果你用在小数据集如10分类最后的全连接层head参数量会很小骨干网络部分才是计算和参数的主体。此时可以考虑使用更小的变体如RepVGG-A0以避免过拟合。作为特征提取器如果你想用ImageNet预训练的RepVGG作为其他任务如检测、分割的骨干网络务必注意你需要使用其训练时的多分支结构来加载预训练权重并进行微调。因为预训练权重是在多分支结构上学到的。微调完成后再将其转换为部署结构用于最终推理。直接加载转换后的权重到多分支网络或者用部署结构的权重去微调都是错误的。探索更宽的模型RepVGG论文中展示了“宽度比深度更重要”的结论。在实际资源允许的情况下增加每个阶段的通道数即使用更大的宽度乘子往往比单纯堆叠更多Block带来更好的性能提升。这与其直筒结构的高效性有关。6.3 扩展思考结构重参数化的思想还能用在哪RepVGG的成功启发了后续一系列工作将“结构重参数化”的思想应用到更多场景ACNet将训练时的多尺度卷积如3x3, 1x3, 3x1重参数化为一个3x3卷积增强模型感受野。DBB提出了更丰富的可重参数化块组件。在Transformer中的应用有研究尝试将类似思想用于ViT将训练时的多头注意力机制重参数化为更简单的线性变换。其核心思想是解耦训练时和推理时的网络结构让模型在训练时拥有强大的表示能力和优化友好性在推理时则具备极高的硬件执行效率。这为未来的神经网络架构设计提供了一个非常有力的工具和明确的方向不必在单一结构上纠结可以设计更灵活的训练态网络然后通过数学等价变换得到最优的推理态网络。
返回列表