论文笔记
文章目录
论文代码
前言
人体姿态估计(Human Pose Estimation)的问题可以分为两大类,2D姿态估计 和 3D姿态估计
其中2D姿态估计在当下的研究多为多人姿态估计,有两种主要的解决思路:
- top-down : 对图形进行目标检测,然后将人找出,再resize后输入到网络中进行姿态估计。(速度很快,但是准确率稍低)
- bottom-up : 找到图中所有的关键点,再对关键点进行分组。(速度较慢,但是准确率较高)
Hourglass结合了Top-down和Bottom-up两种方法,是一种multi-stage的结构,网络像堆积起来的沙漏,网络层的结构是 对称 的,所以叫作 Stacked Hourglass Networks 。
每个Hourglass首先在bottom-up的过程将图片由高分率到底分率(max pooling降采样),再在top-down过程中将图片从低分率到高分率(upsampling上采样)。
特点 :前人的方法是针对不同的scale使用多个不同的pipeline处理图像信息,然后再在网络中整合各种特征信息。而Hourglass能够 处理不同scale下的图像信息 ,它使用了 一个 pipeline和skip layers去保留不同scale下的图像信息。
预备知识
在上采样的过程中,我们只是运用了nearest neighbor upsampling的方法
nearest neighbor : https://blog.csdn.net/linqianbi/article/details/78593724
BN(Batch Normalization) : https://zhuanlan.zhihu.com/p/24810318
Network Architecture
网络输入 : 分辨率为 256 * 256 * 3的图形
网络输出 : 整个网络结构的输出是一个heatmap的集合,这个heatmap表示每个像素中joint出现的可能性(joint可能是膝关节,肘关节,眼睛,鼻子,耳朵,腰部)
如图所示:
预处理网络pre
在PoseNet的最初,首先经过一个卷积核大小 为 7*7 , stride=2的卷积层,将图像通道数变为64,图像的大小变为 128 * 128 * 64。
然后再经过Residual+pool+Residual+Residual,其中pool层将图片大小变为64 * 64 * 128,而Residual改变了图片的通道数为256,没有改变图片大小,图片变为 64 * 64 * 256。
代码如下:
self.pre = nn.Sequential(
Conv(3, 64, 7, 2, bn=True, relu=True),
Residual(64, 128),
Pool(2, 2),
Residual(128, 128),
Residual(128, inp_dim) )
Hourglass
为什么预处理要将图片大小变为64 * 64,因为考虑到对GPU资源的占用,作者规定Hourglass处理的图片分辨率最大为 64 * 64.
一个Hourglass的结构如下所示:
如图所示,其中每一个立方体代表一个 Residual Module(残差块) , 每个 Hourglass 中有四阶的Residual Module 。
为了更清楚的理解Hourglass, 其代码如下:
class Hourglass(nn.Module):
def __init__(self, n, f, bn=None, increase=0):
super(Hourglass, self).__init__()
nf = f + increase
self.up1 = Residual(f, f)
# Lower branch
self.pool1 = Pool(2, 2)
self.low1 = Residual(f, nf)
self.n = n
# Recursive hourglass
if self.n > 1:
self.low2 = Hourglass(n-1, nf, bn=bn)
else:
self.low2 = Residual(nf, nf)
self.low3 = Residual(nf, f)
self.up2 = nn.Upsample(scale_factor=2, mode='nearest')
def forward(self, x):
up1 = self.up1(x)
pool1 = self.pool1(x)
low1 = self.low1(pool1)
low2 = self.low2(low1)
low3 = self.low3(low2)
up2 = self.up2(low3)
return up1 + up2
由代码可知,Hourglass是一个递归的结构,递归四次,这四阶的 Residual Module分别提取了不同 scale(原尺度,1/4尺度,1/16尺度,1/64尺度) 下的图像特征。每一个Residual Module 图像的输入输出的通道数不变,都是256,图片大小随每一次递归中的pool层变为原来的1/4,后面由随着每一次的upsampling将图片大小变为原来的4倍,最终Hourglass的图像输出大小为64 * 64 * 256,与输入一致。
具体的递归过程,参照https://zhuanlan.zhihu.com/p/45002720的图:
Residual
上面已经说了Residual模块不改变图片大小,只改变图片的通道数,因此我们来看一下Residual的具体结构。
Residual Moduel代码如下:
class Residual(nn.Module):
def __init__(self, inp_dim, out_dim):
super(Residual, self).__init__()
self.relu = nn.ReLU()
self.bn1 = nn.BatchNorm2d(inp_dim)
self.conv1 = Conv(inp_dim, int(out_dim/2), 1, relu=False)
self.bn2 = nn.BatchNorm2d(int(out_dim/2))
self.conv2 = Conv(int(out_dim/2), int(out_dim/2), 3, relu=False)
self.bn3 = nn.BatchNorm2d(int(out_dim/2))
self.conv3 = Conv(int(out_dim/2), out_dim, 1, relu=False)
self.skip_layer = Conv(inp_dim, out_dim, 1, relu=False)
if inp_dim == out_dim:
self.need_skip = False
else:
self.need_skip = True
def forward(self, x):
if self.need_skip:
residual = self.skip_layer(x)
else:
residual = x
out = self.bn1(x)
out = self.relu(out)
out = self.conv1(out)
out = self.bn2(out)
out = self.relu(out)
out = self.conv2(out)
out = self.bn3(out)
out = self.relu(out)
out = self.conv3(out)
out += residual
return out
可知, Residual Modle 是由两部分组成 :
- convBlock : (下图中中间的三个箭头表示三次卷积)主要进行卷积,提取出高层次的特征。
convBlock网络结构 : BN+relu+conv1+BN+relu+conv2+BN+relu+conv3
其中conv1和conv3的卷积核为 1 * 1 ,conv2的卷积核为 3 * 3, padding=1,因此 convBlock输出的图像feature map数目不变为256 - skipLayer : (下图中的虚线所示)将原图像数据进行 1 * 1的卷积,图象的feature map数目不变为256
因此Residual的结构就是将convBlock和skipLayer同时进行,图像的featuer map的数量为256,
使用两个部分在提取图像信息的同时也保留了原始的图像特征。
其实在Hourglass中,Residual只负责对图像的信息进行提取,同时保存一定的原图象的信息,图像的尺寸变化由Pool层负责。
作用:Residual模块提取了较高层次的特征(卷积路),同时保留了原有层次的信息(跳级路)。不改变数据尺寸,只改变数据深度。可以把它看做一个保尺寸的高级“卷积”层。
Stacked Hourglass with Intermediate Supervision(中间监督机制)
由于整个网络是由多个Hourglass叠加组成的,因此在每个Hourglass之后,都会对heatmap进行一次预测,产生prediction。
由于hourglass模块整合了局部和全局的信息,因此若想要网络在早期进行预测,则需要它对图片有一个高层次的理解,即使只是整个网络中的一部分。
中间监督机制如下所示:
其中蓝色部分为输出的heatmap集合,计算loss。然后用1*1的conv层对heatmap进行处理保证中间特征的通道数一致。然后再将处理后的heatmap和原Hourglass的输出整合,作为下一个Hourglass的输入,图片的通道数依然是256。
References
论文
http://www.paperweekly.site/papers/notes/157
https://zhuanlan.zhihu.com/p/104917833
https://blog.csdn.net/shenxiaolu1984/article/details/51428392
https://cloud.tencent.com/developer/article/1391909