开始学关键点检测的时候,到处找找不到heatmap的解释。现在大概有些懂了,干脆自己写一个。部分转载。
关键点定位任务两种做法:heatmap和fully connected回归(Heapmap-based和Regression-Based)
heatmap得到一张类似热力图的东西,回归直接得到关键点坐标。
从定位的原理上看
Heatmap和Regression两种方法差异是很大的:
- Heatmap方法实际上是在空间维度上做特征匹配,是卷积核在特征图平面上“滑动”,更多地关注和利用的是局部信息,而定位实际上是特征匹配的“副产品”,是我们通过求响应最大点索引(Argmax)的方式获得的,相对来说,每一个关键点的计算是独立的。(可理解为拿一个卷积核去挨个算,看每一个局部是否符合关键点的特征,计算出的响应越大,越有可能是关键点)
- Regression方法则不同,所有的关键点计算是同时完成的,共享了同一份特征信息。(可理解为把所有特征信息输入一个全连接层,直接计算出坐标。)
heatmap(热图),如下图,可以理解成热感图。越是符合标准的位置,颜色越亮。
这里给出一种热图上像素点的计算方法:
假设真实坐标点 / 标注是
μ
=
(
μ
x
,
μ
y
)
\mu = (\mu_x ,\mu_y)
μ=(μx,μy),那么热图上某一点
(
x
,
y
)
(x,y)
(x,y)上的值为:
h
e
a
t
m
a
p
(
x
,
y
)
=
e
−
(
x
−
μ
x
)
2
+
(
y
−
μ
y
)
2
2
σ
2
heatmap(x,y) =\def\bar#1{#1^} \bar{e}{-\cfrac{\def\bar#1{#1^2} \bar{(x-\mu_x)} +\def\bar#1{#1^2} \bar{(y-\mu_y)}}{2\def\bar#1{#1^2} \bar{\sigma}}}
heatmap(x,y)=e−2σ2(x−μx)2+(y−μy)2
为何要附上高斯热图
很多任务中,目标点其实很难准确的被某一个像素位置定义的,也就很难被准确的标注。目标点附近的点其实也很像目标点,我们直接将其标为负样本,可能给网络的训练带来干扰,将其用高斯函数做一个“软标注”,网络也就更好收敛。
加上高斯图,也能够给网络的训练增加一个方向性的引导,距离目标点越近,激活值越大,这样网络能有方向的去快速到达目标点。
两方法的缺陷
-
高斯热图理论误差下界:高斯图比输入要小,一般是输入图像的1/4
假设输入图片是512x512,输出是缩小4倍即128x128,那么假设一个关键点位置是507x507,那么缩小4倍后,即使没有任何误差的高斯热图还原,也会存在最大507-126*4=3个像素误差,这个3就是理论误差下界。
fc更倾向于预测一个合理得模板,heatmap方法相对关注局部一点得特征,相对来说,heatmap方法更容易出现点位错乱的情况,而fc更多的是单个点精度不足导致偏差。 -
regression模型很容易训练,甚至即是很少的数据也能够训练。所得权重严重依赖于训练数据的分布,非常容易造成过拟合。
Regression方法具有更好的鲁棒性(由计算方式决定的): 关键点之间的能够保持某种潜在的“秩序”(比如face alignment中双眼+鼻子+两嘴角构成的5个点,这5个点总是会保持方位上的秩序)。这种秩序性更体现在,如果输入是一张完全不相关的图像,regression依然可以给出一个形状上非常合理的结果(反观heatmap所给的关键点则会完全乱了套)。