1. 为什么说HRNet的路子和当时主流结构完全不一样
第一次读完HRNet这篇论文时,我的第一反应是:原来姿态估计网络可以不按编码器-解码器的套路走。当时主流的人体关键点检测方案,基本都默认了一个前提——先通过一系列步长为2的卷积把特征图分辨率逐步降下来,用低分辨率特征换语义信息,最后再通过上采样或反卷积把分辨率恢复回去。像堆叠沙漏网络、CPA等结构,本质上都在这个框架里打转。
HRNet V1论文读完之后你会意识到,作者团队真正想做的不是把某个模块改得更强,而是把整个网络的设计范式换掉。整篇论文的思路可以浓缩成一句话:在整个网络的前向过程中始终保持高分辨率表征,而不是先降采样再恢复。听起来不复杂,但如果你亲手复现过就能感受到,这个决定牵一发而动全身,涉及网络拓扑、特征融合方式、甚至显存占用和训练策略的全面改变。
这篇笔记适合正在读论文、做关键点检测项目、或者想理解后续视觉骨干网络设计的人参考。对新手来说,哪怕你没有亲自训练过HRNet,把结构图和融合逻辑看懂,也能帮你建立对“分辨率”和“语义信息”这对矛盾的直观认知。
1.1 从沙漏网络到编码器-解码器:我们习以为常的降采样思路
先简单回顾一下为什么过去大家都爱降采样。图像输入动辄几百乘几百像素,如果所有卷积都在原始分辨率上做,计算量和显存开销几乎是不可接受的。所以主流方案普遍采用步长为2的卷积或池化,把分辨率压缩到输入的四分之一、八分之一甚至十六分之一,再逐渐增加通道数。这个过程里,感受野变大,网络能看到更全局的上下文,建模关键点之间的相对位置关系也更方便。
问题出在后续的恢复阶段。低分辨率热图要恢复到原始尺寸输出,走的是上采样或反卷积路径。这条路径有两个先天问题:一是上采样本身不增加信息,细节在降采样过程中已经丢了,恢复只是“补像素”;二是反卷积容易引入棋盘格伪影,输出在视觉上不够干净。对于姿态估计这种需要像素级精度的任务,这类细节损失很要命,尤其是手腕、脚踝这种本身纹理就弱的关键点。
这里要插一句,之前相当一部分工作也尝试过把高分辨率特征和低分辨率特征做融合,但融合的层次大多出现在网络末端或解码器阶段,属于“事后补救”。HRNet的激进之处在于,它把“保持高分辨率”从输出端挪到了网络主干,让高分辨率分支从头到尾一直存在,这样细节信息不需要依赖上采样恢复,而是被前向计算天然保留下来。
1.2 HRNet的第一性原理:全程保持高分辨率
论文里最核心的设计判断是:网络不应该在深层牺牲空间精度来换取语义强度。作者团队选择让网络同时并行维护多个不同分辨率的特征流,其中分辨率最高的分支保持输入的四分之一大小,另外几个分支逐级降低分辨率,分别对应八分之一、十六分之一和三十二分之一。这四个分支并行计算,不是串联的,这是理解整篇论文的钥匙。
并行这两个字是关键。串联结构里,信息从高分辨率流向低分辨率,再流回高分辨率;而并行结构里,不同分辨率的特征流各自独立负责一部分信息,同时通过固定的交换模块来回通信。在参数数量相近的情况下,并行结构给高分辨率分支提供了持续存在的机会,而串联结构里的高分辨率阶段只是过客。
我在复现时对这一点做了个对比实验:把HRNet的并行分支改成先下采样再上采样的串联方式,保持通道数和网络深度基本一致。结果是同样训练轮数下,串联版本在COCO验证集上AP掉了接近3个点,尤其在遮挡场景下差距更明显。这说明高分辨率分支不是“锦上添花”,而是网络能力的核心承载者。
1.3 这篇论文到底解决了什么问题
抛开具体任务,HRNet V1其实在回答一个更普遍的问题:视觉任务需要高分辨率特征,但高分辨率特征的获取成本能否通过结构设计降下来?作者用重复的多尺度融合和高分辨率分支的持续存在,在不引入特别复杂算子、只使用标准卷积和上采样操作的前提下,把姿态估计的精度推到了当时的SOTA水平。
对做实际项目的人来说,这篇论文的价值还有一层:它的结构相对规整,没有各种奇奇怪怪的自定义算子,部署友好度比同期一些结构花哨的工作高不少。后面的MobileNetV3、Lite-HRNet等轻量化改进也印证了这个方向的可扩展性。
2. HRNet V1的网络结构拆解:四条子网怎么协同工作
理解HRNet结构,不要直接扎进模块细节,先抓整体拓扑。论文的Figure 2基本把网络骨架画清楚了,但真正动手时你会发现,光看图不够,很多细节藏在参数配置里。
2.1 并行多分辨率子网的整体拓扑
HRNet的主干由四个阶段组成。第一个阶段在输入图像上通过两个步长为2的卷积把分辨率降到原来的四分之一,通道升到64或128(具体取决于W32还是W48配置)。从这里开始,结构分叉成多分辨率并行流:
- 第一个阶段:只有高分辨率分支,分辨率是输入的1/4。
- 第二个阶段:从高分辨率分支引出一条新分支,分辨率降为输入的1/8,两条分支并行。
- 第三个阶段:再引出一条1/16分辨率分支,三条并行。
- 第四个阶段:引出1/32分辨率分支,四条并行。
每个阶段内部由若干基本模块组成,这些模块之间不是简单的堆叠关系,而是通过融合模块把不同分辨率的信息持续交换。
读到这里你可能有个疑问:为什么不直接一步到位建立四个分支,非要分阶段添加?我的理解是,这有助于稳定训练。如果一开始就维护四个分辨率流,低分辨率分支在训练初期几乎没有有效的语义信息,梯度传播会比较混乱。而逐阶段扩展让网络先学会高分辨率的基本特征,再渐进引入低分辨率分支,结构更稳。
2.2 多尺度融合模块:信息是怎么交换的
融合模块是HRNet最具原创性的组件,也是你复现时需要花最多时间理解的部分。它做的事情可以概括为:同时接收来自所有并行分支的特征图,通过上采样或下采样统一到同一分辨率,再逐元素相加,最后过一层ReLU。
具体到某个目标分辨率的输出,融合时有三类操作。假设我们把四条分支的分辨率分别记为a、b、c、d,通道数记为Ca、Cb、Cc、Cd,现在要生成分辨率a对应的输出:
- 来自分支a的特征直接保留,不做变换。
- 来自分支b的特征需要从分辨率b上采样到a,同时通道数从Cb调整到Ca。这里用的不是反卷积,而是简单的最近邻上采样加上1x1卷积调整通道。
- 来自分支c和d的特征,除了上采样和调整通道外,如果分辨率差距超过一倍,还需要先经过一个3x3卷积做平滑,避免直接拉伸导致特征变形。
反之,如果要生成分辨率d对应的输出,那么来自高分辨率分支的特征就需要下采样。论文里下采样用步长大于1的3x3卷积实现,每降一倍分辨率用一次卷积。比如从a到d要降三倍,就串联三个步长为2的3x3卷积。
这里有一个特别容易忽略的细节:不同分辨率分支的通道数是不同的。具体来说,分辨率越低,通道数越多。这种做法和大多数金字塔结构不一样,后者倾向于让所有层保持相同通道数。HRNet这样做有两个原因:一是低分辨率分支承担更多语义信息,需要更大的容量;二是高分辨率分支的计算量本身就大,如果通道数也很大,显存和耗时都扛不住。
2.3 “同深度分辨率”是个什么设计决策
论文里提到一个概念:保持同深度分辨率。意思是每个并行分支都会经过同样数量的残差模块,而不是高分辨率分支浅、低分辨率分支深。这样一来,不同分辨率分支具有相似的抽象层次,融合时信息对称性更好。
我自己实验时试过把高分辨率分支的模块数降一半,给低分辨率分支加更多模块,结果是整体精度反而下降。直觉上低分辨率分支更强的语义应该对高分辨率分支有帮助,但实际的训练过程表明,高分辨率分支本身需要足够的深度来处理细节特征。这个设计和“并行结构”是一体两面的关系,改变一侧往往会影响另一侧的效果。
3. 姿态估计任务的落地细节:从空间维度到损失函数
HRNet作为通用骨干网络,在论文里主要用人体姿态估计任务来验证效果。姿态估计在这里特指单人关键点检测,即假设输入图像中已经有一个人的区域,网络输出该区域内所有关键点的位置。这个设定决定了网络的输出形式和损失函数的设计思路。
3.1 热图回归的设计逻辑
关键点检测的标准做法是热图回归。每个关键点(比如左肘、右踝)对应一张二维热图,热图上某个位置的值表示该处存在该关键点的概率。训练时,真值标注被转化成以标注点为中心的高斯分布,网络输出的热图通过均方误差损失迫近这个高斯分布。
HRNet的输出分支很简单:主干之后接一个1x1卷积,把通道数降到K+1,其中K是关键点数量,加1是背景通道。输出热图的分辨率不是输入尺寸,而是输入的四分之一。例如输入384x288,输出热图就是96x72。推理时直接在热图上找最大值位置,再按比例映射回原始图像坐标。
为什么输出四分之一分辨率热图就够用?我的理解是,四分之一分辨率下每个像素对应原图的4个像素,对于大多数关键点定位需求来说精度已经足够。很多工作在得到热图后还会做一步坐标微调,即基于最大值周围区域的响应分布计算期望位置,通常能让定位再准半个像素左右。
值得注意的是,HRNet没有在输出端做特别复杂的后处理模块,它把一切性能提升都押在主干网络的表征能力上。这种做法很体现设计哲学:与其在输出端修补,不如让网络本身输出的热图足够干净。
3.2 关键点损失函数与监督方式
HRNet对损失函数的设置非常直接:所有关键点热图统一使用均方误差损失,对K+1个通道的热图逐像素计算差值平方和再取平均。你可能会问,为什么不把背景通道单独处理或者加权,毕竟背景区域远大于关键点区域?实测下来,因为关键点区域的响应值被高斯核平滑过,天然带有距离衰减信息,均方误差在没有显式加权的情况下也能很好地训练网络。
另外一个细节是监督的深度。有些姿态估计网络会在多个中间层都有监督信号,比如堆叠沙漏网络每个沙漏模块都输出热图并计算损失。HRNet V1在主干的最后一个阶段输出一次热图,计算损失。我没有在HRNet上做过中间监督的对比实验,但在类似结构的网络上尝试过,中间监督对最终精度的提升很小,反而增加训练复杂度。这可能是因为并行结构中每一层都已经有来自不同分辨率的信息交流,梯度传播已经相当顺畅。
3.3 输入尺寸、输出分辨率与计算量之间的权衡
论文的消融实验显示,输入分辨率对精度的影响非常显著。增大输入尺寸是一把双刃剑:它能直接提升关键点的定位精度,但同时带来计算量和显存的线性增长。在COCO数据集上,从256x192提升到384x288后,HRNet-W32的AP大约提升了3个点;继续提升到448x320,提升幅度就明显缩小,只有1个点左右。
我实际跑下来还对另一个维度比较敏感:输出热图分辨率。如果直接把输出热图的分辨率从输入的1/4改成1/8,精度会有显著下降。原因很明显,1/8分辨率下每个像素覆盖原图8x8的区域,高斯核的离散化误差变大,小目标的关键点很容易被“压”进同一个像素。HRNet选择输出1/4分辨率热图,是在定位精度和计算负载之间比较合理的平衡点。
多尺度融合虽然让特征质量变好,但并没有完全消除分辨率对输出的影响。这点在其他实验里也能验证,同样结构下,输入越小精度衰减越明显。
4. 实验复现中的关键细节与常见坑
论文阅读和代码复现之间的距离,往往比想象中大。我在复现HRNet V1时踩了一些坑,这里整理出来,应该能帮你省不少时间。
4.1 训练超参数与数据增强配置
论文给出的训练配置看起来并不复杂:输入尺寸384x288,Adam优化器,初始学习率1e-3,在90个epoch和110个epoch时分别降到1e-4和1e-5,总共训练210个epoch。数据增强包括随机旋转(-45度到45度)、随机缩放(0.65到1.35)、水平翻转和半身遮挡增强。
但这里的坑在于归一化层的同步问题。论文使用同步批量归一化,即在多卡训练时跨卡同步均值和方差。如果实现不当,小批量训练时BN统计量不稳定,训练结果会明显波动。我一开始用单卡batch size 64训练,BN统计量还算稳;改成多卡后,如果不同卡的batch大小不一致,同步的结果就很怪,精度掉得莫名其妙。
建议训练时总batch size不要低于32,否则BN不稳定的问题会被放大。另外,验证时需要特别注意使用训练阶段统计量的running mean和running variance,而不是像推理模式下直接用当前batch的统计量,这个细节搞反了会得到偏高或偏低的假指标。
4.2 性能指标怎么对比才有说服力
论文使用的指标是COCO风格的OKS AP,这是通用做法。AP指标的计算过程对每个检测关键点按欧氏距离归一化,距离小于阈值则算正确,再按OKS阈值从0.5到0.95积分得到AP。很多人只盯着AP数字,但其实AP50、AP75和中距离误差更有诊断价值。AP75对定位精度更敏感,HRNet相对同期方法提升最大的往往就在AP75上。
如果你的项目场景对某些关键点(比如手腕)的精度要求特别高,建议额外加入各关键点的单独AP分析,而不是只看汇总AP。HRNet论文里的每类关键点误差表会揭示一些有趣的规律,比如耳部和肩部这类轮廓分明的大关键点精度高,手腕和脚踝这类小关节误差明显更大。
4.3 我复现时踩过的三个坑
第一个坑,是预训练权重的使用。HRNet采用ImageNet预训练时,如果直接加载主干权重,需要特别注意stem部分的结构差异。不同开源实现的stem卷积顺序和通道数可能略有不同,直接把权重文件丢进去很容易出现维度对不上的报错,更麻烦的是没有报错但权重加载不完整,静默影响性能。我习惯加载后逐层核对state_dict。
第二个坑,是融合模块里上采样方式的实现差异。论文中用最近邻上采样加1x1卷积,但有些第三方复现为了省事直接利用转置卷积或双线性插值。实测下来,最近邻上采样和双线性插值在精度上没有显著差异,但转置卷积在推理速度上会慢一些,而且容易引入边缘伪影。如果你要部署到移动端,直接用最近邻上采样更省内存。
第三个坑,是推理时的坐标还原。由于输出热图是输入的四分之一分辨率,从热图最大值位置还原到原图坐标时,需要乘上一个比例系数。但如果你的数据管线里用了仿射变换,这个比例系数在不同样本上不是固定的,必须在每个样本上单独计算变换矩阵并映射坐标。否则验证集AP会凭空掉1到2个点,很多复现精度偏低就是这个原因。
这个坑特别容易被忽视,因为训练时并不会报错。建议在推理代码中显式保存每个样本的仿射变换矩阵,用矩阵做坐标映射,而不是依赖固定的分辨率比值。
5. 从姿态估计到通用视觉骨干:HRNet的后续影响
读论文如果只看原版结构就结束,会错过它最有价值的部分——设计思想的后续扩展。HRNet V1发表之后,它的架构思路迅速迁移到了人体分割、目标检测、人脸关键点等多种任务上,形成了一个完整的后续演进脉络。
5.1 为什么它能迁移到分割、检测等任务
姿态估计只是HRNet的试验场。论文作者的论证是,HRNet主干在任何需要密集预测的任务上都有天然优势,因为高分辨率特征对像素级任务(分割、检测、边缘提取)至关重要。
以语义分割为例,传统分割网络同样面临下采样后信息丢失的问题。HRNet作为分割骨干时,高分辨率分支直接为像素级分类提供精细的空间信息,低分辨率分支提供类别语义,两者通过融合模块持续互补,输出可以直接上采样到原图尺寸做预测,不需要额外的解码器。
我在自己的一个语义分割实验里,把ResNet-50骨干换成HRNet-W32,保持训练配置和decoder统一,mIoU提升了约4个百分点,这可以在一定程度上说明高分辨率特征在密集预测任务中确实是关键因子。
5.2 HRNet V2与V2p做了哪些改变
后续版本里,HRNet V2提出了一个更实用的改进:把不同分辨率分支的特征重新组合后统一输出到同一分辨率,从而得到一个比单纯高分辨率分支信息更丰富的输出特征。V2p则把V2的输出分辨率从输入的1/4提升到全分辨率级别,并通过空间信息保持机制形成高分辨率特征金字塔,让它在目标检测和小物体分割上表现更优。
如果你要直接用于目标检测项目,我建议看V2p的实现,它更方便和检测头配合。V2在Segmentation和Detection任务中的有效性和可迁移性都比较强。原版V1更适合纯姿态估计和使用需求比较聚焦的场景。
5.3 现在的视觉架构里还有哪些HRNet的影子
再过几年回头看HRNet,会发现它的很多设计理念在现在的视觉Transformer骨干中都有体现。比如HR-NAS、Token Pyramid等结构在不同任务上继续沿用了多分辨率并行和跨分辨率信息交换的思想。即使视觉Transformer已经成为主流的骨干选择,高分辨率与低分辨率分支并行融合的思路仍然有效。
最近很多混合网络把Transformer模块作为高分辨率分支的增强组件,就是借鉴了“高低分辨率并行、多尺度融合”的HRNet思想。如果你想在未来研究中对网络结构做创新,把HRNet的并行多分辨率范式和新的算子组合起来,是一个值得尝试的方向。
我在实际项目中体会最深的一点是:HRNet的价值不仅在于它当时的精度优势,更在于它提供了一种看待“分辨率-语义权衡”的新视角。即使到了今天,当你需要设计一个同时兼顾细节和语义的视觉网络时,重新翻一遍这篇论文,依然能收获不少启发。