Stacked Hourglass Networks for Human Pose Estimation论文笔记

论文笔记



论文代码

前言

人体姿态估计(Human Pose Estimation)的问题可以分为两大类,2D姿态估计3D姿态估计
其中2D姿态估计在当下的研究多为多人姿态估计,有两种主要的解决思路:

  1. top-down : 对图形进行目标检测,然后将人找出,再resize后输入到网络中进行姿态估计。(速度很快,但是准确率稍低)
  2. 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 是由两部分组成 :

  1. convBlock : (下图中中间的三个箭头表示三次卷积)主要进行卷积,提取出高层次的特征。
    convBlock网络结构 : BN+relu+conv1+BN+relu+conv2+BN+relu+conv3
    其中conv1和conv3的卷积核为 1 * 1 ,conv2的卷积核为 3 * 3, padding=1,因此 convBlock输出的图像feature map数目不变为256
  2. 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

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值